3.资源加载器读入以texture为格式的图片,无法作为pixmap格式用
4.在一张透明的pixmap里画pixmap,透明部分的透明度会被加重!(叠加了背景图的透明度)
5.android项目读取local读取不到,不会像pc一样再用interal方法读
6.android反射的顺序会变
左安卓右pc
7.stage控制相机缩放
((OrthographicCamera) gameStage.getCamera()).zoom -=0.01f;
8.使用gradle build项目的时候提示资源路径不对,需要修改Edit Configurations
9.常用类的一些更改
List类-->如果是class使用Array类,如果是基础类型,比如int使用IntArray,float使用FloatArray等
Map类-->普通的使用ObjectMap类,如果是数值类,例如<int,int>可以使用IntIntMap,是<int,Object>使用IntMap等
具体查看com.badlogic.gdx.utils下的方法.使用这些方法以加快libgdx的效率.
10.修改libgdx的颜色亮度
下图中效果尉亮度每行90%的比例递减
//brightness 为0.9 则该颜色亮度降低到原来的0.9 图中效果为0.9的颜色递减 public static Color changeBright(Color color, float brightness) { float r=color.r; float g=color.g; float b=color.b; float h; float s; float v; float min, max, delta; min = ComUtil.Min( r, ComUtil.Min( g, b )); max = ComUtil.Max( r, ComUtil.Max( g, b )); v = max; // v delta = max - min; if( max != 0 ) s = delta / max; // s else { // r = g = b = 0 // s = 0, v is undefined s = 0; h = -1; return color.fromHsv(h,s,v*brightness); } if( r == max ) h = ( g - b ) / delta; // between yellow & magenta else if( g == max ) h = 2 + ( b - r ) / delta; // between cyan & yellow else h = 4 + ( r - g ) / delta; // between magenta & cyan h *= 60; // degrees if( h < 0 ) h += 360; return color.fromHsv(h,s,v*brightness); }
11. 安卓的16进制方法转换问题
public static int getCoverStr(DefRule r, StringBuilder buf, int bufTag) { int cutL = r.getSize(); int str = 0; if (cutL != 0) { if(buf.substring(bufTag, bufTag + cutL).equals("ffffffff")){ str=-1; }else{ // Gdx.app.log("getCoverStr",buf.substring(bufTag, bufTag + cutL)); str = Integer.parseInt(buf.substring(bufTag, bufTag + cutL), 16); } } return str ; }
方法:Integer.parseInt(buf.substring(bufTag, bufTag + cutL), 16);
id:bm16_2 name:regionId c:3 bs:88742~88750
I/getCoverStr: e6010000
W/System.err: java.lang.NumberFormatException: For input string: "e6010000"
W/System.err: at java.lang.Integer.parseInt(Integer.java:618)
此主要把截取的16进制转为十进制数字,但是在安卓部分模拟器上会出错,故我修改读取位数以避免错误
12.
之前连进都进不去
在AndroidManifest.xml中加入 android:largeHeap="true" 后进入
猜测是因为使用映射等方法导致安卓内存过大,随后重写数据加载方法后速度加快
13.重复动作Action
使用重复动作,如一些比例变换,位置移动等必须复位,否则因为状态相同基本不会执行
SequenceAction sequence = Actions.sequence( Actions.scaleTo(0.5F, rate, 1.0F), Actions.alpha(0.0F, 2.0F), // Runnable 复位 Actions.run(new Runnable() { @Override public void run() { // 打印一句 log 表示动作已执行 // Gdx.app.log(TAG, "The runnable action has been running."); comActor.setScaleY(rate/3); comActor.getColor().a=1.0f; } }) ); RepeatAction repeatAction = Actions.forever(sequence);
14.map的遍历
//遍历IntIntMap drawHexagon Iterator<IntIntMap.Entry> it = drawHexagon.iterator(); while (it.hasNext()) { IntIntMap.Entry c= it.next(); int id=c.key; int value=c.value;
15. libgdx的actor批量绘制 当draw方法涉及不同图集的素材,批量绘制该actor会导致
DrawCall暴增
如图,在大比例模式下,由于兵模,国旗,血条来自不同的三个图集,导致批量绘制时 会在三个图集之间来回切换绘制,导致drawcalls暴增.极度影响游戏效率
@Override public void draw() { if(getMainGame().gameConfig.ifDrawArmyMark){ super.draw(); }else { setArmyActorState(0); super.draw(); for(int i=1;i<4;i++){ super.getBatch().begin(); for(ArmyActor a:armyActorList){ if (a!=null) { a.setDrawState(i); a.draw(super.getBatch(),1); } } super.getBatch().end(); } } }
@Override public void draw(Batch batch, float parentAlpha) { super.draw(batch, parentAlpha); if (armyRegion == null || !isVisible()/*||cam.getCamera().zoom>0.85*/) { return; } // 备份 batch 原本的 Color // Color tempBatchColor = batch.getColor(); // 获取演员的 Color Color color = getColor(); if(game.gameConfig.ifDrawArmyMark){//绘制底牌 // 将演员的 Color 结合 parentAlpha 设置到 batch batch.setColor(1f-legionColor.r,1f-legionColor.g,1f-legionColor.b,parentAlpha); // 结合演员的属性绘制表示演员的纹理区域 if(loopState==0||loopState==1) { batch.draw( armyBottomRegion, getX()+markRefX, getY()+markRefY, getOriginX(), getOriginY(), getWidth() , getHeight() , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( armyBottomRegion, getX()+markRefX+getMapW_px(), getY()+markRefY, getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() ); } batch.setColor(color.r, color.g, color.b, parentAlpha); } if(game.gameConfig.ifDrawArmyMark) {//绘制兵牌 // 将演员的 Color 结合 parentAlpha 设置到 batch batch.setColor(color.r, color.g, color.b, 0.5f); if(loopState==0||loopState==1) { // 结合演员的属性绘制表示演员的纹理区域 batch.draw( armyRegion, getX()+markRefX, getY()+markRefY, getOriginX(), getOriginY(), getWidth() , getHeight() , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( armyRegion, getX()+getMapW_px()+markRefX, getY()+markRefY, getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() ); } batch.setColor(color.r, color.g, color.b, parentAlpha); }else if(drawState==1){ if(loopState==0||loopState==1) { // 结合演员的属性绘制表示演员的纹理区域 batch.draw( armyModelR, getX()+modelRefX, getY()+modelRefY, getOriginX(), getOriginY(), armyModelR.getRegionWidth()* ResConfig.Map.MAP_SCALE , armyModelR.getRegionHeight()* ResConfig.Map.MAP_SCALE , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( armyModelR, getX()+modelRefX +getMapW_px(),getY()+ modelRefY, getOriginX(), getOriginY(), armyModelR.getRegionWidth()* ResConfig.Map.MAP_SCALE , armyModelR.getRegionHeight()* ResConfig.Map.MAP_SCALE , getScaleX(), getScaleY(), getRotation() ); } } if(game.gameConfig.ifDrawArmyMark){ if(armyData.getArmyRound()!=0){ batch.setColor(1,1,1,0.5f); } //绘制血条 // 结合演员的属性绘制表示演员的纹理区域 if(loopState==1||loopState==0) { batch.draw( armyHpRegion.getRegion(), getX()+markRefX, getY()+markRefY+ hpRefy*getScaleY(),//armyHpRegion.getSprite().getRegionHeight()*getScaleY()*hpRate game.gameConfig.hpOx, game.gameConfig.hpOy,//手工测出来的..... // game.sMapScreen.tempX,game.sMapScreen.tempY, getWidth() , armyHpRegion.getSprite().getRegionHeight() , getScaleX(), getScaleY(), 180 ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( armyHpRegion.getRegion(), getX()+markRefX+getMapW_px(),getY()+markRefY+ hpRefy*getScaleY() ,//armyHpRegion.getSprite().getRegionHeight()*getScaleY()*hpRate game.gameConfig.hpOx, game.gameConfig.hpOy,//手工测出来的..... // game.sMapScreen.tempX,game.sMapScreen.tempY, getWidth(), armyHpRegion.getSprite().getRegionHeight(), getScaleX(), getScaleY(), 180 ); } batch.setColor(1,1,1,1f); }else if(drawState==2){ if(loopState==0||loopState==1) { batch.draw( flag, getX()-6, getY()-12, getOriginX(), getOriginY(), flagW ,flagH , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){ batch.draw( flag, getX()-6+getMapW_px(), getY()-12, getOriginX(), getOriginY(), flag.getRegionWidth()*0.4f ,flag.getRegionHeight()*0.4f , getScaleX(), getScaleY(), getRotation() ); } }else if(drawState==3){ if(loopState==0||loopState==1) { batch.draw( armyHpRegion.getRegion(), getX()-25.4f, getY()-31.5f+ hpRefy*getScaleY()*0.4f,//armyHpRegion.getSprite().getRegionHeight()*getScaleY()*hpRate game.gameConfig.hpOx, game.gameConfig.hpOy,//手工测出来的..... // game.sMapScreen.tempX,game.sMapScreen.tempY, flagW, armyHpRegion.getSprite().getRegionHeight()*0.4f , getScaleX(), getScaleY(), 180 ); } if(loopState==1||loopState==2){ batch.draw( armyHpRegion.getRegion(), getX()-25.4f+getMapW_px(), getY()-31.5f+ hpRefy*getScaleY()*0.4f,//armyHpRegion.getSprite().getRegionHeight()*getScaleY()*hpRate game.gameConfig.hpOx, game.gameConfig.hpOy,//手工测出来的..... // game.sMapScreen.tempX,game.sMapScreen.tempY, flagW, armyHpRegion.getSprite().getRegionHeight()*0.4f , getScaleX(), getScaleY(), 180 ); } } if(game.gameConfig.ifDrawArmyMark||drawState==3){ if(rank!=null){//绘制军衔 // 将演员的 Color 结合 parentAlpha 设置到 batch if(ifGeneral){ if(loopState==1||loopState==0) { batch.draw( rank, getX()+markRefX, getY()+markRefY, getOriginX(), getOriginY(), getWidth() , getHeight() , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( rank, getX()+markRefX+getMapW_px(), getY()+markRefY, getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() ); } }else{ if(loopState==1||loopState==0) { batch.draw( rank, getX()+markRefX + 20 * scale, getY()+markRefY + 16 * scale, getOriginX(), getOriginY(), rank.getRegionWidth() , rank.getRegionHeight() , getScaleX(), getScaleY(), getRotation() ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( rank, getX()+markRefX+getMapW_px()+20*scale, getY()+markRefY+16*scale, getOriginX(), getOriginY(), rank.getRegionWidth(), rank.getRegionHeight(), getScaleX(), getScaleY(), getRotation() ); } } } if(ifPlayer&&(game.gameConfig.ifDrawArmyMark||game.sMapScreen.getGameOperateState()== GameOperateState.selectPlayerArmyToCommand||game.sMapScreen.getGameOperateState()== GameOperateState.selectMergeArmy)&&targetState!=0) {//绘制目标 // 结合演员的属性绘制表示演员的纹理区域 if(loopState==1||loopState==0) { batch.draw( targetRegionDAO.getTextureRegion(), getX()+markRefX - game.gameConfig.targetRefv , getY()+markRefY -game.gameConfig.targetRefv, // getX()-game.sMapScreen.tempX,getY()-game.sMapScreen.tempY, targetRegionDAO.getRefx(), targetRegionDAO.getRefy(), getWidth() , getHeight() , getScaleX(), getScaleY(), targetAngle ); } if(loopState==1||loopState==2){//如果循环,则添加一部分 batch.draw( targetRegionDAO.getTextureRegion(), //getX()-game.sMapScreen.tempX+getMapW_px(),getY()-game.sMapScreen.tempY, getX()+markRefX-game.gameConfig.targetRefv+getMapW_px(),getY()+markRefY-game.gameConfig.targetRefv, targetRegionDAO.getRefx(),targetRegionDAO.getRefy(), getWidth(), getHeight(), getScaleX(), getScaleY(), targetAngle ); } } } // 还原 batch 原本的 Color // batch.setColor(tempBatchColor); }
效果如图 drawcall 14
想要的效果
思路:首先通过button中的label 的setWrap(false)和getPrefWidth方法获取不换行时文字的长度,然后除以要实现的行,获得自适应应该的宽度,同理可以制作根据自适应高度,来实现的效果
//h 一般为对齐的行长度 lineCount 字体长度 public void setTButtonTextAndPotionAndAdapt(int i,float x,float y,float h,int lineCount, String text) { TextButton t=getTButton(i); if(t!=null){ t.setVisible(true); t.getLabel().setText(text); t.getLabel().setHeight(h); // t.getLabel().setWidth(w); t.getLabel().setWrap(false); float width=t.getLabel().getPrefWidth()/lineCount+10; t.setWidth(width); t.setHeight(h); t.setX(x); t.setY(y); t.getLabel().setWrap(true); } }
增加下列代码并重启
-Dfile.encoding=UTF-8
2.项目gradle building时间过长
修改 gradle.properties
org.gradle.daemon=true org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.parallel=true org.gradle.configureondemand=true
Button button=windowGroups.get(cmd.getInt("groupId")).getButton(cmd.getInt("buttonId"));
if(button==null){
return;
}
Vector2 p=new Vector2();
//将对象位置转换到屏幕左边中
button.localToScreenCoordinates(p);
//获取位置中心
int x= (int)(p.x+button.getWidth()/2);
int y=(int)(p.y-button.getHeight()/2);
//在stage中点击对象位置
uiStage.touchDown(x,y,1,0);
uiStage.touchUp(x,y,1,0);
22. 启用gradle的离线模式
23.
今天gradle自动更新,然后我不知道怎么操作了项目,导致项目启动后帧率 fps只有10.最后不得不把改动同步到旧项目,
经过查找发现是启用安卓项目,无法正常启动,导致pc项目也出现了问题
解决方法是 先把.gradle和.idea两个文件夹删除,然后找到旧项目,把.gradle和.idea两个文件夹完全复制过去
24.
导入旧项目配置记录
25.ShapeRenderer的使用
绘制飞机范围 if(airRangeScale>0){ batch.end(); //batch.setColor(Color.WHITE.r,Color.WHITE.g,Color.WHITE.b,Color.WHITE.a/2); Gdx.gl.glEnable(GL30.GL_BLEND); Gdx.gl.glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA); game.shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix()); game.shapeRenderer.setTransformMatrix(batch.getTransformMatrix()); game.shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); game.shapeRenderer.setColor(Color.LIGHT_GRAY.r,Color.LIGHT_GRAY.g,Color.LIGHT_GRAY.b,Color.LIGHT_GRAY.a/3f); if(cam.loopState==0||cam.loopState==1){ game.shapeRenderer.circle(getX()+airRangeX,getY()+airRangeY,airRangeLength); } if(cam.loopState==1||cam.loopState==2){ game.shapeRenderer.circle(getX()+cam.getMapW_px()+airRangeX,getY()+airRangeY,airRangeLength); } game.shapeRenderer.end(); Gdx.gl.glDisable(GL30.GL_BLEND); batch.begin(); }
26. label字体空格间距问题
如图,这是一个label,要实现对齐效果是要补齐空格的: unitAttribute=生命:{0} 伤害:{1} 防御:{2} \n视野:{3} 射程:{4} 移动:{5} \n拥有特性:{6}
public String formmatStringForSpace(Label label,String str, int length, boolean ifLeft){ float base=getCharLengthBySpace(label,ResDefaultConfig.StringName.space1); int num = Math.round (getCharLengthBySpace(label,str)/base); length= Math.round (getCharLengthBySpace(label,ComUtil.getSpace(length))/base); if (num == length) { return str; } else if (num< length) { for (int i = 0, iMax = length - num; i < iMax; i++) { if (ifLeft) { str = ResDefaultConfig.StringName.space1 + str; } else { str = str + ResDefaultConfig.StringName.space1; } } /* if(num==2){ if (ifLeft) { str = ResDefaultConfig.StringName.space1 + str; } else { str = str + ResDefaultConfig.StringName.space1; } }*/ Gdx.app.log("formmatString:"+ num+" "+(length - num),str); return str; } else { return ComUtil.formmatString(str,length,ifLeft,ResDefaultConfig.StringName.space1); } } private float getCharLengthBySpace(Label label,String str) { label.setText(str); return label.getPrefWidth(); } /* * 处理字符串,进行前后补位 resultString ,表原字符串 length,处理后要求长度 flag,1表示前面增加,0表示后增加 * str1,要补位的字符串 */ public static String formmatString(String str, int length, boolean ifLeft, String str1) { // int num = computeDisplayLen(str); // int numj=computeDisplayLen(str1); int num = str.getBytes().length; int numj=str1.getBytes().length; if (num == length) { return str; } else if (num< length) { for (int i = 0, iMax = length - num; i < iMax; i+=numj) { if (ifLeft) { str = str1 + str; } else { str = str + str1; } } Gdx.app.log("formmatString:"+ num,str); return str; } else { return str.substring(0, length); } }
26,steam云存档配置问题
主要是libgdx的Preference方法储存位置无法配置到steam的云存档路径中,不得不对该方法进行仿写,让其保存到安装目录下
1 package com.zhfy.game.framework.tool; 2 3 import com.badlogic.gdx.Gdx; 4 import com.badlogic.gdx.files.FileHandle; 5 import com.badlogic.gdx.utils.Base64Coder; 6 import com.badlogic.gdx.utils.Json; 7 import com.badlogic.gdx.utils.JsonWriter; 8 import com.badlogic.gdx.utils.ObjectMap; 9 import com.zhfy.game.config.ResDefaultConfig; 10 import com.zhfy.game.framework.ComUtil; 11 12 import java.io.FileNotFoundException; 13 import java.io.FileOutputStream; 14 import java.io.IOException; 15 import java.util.Iterator; 16 import java.util.Properties; 17 18 public class PropertiesUtil { 19 20 private Properties save; 21 private FileHandle file; 22 23 24 public PropertiesUtil(String path) { 25 file = Gdx.files.local(path); 26 save=new Properties(); 27 if(file.exists()){ 28 try { 29 save.load(file.read()); 30 } catch (IOException e) { 31 e.printStackTrace(); 32 } 33 } 34 } 35 36 37 public void flush() { 38 /* Iterator<String> iterator = save.stringPropertyNames().iterator(); 39 40 while (iterator.hasNext()){ 41 String key = iterator.next(); 42 43 }*/ 44 file.writeString(ComUtil.transStrForProperty(save),false); 45 /* FileOutputStream oFile=null; 46 try { 47 oFile = new FileOutputStream(file.file()); 48 } catch (FileNotFoundException e) { 49 e.printStackTrace(); 50 } 51 if(oFile!=null){ 52 try { 53 save.store(oFile,null); 54 oFile.close(); 55 } catch (IOException e) { 56 e.printStackTrace(); 57 } 58 }*/ 59 } 60 61 /**/ public void put(String key, Object object){ 62 save.put(key, object); 63 // flush(); // 立即保存数据 64 } 65 66 67 68 public int getInteger(String key,int defaultValue){ 69 if(save.containsKey(key)) 70 return Integer.parseInt(save.get(key).toString()); 71 else 72 save.put(key, String.valueOf(defaultValue)); 73 return defaultValue; 74 } 75 76 public String get(String key,String defaultValue){ 77 if(save.containsKey(key)) 78 return (String) save.get(key); 79 else 80 save.put(key, defaultValue); 81 return defaultValue; 82 } 83 84 public Boolean getBoolean(String key,Boolean defaultValue){ 85 if(save.containsKey(key)) 86 return save.get(key).equals("true"); 87 else 88 save.put(key, String.valueOf(defaultValue)); 89 return defaultValue; 90 } 91 92 public void putInteger(String key, int i) { 93 save.put(key,String.valueOf( i)); 94 //flush(); // 立即保存数据 95 } 96 97 public void putBoolean(String key, boolean i) { 98 save.put(key, String.valueOf(i)); 99 // flush(); // 立即保存数据 100 } 101 102 public String getString(String s, String no_stage_name) { 103 return get(s,no_stage_name); 104 } 105 106 public void putString(String s, String s1) { 107 put(s,s1); 108 } 109 110 111 112 113 }
27 actor与其内部组件旋转问题
//先存入其位置 tv.set( getRegionDAORefSX(i), getRegionDAORefSY(i)); //通过方法获得旋转后坐标 GameUtil.potionCoordinates(tv,getX(),getY(),getOriginX(),getOriginY(),getScaleX(),getScaleY(),getRotation());//Vector2 localCoords,float x,float y,float originX,float originY,float scaleX,float scaleY,float rotation //localToParentCoordinates(tv); //绘制坐标 batch.draw( regionDAO.getTextureRegion(), tv.x, tv.y, 0, 0, regionDAO.getW(), regionDAO.getH(), getScaleX(), getScaleY(), getRotation() ); //坐标转化方法 public static Vector2 potionCoordinates(Vector2 localCoords,float x,float y,float originX,float originY,float scaleX,float scaleY,float rotation) { rotation =-rotation; if (rotation == 0) { if (scaleX == 1 && scaleY == 1) { localCoords.x += x; localCoords.y += y; } else { localCoords.x = (localCoords.x - originX) * scaleX + originX + x; localCoords.y = (localCoords.y - originY) * scaleY + originY + y; } } else { final float cos = (float)Math.cos(rotation * MathUtils.degreesToRadians); final float sin = (float)Math.sin(rotation * MathUtils.degreesToRadians); final float tox = (localCoords.x - originX) * scaleX; final float toy = (localCoords.y - originY) * scaleY; localCoords.x = (tox * cos + toy * sin) + originX + x; localCoords.y = (tox * -sin + toy * cos) + originY + y; } return localCoords; }
注意这个无法旋转文字,旋转文字的方式为外层套一个group,然后加label,通过操纵group来实现旋转
package com.zhfy.game.screen.actor.framework; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Pool; import com.badlogic.gdx.utils.XmlReader; import com.zhfy.game.MainGame; import com.zhfy.game.framework.ComUtil; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.framework.TextureRegionDAO; public class CardActor extends BaseActor implements Pool.Poolable { /* 可以直接使用该类来在batch中绘制 ShapeDrawer drawer = new ShapeDrawer(batch, region); batch.begin(); drawer.line(0, 0, 100, 100); batch.end();*/ public TextureRegionDAO cardBgDAO; public TextureRegionDAO cardRegionDAO; public TextureRegionDAO energyboxDAO; public TextureRegionDAO gemboxDAO; public TextureRegionDAO gemRegionDAO1; public TextureRegionDAO gemRegionDAO2; public TextureRegionDAO gemRegionDAO3; public TextureRegionDAO gemRegionDAO4; public TextureRegionDAO leadershipMarkDAO; public TextureRegionDAO forceboxDAO; public TextureRegionDAO forceMarkDAO; public TextureRegionDAO mainboxDAO; public TextureRegionDAO stateboxDAO; public TextureRegionDAO titleboxDAO; public TextureRegionDAO rangeboxDAO; public TextureRegionDAO atkboxDAO; public TextureRegionDAO hpboxDAO; public TextureRegionDAO shieldboxDAO; public TextureRegionDAO moveboxDAO; private int leadShip; public boolean alive; public XmlReader.Element cardE; //public Label stateLabel; public String text; public CardActor(MainGame game){ setMainGame(game); this.alive = false; mainboxDAO=game.getImgLists().getTextureByName("card_mainbox0"); setSize(this.mainboxDAO.getW(), this.mainboxDAO.getH()); setOrigin(this.mainboxDAO.getW()/2, this.mainboxDAO.getH()/2); } public void init(MainGame game,int cardId) { setMainGame(game); this.cardE =game.gameConfig.getDEF_CARD().getElementById(cardId); if(cardE==null){ return; } //0单位 //1母舰行动卡 //2战术卡 //3指令卡 int type=cardE.getInt("type",0); cardBgDAO=game.getImgLists().getTextureByName("card_bg"+type); energyboxDAO=game.getImgLists().getTextureByName("card_energybox"+type); gemboxDAO=game.getImgLists().getTextureByName("card_gembox"+type); cardRegionDAO=game.getImgLists().getTextureByName("card_hqship"); //TODO /* gemRegionDAO1=game.getImgLists().getTextureByName(""+type); //TODO gemRegionDAO2=game.getImgLists().getTextureByName(""+type); gemRegionDAO3=game.getImgLists().getTextureByName(""+type); gemRegionDAO4=game.getImgLists().getTextureByName(""+type);*/ leadershipMarkDAO=game.getImgLists().getTextureByName("card_leadershipMark"+type); forceboxDAO =game.getImgLists().getTextureByName("card_forcebox"+type); forceMarkDAO =game.getImgLists().getTextureByName("card_forceMark1"); mainboxDAO=game.getImgLists().getTextureByName("card_mainbox"+type); stateboxDAO=game.getImgLists().getTextureByName("card_statebox"+type); titleboxDAO=game.getImgLists().getTextureByName("card_titlebox"+type); // rangeboxDAO=game.getImgLists().getTextureByName("card_rangebox"); atkboxDAO =game.getImgLists().getTextureByName("card_atkbox"); hpboxDAO=game.getImgLists().getTextureByName("card_ship7box"); shieldboxDAO=game.getImgLists().getTextureByName("card_shieldbox"); moveboxDAO=game.getImgLists().getTextureByName("card_movebox"); // stateLabel= GameUtil.initLabel(stateLabel,getMainGame().gameConfig.gameFont,"test",Color.WHITE, labelEs.get(l),stageW,stageH,getMainGame().gameConfig.gameFontScale); /* stateLabel = new Label("test", new Label.LabelStyle(getMainGame().gameConfig.gameFont, Color.WHITE)); stateLabel.setText("测试技能 这技能无敌,可以杀死全部敌人,并获得敌人的卡牌在手中"); stateLabel.setColor(Color.WHITE); stateLabel.setFontScale(0.5f); stateLabel.setWidth(445); stateLabel.setHeight(220); stateLabel.setWrap(true); stateLabel.setDebug(true);*/ /*this.textureRegionDAO = game.getImgLists().getTextureByName(regionName); this.region= textureRegionDAO.getTextureRegion(); setSize(this.region.getRegionWidth(), this.region.getRegionHeight());*/ text=game.gameMethod.getDialogueStr(1, ComUtil.getRandom(1,game.gameConfig.getDEF_RDIALOGUE().getElementById(1).getInt("count") ) ,""); setSize(this.mainboxDAO.getW(), this.mainboxDAO.getH()); this.alive =true; setScale(1.0f); leadShip=6; setDebug(true); } @Override public void act(float delta) { super.act(delta); } @Override public void draw(Batch batch, float parentAlpha) { super.draw(batch, parentAlpha); if (!alive || !isVisible()) { return; } boolean batchBlendState=batch.isBlendingEnabled(); /* * 先把 batch 原本的 color 保存起来, 因为 batch 是从外部传进来的, 最好不要改变它原本的状态, * 但在这里需要重新设置 batch 的 color, 所以先保存起来, 等当前方法执行完时再将 batch 原本的 color 设置回去。 */ Color tempBatchColor = batch.getColor(); /* * 实际上演员并没有单独的 alpha 属性, alpha 包含在颜色(color)属性中, rgba color 中的 a 表示 alpha; * 演员有 alpha 值, 而父节点(舞台/演员组)中也有 alpha 值(parentAlpha)。 由于最终在演员节点中才真正把纹理 * 绘制在屏幕上, 才是真正绘制的地方, 而父节点一般用于组织演员, 不会直接绘制任何纹理, 透明度 alpha 值只有在绘制 * 时才能体现出来, 所以父节点无法体现自己的 alpha 值, 因此父节点会将自己的 alpha 值(就是draw方法中的参数 parentAlpha) * 传递给它自己的所有子节点,即最终直接绘制纹理的演员, 让演员结合自身的 alpha 值在绘制时综合体现。 */ // 获取演员的 color 属性 Color color = getColor(); /* * 处理 color/alpha 属性, 即将演员的 rgba color 设置到纹理画布 batch。 * 其中的 alpha 需要结合演员和父节点的 alpha, 即演员的 alpha 与父节点的 alpha 相乘, * 例如父节点的 alpha 为 0.5, 演员的 alpha 为 0.5, 那么最终的显示效果就是 0.5 * 0.5 = 0.25 */ batch.setColor(color.r, color.g, color.b, color.a); Vector2 tv= getMainGame().rescource.cardVector2; for(int i=0;i<=26;i++){ TextureRegionDAO regionDAO=getRegionDAO(i); if(regionDAO!=null){ tv.set( getRegionDAORefSX(i), getRegionDAORefSY(i)); GameUtil.potionCoordinates(tv,getX(),getY(),getOriginX(),getOriginY(),getScaleX(),getScaleY(),getRotation());//Vector2 localCoords,float x,float y,float originX,float originY,float scaleX,float scaleY,float rotation //localToParentCoordinates(tv); batch.draw( regionDAO.getTextureRegion(), tv.x, tv.y, 0, 0, regionDAO.getW(), regionDAO.getH(), getScaleX(), getScaleY(), getRotation() ); } } // batch.setColor(color.r, color.g, color.b, parentAlpha); //stateLabel.setX(getX()); //stateLabel.setY(getY()); //stateLabel.draw(batch,parentAlpha); /* float sourceScale=getMainGame().gameConfig.gameFont.getScaleX(); getMainGame().gameConfig.gameFont.getData().setScale(0.5f); tv.set( 10, 120); GameUtil.potionCoordinates(tv,getX(),getY(),111,getOriginY(),getScaleX(),getScaleY(),getRotation());//Vector2 localCoords,float x,float y,float originX,float originY,float scaleX,float scaleY,float rotation batch.setTransformMatrix(getMainGame().rescource.cardMatrix4.setToRotation(0,0,1,getRotation())); getMainGame().gameConfig.gameFont.draw(batch,text,tv.x,tv.y,222, Align.center,true); getMainGame().gameConfig.gameFont.getData().setScale(sourceScale); */ // 将 batch 原本的 color 设置回去 batch.setColor(tempBatchColor); if(batchBlendState){ batch.enableBlending(); }else { batch.disableBlending(); } } private TextureRegionDAO getRegionDAO(int i) { switch (i){ case 0:return cardBgDAO; case 1:return cardRegionDAO; case 2:return energyboxDAO; //TODO // case 3:return forceboxDAO; // case 4:return forceMarkDAO; case 5:return titleboxDAO; case 6:return stateboxDAO; case 7:return mainboxDAO; case 8:return gemRegionDAO1; case 9:return gemRegionDAO2; case 10:return gemRegionDAO3; case 11:return gemRegionDAO4; case 12: case 13: case 14: case 15:return gemboxDAO; case 16:return rangeboxDAO; case 17:return atkboxDAO; case 18:return hpboxDAO; case 19:return shieldboxDAO; case 20:return moveboxDAO; case 21: case 22: case 23: case 24: case 25: case 26:return leadershipMarkDAO; // leadershipMarkDAO } return null; } private float getRegionDAORefSX(int i){ if(i==-1){ return getMainGame().generalScreen.tempActor.getX(); } switch (i){ case 0:return 0; case 1:return 2; case 2:return 2; case 3:return 199; case 4:return 203; case 5:return 0; case 6:return 1; case 7:return 0; case 8:return 0; case 9:return 0; case 10:return 0; case 11:return 0; case 12:return 200; case 13:return 200; case 14:return 200; case 15:return 200; case 16:return 9; case 17:return 52; case 18:return 95; case 19:return 154; case 20:return 197; case 21:return 112+(leadShip%2 == 1?0:-13); case 22:return 112+(leadShip%2 == 1?26:13); case 23:return 112+(leadShip%2 == 1?-26:-39); case 24:return 112+(leadShip%2 == 1?52:39); case 25:return 112+(leadShip%2 == 1?-52:-65); case 26:return 112+(leadShip%2 == 1?78:65); } return 0; } private float getRegionDAORefSY(int i) { if(i==-1){ return getMainGame().generalScreen.tempActor.getY(); } switch (i){ case 0:return 5; case 1:return 163; case 2:return 285; case 3:return 163; case 4:return 170; case 5:return 122; case 6:return -2; case 7:return 0; case 8:return -300; case 9:return -300; case 10:return -300; case 11:return -300; case 12:return 295; case 13:return 264; case 14:return 233; case 15:return 202; case 16:return 169; case 17:return 166; case 18:return 160; case 19:return 167; case 20:return 169; case 21: case 22: case 23: case 24: case 25: case 26:return 307; } return 0; } private int getRegionDAORefOX(int i){ switch (i){ case 0:return cardBgDAO.getRefx(); case 1:return cardRegionDAO.getRefx(); case 2:return energyboxDAO.getRefx(); case 3:return forceboxDAO.getRefx(); case 4:return forceMarkDAO.getRefx(); case 5:return titleboxDAO.getRefx(); case 6:return stateboxDAO.getRefx(); case 7:return mainboxDAO.getRefx(); case 8:return gemRegionDAO1.getRefx(); case 9:return gemRegionDAO2.getRefx(); case 10:return gemRegionDAO3.getRefx(); case 11:return gemRegionDAO4.getRefx(); case 12: case 13: case 14: case 15:return gemboxDAO.getRefx(); case 16:return rangeboxDAO.getRefx(); case 17:return atkboxDAO.getRefx(); case 18:return hpboxDAO.getRefx(); case 19:return shieldboxDAO.getRefx(); case 20:return moveboxDAO.getRefx(); case 21: case 22: case 23: case 24: case 25: case 26:return leadershipMarkDAO.getRefx(); } return 0; } private int getRegionDAORefOY(int i) { switch (i){ case 0:return cardBgDAO.getRefy(); case 1:return cardRegionDAO.getRefy(); case 2:return energyboxDAO.getRefy(); case 3:return forceboxDAO.getRefy(); case 4:return forceMarkDAO.getRefy(); case 5:return titleboxDAO.getRefy(); case 6:return stateboxDAO.getRefy(); case 7:return mainboxDAO.getRefy(); case 8:return gemRegionDAO1.getRefy(); case 9:return gemRegionDAO2.getRefy(); case 10:return gemRegionDAO3.getRefy(); case 11:return gemRegionDAO4.getRefy(); case 12: case 13: case 14: case 15:return gemboxDAO.getRefy(); case 16:return rangeboxDAO.getRefy(); case 17:return atkboxDAO.getRefy(); case 18:return hpboxDAO.getRefy(); case 19:return shieldboxDAO.getRefy(); case 20:return moveboxDAO.getRefy(); case 21: case 22: case 23: case 24: case 25: case 26:return leadershipMarkDAO.getRefy(); } return 0; } @Override public void reset() { setVisible(false); setRotation(0); setOriginY(0); setOriginX(0); setScale(1.0f); alive=false; } //会把中心点设置图片的中心 public void setCenterPotionAndOriginByTextureRegionRef(float sourceX, float sourceY){ setX(sourceX- mainboxDAO.getRefx()); setY(sourceY- mainboxDAO.getRefy()); setOrigin(mainboxDAO.getRefx(), mainboxDAO.getRefy()); } //需要提前设置中心点 public void setCenterPotionByHaveOrigin(float sourceX, float sourceY){ setX(sourceX- getOriginX()); setY(sourceY- getOriginY()); } /** * 设置中心点坐标 * @param centerX * @param centerY */ public void setCenter(float centerX, float centerY) { setCenterX(centerX); setCenterY(centerY); } /** * 设置水平方向中心点坐标 * @param centerX */ public void setCenterX(float centerX) { setX(centerX - getWidth() / 2.0F); } /** * 设置竖直方向中心点坐标 * @param centerY */ public void setCenterY(float centerY) { setY(centerY - getHeight() / 2.0F); } }
28.使用pool创建对象,对其使用RunnableAction导致冲突,
原因为RunnableAction也是一个pool创建的,导致action没准确的回收时机,在创建多对象时导致action有可能重复
解决方法是 重写一个pool,来创建对象
package com.zhfy.game.screen.actor.framework; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Pool; //原来的pool不兼容action,并且无法区分是否还在使用,所以使用这个替代 public abstract class ObjectPool<T> { private final Array<T> freeObjects=new Array(); private final Array<T> useObjects=new Array(); public ObjectPool () { } public T obtain(){ if(freeObjects.size==0){ T t= newObject(); useObjects.add(t); Gdx.app.log("objectPool obtain1",t.toString()); return t; }else{ T t=freeObjects.removeIndex(0); useObjects.add(t); Gdx.app.log("objectPool obtain2",t.toString()); return t; } } public void free(T t){ if(useObjects.removeValue(t,false)){ freeObjects.add(t); Gdx.app.log("objectPool free",t.toString()); }else{ Gdx.app.error("objectPool free is error",t.toString()); } } abstract protected T newObject (); }
初始创建: public final ObjectPool<CardSkin> tempCardSkins = new ObjectPool<CardSkin>() { @Override protected CardSkin newObject() { return new CardSkin(getMainGame()); } }; 创建对象: CardSkin tempCard=tempCardSkins.obtain(); 释放示例: final float finalTime = time; RunnableAction runAction = Actions.run(new Runnable() { @Override public void run() { cardOperateGroup.setUse(false); cardOperateGroup.setVisible(false); tempCardSkins.free(cardOperateGroup); if(operateState == GameOperateState.母舰行动阶段){ bfResetCardActorPotion(); cmResetPlayerHandCardPotion(finalTime); } } }); //ScaleToAction scaleTo = Actions.scaleTo(0, 0, time*0.3f); SequenceAction sequenceAction = null; if(ifHid){ sequenceAction=Actions.sequence(moveTo,runAction); }else{ sequenceAction=Actions.sequence(moveTo); }
cardOperateGroup.addAction(sequenceAction);