Skip to content
isee edited this page Mar 10, 2014 · 21 revisions

让CocoStudio变成libgdx的UI编辑器

首先,这个想法不是我原创.我所知道的原作者是:https://github.com/bigstupidx/libgdx-cocostudio 他实现了 ui编辑器和动作编辑器的解析.完成度有多少我还不清楚,没细看代码. 我只是觉得他的实现方式不是很好,所以重写ui编辑器的解析部分. 我对cocos2d不熟悉,CocoStudio是为cocos2d开发的编辑器.所以会对一些控件属性理解有误导致bug产生,也希望各位能多多的支出错误.

使用的版本(不表示只支持该版本,而是我的使用版本):

libgdx:0.9.9

CocoStudio:v1.2.0.1 http://www.cocostudio.org

工作原理:CocoStudio 编辑器生成json,通过解析json创建libgdx的原生控件.

目前支持的CocoStudio 控件与实现:

  • ImageView :Image
  • Button :ImageButton
  • LabelBMFont :Label
  • TextField :TextField
  • Label :Label
  • Panel :Table
  • ScrollPane :ScrollPane
  • CheckBox :CheckBox
  • LoadingBar :Image
  • LabelAtlas :LabelAtlas(新增控件,继承于Table)

用得最多的也就这些,其他的后续添加支持.


cocostudio-ui-libgdx的优点: 全部使用的是libgdx的原生控件,actor group image button table 这些.不会产生新学习成本. 使用起来简单易懂.


从CocoStudio 编辑器迁移到libgdx的注意点: CocoStudio 是为cocos2d而生,他一些设定需要注意:

1.文字,CocoStudio的控件用到自定义字体的只有LabelBMFont,其他的 TextField Label 和 button 的文本都只支持ttf文件

2.编辑器的交互属性对应着libgdx 的Touchable 属性.控制控件是否响应事件.对Panel 控件设置false则被设置为 Touchable.childrenOnly,子控件继续可响应事件

3.可以使用2种方式处理图片文件,合并文件方式或者小图片方式.如果是合并图片,一定要确保一个界面使用到的资源在同一个贴图文件内.或者说是把这个界面使用到的图片打包到一个文件里面.CocoStudioUIEditor 的 TextureAtlas参数为null, 则会默认以小图片方式去查找资源

4.重复名字控件集合通过findActors方法获取

5.导出的时候会有选择是否打包成一张图片,如果选择是.那么在构建CocoStudioUIEditor对象的时候 就要传入对应的TextureAtlas 一个界面=一个json文件+TextureAtlas . 如果不打包,就会根据目录去查找文件. 选择打包方式导出 文件后缀为.ExportJson 只是后缀名称变了.

6.为了能让BitmapFont 使用预加载,所以 BitmapFont 是传入CocoStudioUIEditor 而不是自动创建.但是如果你不在乎这点,CocoStudioUIEditor 还是会帮你根据目录名去查找这个BitmapFont 文件并创建

7.CocoStudio 的ttf文件没有记录相对目录,所以无法获取到ttf,因此ttf文件也是由CocoStudioUIEditor传入.已经对使用ttf字体的文本过滤处理.不必担心显示的文字有重复问题.

8.如果没有用到文字显示,可以传入null.当查找不到字体文件的时候会采用libgdx自带字体.new BitmapFont();

9.Button用的libgdx ImageButton实现. CocoStudio中禁用图片 得设置 ImageButton实现 isDisabled = true.

10.最需要注意的就是libgdx 项目中资源目录与CocoStudio 资源目录结构问题了.例如,控件内显示图片的文件路径为:res/img/xx.jpg到了libgdx这边则是去查找img/xx的纹理.过滤掉了 img的父文件夹与.jpg后缀. 如果不是采用合并资源的方式导出,也就是导出后json文件的后缀为.json文件.这种不需要注意这个问题


使用篇

1.创建

//使用合并图片方式 TextureAtlas gui = new TextureAtlas(Gdx.files.internal("ui/gui.txt"));

	CocoStudioUIEditor editer = new CocoStudioUIEditor(
			Gdx.files.internal("login.ExportJson"), gui, null,
			null);

或者使用小图片方式

	CocoStudioUIEditor editer = new CocoStudioUIEditor(
			Gdx.files.internal("login.json"), null, null,
			null);

///因为没有使用到文本,ttf 和 bitmapFont 传入null

	Group group = editer.createGroup();   //创建Group,界面所有元素都已经存在于这个Group里面了
	
	addActor(group);   //添加group 到舞台显示.

2.获取控件

Actor login = editer.findActor("login");//根据控件名字查找

3.添加自己的业务功能

login实际是一个Button,点击跳转到其他场景.所以要添加点击事件.

	login.addListener(new ClickListener() {
		@Override
		public void clicked(InputEvent event, float x, float y) {

			System.out.println("click LOGIN");
			super.clicked(event, x, y);
		}
	});

4.获取编辑的Action

/** 移植的简单动作编辑器功能 */
private void SampleUIAnimation() {

	CocoStudioUIEditor editor = new CocoStudioUIEditor(
			Gdx.files.internal("SampleUIAnimation/SampleUIAnimation.json"),
			null, null, null);
	Group group = editor.createGroup();
	addActor(group);
	// 查找动画
	Map<Actor, Action> actions = editor.getAction("Animation1");
	// 查找演员
	final Actor actor = editor.findActor("ImageView");
	// 查找动作
	final Action action = actions.get(actor);

	Actor textButton = editor.findActor("TextButton");

	textButton.addListener(new ClickListener() {
		@Override
		public void clicked(InputEvent event, float x, float y) {

			// 点击的时候把动作添加到演员上去,然后play!!!
			actor.addAction(action);

			super.clicked(event, x, y);
		}
	});
}

以上则为demo的实际使用情况.和平时开发界面步骤 可能只是把初始化和设置属性的代码变成了 findActor 这一个简单的方法.

5.如何重写/添加控件

例如:重写CCButton,继承CCBUtton,重写parse方法

` public class MyCCButton extends CCButton {

@Override
public Actor parse(CocoStudioUIEditor editor, CCWidget widget,
		CCOption option) {

	final ImageButtonStyle style = new ImageButtonStyle(null, null, null,
			editor.findDrawable(option, option.getNormalData().getPath()),
			editor.findDrawable(option, option.getPressedData().getPath()),
			null);
	style.imageDisabled = editor.findDrawable(option, option
			.getDisabledData().getPath());
	final ImageButton button = new ImageButton(style);
	button.addListener(new ClickListener() {
		@Override
		public boolean touchDown(InputEvent event, float x, float y,
				int pointer, int b) {
			if (style.imageDown == null) {
				button.setScale(1.1f);
			}
			return super.touchDown(event, x, y, pointer, b);
		}

		@Override
		public void touchUp(InputEvent event, float x, float y,
				int pointer, int b) {
			if (style.imageDown == null) {
				button.setScale(1f);
			}
			super.touchUp(event, x, y, pointer, b);
		}
	});

	if (style.imageDown == null) {
		button.setTransform(true);
		button.setOrigin(button.getWidth() / 2, button.getHeight() / 2);
	}

	if (option.getText() != null && !option.getText().equals("")) {
		TTFLabelStyle labelStyle = editor.createLabelStyle(option);
		TTFLabel label = new TTFLabel(option.getText(), labelStyle);
		label.setPosition((button.getWidth() - label.getWidth()) / 2,
				(button.getHeight() - label.getHeight()) / 2);
		button.addActor(label);
	}
	return button;
}

}`

添加新的控件实现,继承GroupParser 或者 WidgetParser. 然后重写 getClassName()方法: className要与cocostudio生成的控件className一致

最后在解析之前添加进解析器

` editor.addParser(new MyCCButton());

	editor.addParser(new CCLabelAtlas());`

MyCCButton 就是为了实现点击button的时候有一个方法的效果.这个在原控件是没有支持选项的.这里我们自己添加

这样就ok了!


上传移植的ui图