项目结构:
了解本章的时候,相信大家已经成功把hello world在工具cocoseditor运行起来了,现在我们来分析cocos2d-java的项目结构
cce是什么:
cce是cocoseditor的简称,可以理解为是界面设计,可以去表示一个scene,sprite,layer,node等,默认的main.cce是一个场景。cce和官方的cocostudio意思比较接近,它不仅支持可见可得的拖动控件,而且可以通过xml代码直接编写。推荐先通过可见可得搭建好基础控件,然后通过xml代码调整。
有一点需要记清楚:cce里面只是结构化的代码,最后编译的时候还是会转化成相应的java或者c++代码,比如里面有<Sprite name="xx" positionX=100 positionY=100/>
最终还是会转成Sprite sprite=Sprite.create() sprite.setPosition(100,100) 这样的java的代码
cce关联controller:
controller表面很好理解,就是控制中心,对一个cce进行控制,也可以对任何控件进行控制;
我们通过xml代码简单分析一下cce文件。基本遵从cocos的元素,一个Scene上有一个Layer,Layer上面有背景Sprite,而这个Sprite上面有一个关闭按钮Button。通过Compenent可以关联代码SceneController;java包名需要写明org.ccj.game.hello;
可见可得界面设计区域,可看图片文字了解基本概念
元素如何绑定@Bind(Sprite,Button等)
进入hello工程是,我们发现背景图片cocos2dx有缩放的动画,我们可能疑问,在cce里面设计好的图片,代码里面怎么关联并进行操作?
首先在cce里面命名该精灵,如在main.cce里面的代码:图片Sprite name=“bgSprite" 按钮Button name="closeButton"
<Sprite name="bgSprite" texture="textures/main.plist/HelloWorld.png" positionX="241.0" positionY="162.0"> <Button name="closeButton" positionX="441.0" positionY="284.0" textureNormal="textures/main.plist/CloseNormal.png" texturePressed="textures/main.plist/CloseSelected.png"/> </Sprite>
<Component name="org.ccj.game.hello.SceneController"/>把main.cce和SceneController.java关联好了,所以在SceneController里面通过@Bind标签直接关联精灵。这里bgSprite名字和cce里面的名字是一致的,而按钮button还需要@Action绑定。下面的方法是通用,以后其他操作基本类似
@Bind() public Sprite bgSprite; @Override public void onEnter() { super.onEnter(); bgSprite.runAction(Sequence.create(ScaleTo.create(0.5f, 0.3f), ScaleTo.create(0.5f, 1f))); } @Bind("closeButton") @Action(Action.ActionType.WidgetTouchUp) public void onCloseClicked(Ref ref) { Director.getInstance().end(); }
如何调用读取cce文件
我们分析一下Main.java文件;首先进入public static void main,Application启动,getTargetPlatform判断当前的系统,调取openGL,创建了一个指定大小的View;
然后进入mainScene函数里面,实例导演,设置分辨率,状态参数,然后runWithScene(场景跳转函数),去调取main.cce文件。这里我们封装了一个NodeReader函数,来获取layouts文件下面的cce文件,可以readScene,也可以readLayer等等;
public class Main { public static final int DESIGN_WIDTH = 480; public static final int DESIGN_HEIGHT = 320; public static void mainScene() { String paths[] = { "" }; for (String path : paths) { FileUtils.getInstance().addSearchPath(path); } Director director = Director.getInstance(); director.setDisplayStats(true); director.getOpenGLView().setDesignResolutionSize(DESIGN_WIDTH, DESIGN_HEIGHT, GLView.POLICY_EXACT_FIT); director.runWithScene(NodeReader.create().readScene("layouts/main.cce")); } public static void main(String[] args) { int w = DESIGN_WIDTH; int h = DESIGN_HEIGHT; if (args != null && args.length >= 2) { w = Integer.parseInt(args[0]); h = Integer.parseInt(args[1]); } final int width = w; final int height = h; Application app = new Application() { public boolean applicationDidFinishLaunching() { if (OS_WINDOWS == getTargetPlatform() || OS_ANDROID == getTargetPlatform() || OS_MAC == getTargetPlatform()) { GLView eglView = GLView.create("CocosPlayer"); eglView.setFrameSize(width, height); Logger.log("width " + width + " height " + height); Director.getInstance().setOpenGLView(eglView); } Main.mainScene(); return true; } }; app.run(); } }
API在哪里:
很多同学一直在问,api在哪里,因为cocos2d-java只是jni,所以你看到的都是和c++对应好的jni接口代码;比如,你在SceneController.java里面看到Sprite,你可以通过ctrl+鼠标单击,进入Sprite的api,如下图;你发现命名和使用和coos2dx是一样。
JNI到底如何运作:
还是以Sprite为例子,看上面的Sprite图片,假如用户在代码里面使用Sprite.create()这样的函数;首先我们看到JNI里面是存在create()这个函数的,代码运行的时候,这个create()会去调取工具cdk-bin-cocosjava.dll里面的c++库,库里面有对应的代码存在;引擎底层核心还是c++,所以保证java引擎的效率;
简单代码修改:
现在我修改SceneController里面的代码,实现功能如下:创建5*5的图片表格,小图片各自随机旋转动画,点击按钮,创建的5*5图片表格全部删除;
代码如下,童鞋可以把下面代码拷贝过去,试试运行效果。
package org.ccj.game.hello; import org.ccj.Director; import org.ccj.Logger; import org.ccj.base.Color3B; import org.ccj.base.Ref; import org.ccj.d2.Node; import org.ccj.d2.Sprite; import org.ccj.d2.action.RepeatForever; import org.ccj.d2.action.RotateBy; import org.ccj.d2.action.ScaleTo; import org.ccj.d2.action.Sequence; import org.ccj.editor.cce.Action; import org.ccj.editor.cce.Bind; import org.ccj.editor.cce.NodeController; /** */ public class SceneController extends NodeController { @Bind() public Sprite bgSprite; @Override public void onEnter() { super.onEnter(); bgSprite.runAction(Sequence.create(ScaleTo.create(0.5f, 0.3f), ScaleTo.create(0.5f, 1f))); bgSprite.setColor(new Color3B(50, 100, 30)); createManySprites(); } public void createManySprites() { for (int i = 0; i < 25; i++) { Sprite sprite = Sprite.createWithSpriteFrameName("HelloWorld.png"); sprite.setScale(0.1f); sprite.setAnchorPoint(0.5f, 0.5f); sprite.setTag(101); sprite.setPosition(50 + i / 5 * 80, 50 + i % 5 * 60); sprite.runAction(RepeatForever.create(RotateBy.create((float) (Math.random()), 90))); owner.addChild(sprite); } } @Override public void onExit() { super.onExit(); } @Override public void onUpdate(float delta) { super.onUpdate(delta); } @Bind("closeButton") @Action(Action.ActionType.WidgetTouchUp) public void onCloseClicked(Ref ref) { Logger.log("count==" + owner.getChildrenCount()); int counts = owner.getChildrenCount(); for (int i = 0; i < counts; i++) { owner.removeChildByTag(101); } } }