思路:
screen分为普通和复杂两种,普通的功能大部分是页面跳转以及简单的crud数据,复杂的单独弄出来
跳转普通的screen,直接根据配置文件调整设置
<layouts> <loyout screenId="0" bg="bg_start" name="start" defaultWinId="" bgm="" remark=""> </loyout> <loyout screenId="1" bg="bg_main" name="main" defaultWinId="0" bgm="" remark=""> <window id="0" scale="1.0" bg="" x="0" y="0" w="0" h="0" float="center" > <buttons > <button x="50" y="30" w="0" h="0" imgUpName="mbtn_empire" imgDownName="mbtn_empire" functionId="0" font="" remark="帝国"></button> <button x="300" y="30" w="0" h="0" imgUpName="mbtn_conquest" imgDownName="mbtn_conquest" functionId="1" font="" remark="征服"></button> <button x="550" y="30" w="0" h="0" imgUpName="mbtn_commder" imgDownName="mbtn_commder" functionId="2" font="" remark="指挥官"></button> <button x="800" y="30" w="0" h="0" imgUpName="mbtn_option" imgDownName="mbtn_option" functionId="3" font="" remark="设置"></button> <button x="300" y="120" w="0" h="0" imgUpName="mbtn_map" imgDownName="mbtn_map" functionId="4" font="" remark="地图"></button> </buttons> </window> </loyout> </layouts>
package com.zhfy.game.screen; import java.util.ArrayList; import java.util.List; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.ScreenAdapter; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.zhfy.game.MainGame; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.GameFramework; import com.zhfy.game.framework.GameLayout; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.framework.TextureRegionListDAO; import com.zhfy.game.screen.actor.base.BaseActor; /** * 主游戏场景(游戏主界面), 实现 Screen 接口 或者 继承 ScreenAdapter 类 <br/> * 这里就展示一张图片代表游戏主界面 */ public class MainScreen extends ScreenAdapter { private MainGame game; private EmpireScreen empireScreen; private Texture manTexture; private List<Stage> stages; private Stage stage; private BaseActor manActor; private TextureRegionListDAO imgLists; private TextureRegionListDAO imgUpList; private TextureRegionListDAO imgDownList; private ImageButton button; //使用场景 private int screenId=1; //uiRoot private Element uiR; //ui private List<Element> ui; private XmlReader reader ; private String bgTexture; private float tempX,tempY,tempW,tempH; Array<Element> buttonEs; //private GameFramework framework; public MainScreen(MainGame mainGame) { //获取传参 this.game=mainGame; // 创建背景纹理, 图片 bg_main.png reader = ResConfig.reader; uiR=GameLayout.getXmlERootByScreenId(screenId); ui=GameUtil.getXmlEByRootE(uiR); manTexture = GameUtil.getBgTextureByStr(uiR.get("bg"),mainGame.getAssetManager()); //stages=new ArrayList<Stage>(); //获取对应图片 imgLists=GameUtil.getTextureReigonByScreenId( screenId,mainGame.getAssetManager()); // 创建游戏人物演员 manActor = new BaseActor(new TextureRegion(manTexture)); for (Element window:ui) { tempX=window.getInt("x");tempY=window.getInt("y");tempW=window.getInt("w");tempH=window.getInt("h"); stage = new Stage(new StretchViewport(tempW==0?mainGame.getWorldWidth():tempW,tempH==0?mainGame.getWorldHeight():tempH)); // 添加演员到舞台 stage.addActor(manActor); imgUpList=new TextureRegionListDAO(); imgDownList=new TextureRegionListDAO(); //遍历window的buttons按钮 buttonEs = window.getChildByName("buttons").getChildrenByNameRecursively("button"); // 递归遍历,否则的话返回null for (Element buttonE : buttonEs) { //Gdx.app.log("ui测试", button.get("remark")); imgUpList.add(imgLists.getTextureByName(buttonE.get("imgUpName"))); imgDownList.add(imgLists.getTextureByName(buttonE.get("imgDownName"))); button = new ImageButton(new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion())); button.setSize(buttonE.getInt("w")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionWidth():buttonE.getInt("w"), buttonE.getInt("h")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionHeight():buttonE.getInt("h")); button.setPosition(buttonE.getInt("x"),buttonE.getInt("y")); function(buttonE.getInt("functionId")); stage.addActor(button); Gdx.input.setInputProcessor(stage); } } /*// 使用伸展视口创建舞台 // 将输入处理设置到舞台(必须设置, 否则点击按钮没效果) Gdx.input.setInputProcessor(stage); { //设定按钮 for(int i=0;i<imgUpList.size();i++) { button = new ImageButton(new TextureRegionDrawable(new TextureRegion(imgUpList.get(i).getTextureRegion())),new TextureRegionDrawable(new TextureRegion(imgDownList.get(i).getTextureRegion())),new TextureRegionDrawable(new TextureRegion(imgDownList.get(i).getTextureRegion()))); button.setSize(imgUpList.get(i).getTextureRegion().getRegionWidth(), imgUpList.get(i).getTextureRegion().getRegionHeight()); button.setPosition(imgUpList.get(i).getRefx(),imgUpList.get(i).getRefy()); //把按钮监听放到function(i)里了; function(i); stage.addActor(button); } } //测试框架 //framework.getStagesByScreenId(screenId); //文字示例 Label label=new Label("124563987258,12456382236874,123654236",new LabelStyle(new BitmapFont(), null)); label.setWidth(100);//设置每行的宽度 label.setWrap(true);//开启换行 stage.addActor(label);*/ } @Override public void render(float delta) { // 红色清屏 Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // 更新舞台逻辑 stage.act(); // 绘制舞台 stage.draw(); } public void dispose() { super.dispose(); // 场景被销毁时释放资源 /*if (manTexture != null) { manTexture.dispose(); }*/ if (stage != null) { stage.dispose(); } } //实现的功能 public void function(int i){ switch(i) { case 0://跳转到帝国页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //Gdx.app.log("点击了第1个按钮", "x:" + x+" y:" + y); game.showGameScreen(screenId,3); } }); break; case 1://跳转到征服页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,4); } }); break; case 2://跳转到指挥官页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,5); } }); break; case 3://跳转到设置页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,6); } }); break; case 4://跳转到设置页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //game.showGameScreen(6); game.showGameScreen(screenId,7); } }); break; default: button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了其他按钮", "x:" + x+" y:" + y); } }); break; } } }
构想中首先根据screenId获得其布局背景图,布局默认stage编号,背景音乐等信息,
然后一个window代表一个stage,buttons下加载其按钮配置
随后还设想加入Lable(文本标签)和Image(图片标签),并且x,y,w,h等都会变为百分比计算距离,根据float来确定位置(靠左,靠右,居中),根据bgm切换音乐
实现多窗口(多stage),动态加载内容等功能
此篇将随着后续对ui的完善持续更新
6.22更新:
所有坐标按百分比读取,绘制点为图片中心点,如果超边界,会顶边而不超出去
package com.zhfy.game.screen; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.ScreenAdapter; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.zhfy.game.MainGame; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.GameFramework; import com.zhfy.game.framework.GameLayout; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.framework.TextureRegionListDAO; import com.zhfy.game.screen.abandon.EmpireScreen; import com.zhfy.game.screen.actor.base.BaseActor; /** * 主游戏场景(游戏主界面), 实现 Screen 接口 或者 继承 ScreenAdapter 类 <br/> * 这里就展示一张图片代表游戏主界面 */ public class GeneralScreen extends ScreenAdapter { private MainGame game; private Texture manTexture; private Image bgImage; private List<Stage> stages; private Stage stage; private TextureRegionListDAO imgLists; private TextureRegionListDAO imgUpList; private TextureRegionListDAO imgDownList; private ImageButton button; //使用场景 private int screenId=-1; //uiRoot private Element uiR; //ui private List<Element> ui; private XmlReader reader ; private String bgTexture; private float tempX,tempY,tempW,tempH; Array<Element> buttonEs; private Map tempMap; private int i;//function的计数标志,从1开始 //private GameFramework framework; public GeneralScreen(MainGame mainGame,int screenId) { //获取传参 this.game=mainGame; // 创建背景纹理, 图片 bg_main.png this.screenId=screenId; reader = ResConfig.reader; uiR=GameLayout.getXmlERootByScreenId(screenId); ui=GameUtil.getXmlEByRootE(uiR); manTexture = GameUtil.getBgTextureByStr(uiR.get("bg"),mainGame.getAssetManager()); //stages=new ArrayList<Stage>(); //获取对应图片 imgLists=GameUtil.getTextureReigonByScreenId( screenId,mainGame.getAssetManager()); // 创建游戏人物演员 bgImage= new Image(manTexture); bgImage.setSize(mainGame.getWorldWidth(), mainGame.getWorldHeight()); i=1; for (Element window:ui) { tempX=window.getInt("x");tempY=window.getInt("y");tempW=window.getInt("w");tempH=window.getInt("h"); stage = new Stage(new StretchViewport(tempW==0?mainGame.getWorldWidth():tempW,tempH==0?mainGame.getWorldHeight():tempH)); // 添加演员到舞台 stage.addActor(bgImage); imgUpList=new TextureRegionListDAO(); imgDownList=new TextureRegionListDAO(); //遍历window的buttons按钮 buttonEs = window.getChildByName("buttons").getChildrenByNameRecursively("button"); // 递归遍历,否则的话返回null for (Element buttonE : buttonEs) { //Gdx.app.log("ui测试", button.get("remark")); imgUpList.add(imgLists.getTextureByName(buttonE.get("imgUpName"))); imgDownList.add(imgLists.getTextureByName(buttonE.get("imgDownName"))); button = new ImageButton(new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion())); button.setSize(buttonE.getInt("w")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionWidth():buttonE.getInt("w")*imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionWidth()/100, buttonE.getInt("h")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionHeight():buttonE.getInt("h")*imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionHeight()/100); button.setPosition( buttonE.getInt("x")*stage.getWidth()/100+button.getWidth()/2>stage.getWidth()?stage.getWidth()-button.getWidth():buttonE.getInt("x")*stage.getWidth()/100-button.getWidth()/2<0?0:buttonE.getInt("x")*stage.getWidth()/100-button.getWidth()/2, buttonE.getInt("y")*stage.getHeight()/100+button.getHeight()/2>stage.getHeight()?stage.getHeight()-button.getHeight():buttonE.getInt("y")*stage.getHeight()/100-button.getHeight()/2<0?0:buttonE.getInt("y")*stage.getHeight()/100-button.getHeight()/2); tempMap=new HashMap(); tempMap.put("FUNCTION_ID", buttonE.get("functionId")); tempMap.put("ID", i); /*switch(screenId) { //一些特殊的数据 暂时废弃 case 7: break; }*/ i++; function(tempMap); stage.addActor(button); Gdx.input.setInputProcessor(stage); } } /*// 使用伸展视口创建舞台 // 将输入处理设置到舞台(必须设置, 否则点击按钮没效果) Gdx.input.setInputProcessor(stage); { //设定按钮 for(int i=0;i<imgUpList.size();i++) { button = new ImageButton(new TextureRegionDrawable(new TextureRegion(imgUpList.get(i).getTextureRegion())),new TextureRegionDrawable(new TextureRegion(imgDownList.get(i).getTextureRegion())),new TextureRegionDrawable(new TextureRegion(imgDownList.get(i).getTextureRegion()))); button.setSize(imgUpList.get(i).getTextureRegion().getRegionWidth(), imgUpList.get(i).getTextureRegion().getRegionHeight()); button.setPosition(imgUpList.get(i).getRefx(),imgUpList.get(i).getRefy()); //把按钮监听放到function(i)里了; function(i); stage.addActor(button); } } //测试框架 //framework.getStagesByScreenId(screenId); //文字示例 Label label=new Label("124563987258,12456382236874,123654236",new LabelStyle(new BitmapFont(), null)); label.setWidth(100);//设置每行的宽度 label.setWrap(true);//开启换行 stage.addActor(label);*/ } @Override public void render(float delta) { // 红色清屏 Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // 更新舞台逻辑 stage.act(); // 绘制舞台 stage.draw(); } public void dispose() { super.dispose(); // 场景被销毁时释放资源 /*if (manTexture != null) { manTexture.dispose(); }*/ if (stage != null) { stage.dispose(); } } //实现的功能 /* 0:帝国/战役 1:征服 2:指挥官 3:设置 4:地图 5:返回主页 6:地图跳入(i) 7:跳入详细地图 8: 9: 10: 11: 12: */ public void function(Map map){ int i=Integer.parseInt(map.get("FUNCTION_ID").toString()); switch(i) { case 0://跳转到帝国页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //Gdx.app.log("点击了第1个按钮", "x:" + x+" y:" + y); game.showGameScreen(screenId,3); } }); break; case 1://跳转到征服页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,4); } }); break; case 2://跳转到指挥官页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,5); } }); break; case 3://跳转到设置页面 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.showGameScreen(screenId,6); } }); break; case 4://跳转到设置地图 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //game.showGameScreen(6); game.showGameScreen(screenId,7); } }); break; case 5://返回 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //game.showGameScreen(6); game.showGameScreen(screenId,1); } }); break; case 6://地图跳入 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { //game.showGameScreen(6); game.showGameScreen(screenId,7); } }); break; case 7://地图编辑 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.setMapId(Integer.parseInt(map.get("ID").toString())); game.showGameScreen(screenId,71); } }); break; case 8://跳入征服 button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { game.setStageId(Integer.parseInt(map.get("ID").toString())); game.showGameScreen(screenId,81); } }); break; default: button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了其他按钮", "x:" + x+" y:" + y); } }); break; } } }