Android游戏开发之Cocos2d-x

一、简介

游戏的制作如播放电影,拥有四大核心,包括:导演、场景、图层、演员。通过它们之间的不同配合,实现丰富多彩的效果。


二、通用模板

public class CocosActivity extends AppCompatActivity {

private CCDirector mCcDirector;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

CCGLSurfaceView ccglSurfaceView =new CCGLSurfaceView(this);

setContentView(ccglSurfaceView);

导演,全局只有一个,单例模式创建

mCcDirector = CCDirector.sharedDirector();

开启绘制(开始拍电影)

mCcDirector.attachInView(ccglSurfaceView);

帧率,每秒刷新的次数,与手机性能有关

//ccDirector.setDisplayFPS(true);

设置帧率为60(记得把帧率文件放进项目中)

//ccDirector.setAnimationInterval(1/60f);

设置横屏

//ccDirector.setDeviceOrientation(CCDirector.kCCDeviceOrientationLandscapeLeft);

屏幕适配,会基于不同屏幕大小进行适配

mCcDirector.setScreenSize(1920,1080);

场景

CCScene ccScene = CCScene.node();

图层

CCLayer ccLayer =CCLayer.node();

给场景添加图层

ccScene.addChild(ccLayer);

导演运行场景

mCcDirector.runWithScene(ccScene);

}

@Override

protected void onResume() {

super.onResume();

mCcDirector.onResume();

}

@Override

protected void onPause() {

super.onPause();

mCcDirector.onPause();

}

@Override

protected void onDestroy() {

super.onDestroy();

mCcDirector.end();

}


三、动画效果(By or To)

1、平移

参数1是移动时间,参数2是目标位置坐标,ccp方法是把坐标转换为cocos2d的坐标

CCMoveTo ccMoveTo = CCMoveTo.action(3,ccp(200,0));

与上不同的是,第2个参数代表水平移动200,竖直不移动,即偏移量

CCMoveBy ccMoveBy =CCMoveBy.action(3,ccp(200,0));

2、旋转

参数1时间,参数2角度,旋转中心是左下角的点,顺时针转

CCRotateBy ccRotateBy =CCRotateBy.action(3,360);

与上不同的是,逆时针转(捷径,顺时针转270==逆时针转90)

CCRotateTo ccRotateTo =CCRotateTo.action(3,270);

3、缩放

参数1时间,参数2X方向缩放,参数3Y方向缩放

CCScaleBy ccScaleBy =CCScaleBy.action(3,2,2);

参数1时间,参数2缩放

CCScaleTo ccScaleTo =CCScaleTo.action(3,2);

4、跳跃(参数1时间,参数2目标点,参数3跳跃高度,参数4跳跃次数)

CCJumpBy ccJumpBy =CCJumpBy.action(3,ccp(0,0),100,3);

5、淡入淡出(参数是时间)

CCFadeIn ccFadeIn =CCFadeIn.action(2);

CCFadeOut ccFadeOut =CCFadeOut.action(2);

6、贝塞尔曲线

点的含义,从point1出发,经过point2,到达endPosition

CCBezierConfig ccBezierConfig =new CCBezierConfig();

ccBezierConfig.controlPoint_1=ccp(100,50);

ccBezierConfig.controlPoint_2=ccp(200,200);

ccBezierConfig.endPosition=ccp(300,100);

CCBezierBy ccBezierBy =CCBezierBy.action(2,ccBezierConfig);

7、加速度

CCMoveBy ccMoveBy =CCMoveBy.action(2,ccp(100,100));

渐快渐慢,参数2是加速度

CCEaseIn ccEaseIn =CCEaseIn.action(ccMoveBy,5);

CCEaseOut ccEaseOut =CCEaseOut.action(ccMoveBy,5);

8、闪烁(时间,闪烁次数)

CCBlink ccBlink =CCBlink.action(2,10);

9、文字(参1是显示的文字,参2是字体格式(可不填,如""),参数3是字体大小)

CCLabel ccLabel = CCLabel.labelWithString("显示文字","STCAIYUN.TTF",20);

设置文字颜色

ccColor3B ccColor3B =ccc3(100,50,0);

ccLabel.setColor(ccColor3B );

设置文字位置

ccLabel.setPosition(ccp(width,height));

重置文字

ccLabel.setString("显示文字");

颜色渐变(从本来的文字颜色渐变到设置的字体颜色)

CCTintBy tintBy =CCTintBy.action(3,ccc3(50,-50,100));

10、循环(参数是动画效果)

CCRepeatForever ccRepeatForever =CCRepeatForever.action(action);

11、延迟(参数是时间)

CCDelayTime ccDelayTime =CCDelayTime.action(1);

12、反转(将一个动画倒序执行)

ccJumpBy.reverse();

13、同时(参数是不定长度数组)

CCSpawn ccSpawn =CCSpawn.actions(action1,action2);

14、连续动画(参数是不定长度数组)

CCSequence ccSequence =CCSequence.actions(action1,action2,ccCallFunc");

15、反射(执行一个动画方法)

CCCallFunc.action(this,"anim");

被反射的执行方法

public void anim(){} 

16、逐帧动画

public void walk(){

存放帧动画的集合

ArrayList ccSpriteFrames =new ArrayList<>();

String format="z_1_%d.png";  // %d和%02d代表整数,用i来取代,%d只取代i,%02d会补0

for(int i=1;i<10;i++){

CCSprite ccSprite =CCSprite.sprite(String.format(format,i));

CCSpriteFrame ccSpriteFrame =ccSprite.displayedFrame();

ccSpriteFrames.add(ccSpriteFrame );

}

参数1是动画名称,参数2是每一帧停留的时间,参数3是帧动画集合

CCAnimation ccAnimation =CCAnimation.animation("walk",.2f,ccSpriteFrames);

参数2是否持续执行动画,如果想执行无限循环,可以使用CCRepeatForever

CCAnimate ccAnimate =CCAnimate.action(ccAnimation,false);

mCcSprite.runAction(ccAnimate);

}

17、隐藏

CCHide ccHide =CCHide.action();

18、显示

CCShow ccShow =CCShow.action();

19、跟随(参数是跟随的对象)

CCFollow ccFollow =CCFollow.action(mCCSprite);

20、执行动画(上述皆是)

mCcSprite.runAction(action);

21、工具类使用

CGPointUtil.distance(point1,point2); //计算两点距离


四、播放音乐

获取声音引擎

SoundEngine engine =SoundEngine.sharedEngine();

参数1是activity,SurfaceView创建时存入,参2是播放资源id(res\raw),参数3是否循环播放

engine.playSound(CCDirector.theApp,1,true);

手动停止音乐播放

engine.realesAllSounds();

生命周期跟随Activity

SoundEngine.sharedEngine().resumeSound();

SoundEngine.sharedEngine().pauseSound();

SoundEngine.sharedEngine().realesAllSounds();

预加载播放音乐,避免播放音乐时没声音

SoundEngine.sharedEngine().preloadEffect();

SoundEngine.sharedEngine().preloadSound();


五、演员

1、创建

CCSprite mCcSprite =new CCSprite("pic.jpeg");

2、锚点(图片上的一点,类似图钉,对应图片显示的位置)

CGPoint cgPoint =ccp(0,0);

mCcSprite.setAnchorPoint(cgPoint);

3、位置

mCcSprite.setPosition(cgPoint);

4、属性(缩放、翻转、透明度)

ccSprite.setFlipX(true); 水平翻转

ccSprite.setOpacity(255); 透明度

ccSprite.setScale(2); 缩放

5、移除(在Layer里面操作)

mCcSprite.removeSelf();  //精灵从图层中移除

(Layer)this.removeSelf(); // 移除整个图层

6、尺寸

CGSize cgSize =CCDirector.sharedDirector().winSize();


六、图层

1、游戏暂停(图层静止,将不再响应任何事件)

MapLayer.this.onExit(); 

注意:因为图层不再响应任何事件,所以暂停按钮应该加在暂停图层的父图层上

this.getParent().addChild(new PauseLayer());

2、游戏继续(图层恢复动态,接收点击事件)

MapLayer.this.onEnter(); 

通用的游戏继续方法

CCDirector.sharedDirector().getRunningScene().onEnter();

3、定时器

CCScheduler ccScheduler =CCScheduler.sharedScheduler();

通过反射执行方法

ccScheduler.schedule("onScheduler",this,2,false);

方法声明为公开类型

public void onScheduler(float f){ //实现具体逻辑

};

4、进度条

CCProgressTimer ccProgressTimer =CCProgressTimer.progressWithFile("image/pic.jpeg"); //多层目录

ccProgressTimer.setPosition(width,height);

this.getParent().addChild(ccProgressTimer);  //具体加到什么图层,看情况

ccProgressTimer.setScale(0.6f);

ccProgressTimer.setPercentage(2);

设置显示样式(垂直,水平)->(最后2个字母,left,right,代表进度条从左往右)

ccProgressTimer.setType(CCProgressTimer.kCCProgressTimerTypeHorizontalBarLR);

进度条外框等元素,都作为精灵与进度条同级加入图层

this.getParent().addChild(sprite);

注意:不要设置图层的显示位置以及锚点,如果CCNODE在图层中显示的位置有偏差,请设置CCNODE的锚点以及位置来让其正确地显示在图层上。


七、Cocos2d-x坐标

Android坐标系的(0,0)在左上角,而Cocos2d-x坐标系的(0,0)在左下角。所以在处理Android的点击事件MotionEvent时,需要进行坐标体系的转换。

CGPoint cgPoint = convertPrevTouchToNodeSpace(event);

监听图片的点击范围,自定义封装点击事件

CGRect.containsPoint(mCcSprite.getBoundingBox(),cgPoint);


八、菜单

CCMenu ccMenu =CCMenu.menu();

CCSprite normalSprite =CCSprite.sprite("pic_1.jpeg"); //正常情况下显示的图片

CCSprite selectSprite =CCSprite.sprite("pic_2.jpeg"); //按下时显示的图片

注意:反射的方法需要使用pulbic修饰,参数指target,直接传this,它不是上下文Context

CCMenuItemSprite itemSprite=CCMenuItemSprite.item(normalSprite,selectSprite,this,"onCLick");

ccMenu.addChild(itemSprite);

this.addChild(ccMenu); //菜单添加到图层

public void onCLick(Object obj){}  //点击事件响应方法,必须用public修饰以及带参数

setIsTouchEnabled(true); //打开图层点击事件,默认关闭


九、粒子系统(天气特效)

模仿任何天气现象,只需要改这一句,剩下的不变

CCParticleSystem ccParticleSystem= CCParticleSnow.node();

设置雪花大小

ccParticleSystem.setScale(2);

设置飘落的速度

ccParticleSystem.setSpeed(10);

设置雪花的图片

ccParticleSystem.setTexture(CCTextureCache.sharedTextureCache().addImage("snow.png"));

this.addChild(ccParticleSystem,1);

停止粒子系统(下雪)

ccParticleSystem.stopSystem();


十、地图

1、加载地图

 ArrayList mCGPoints = new ArrayList<>();

CCTMXTiledMap mCctmxTiledMap = CCTMXTiledMap.tiledMap("map.tmx");

mCctmxTiledMap.setAnchorPoint(ccp(0.5f,0.f));

mCctmxTiledMap.setPosition(width,height);

CCTMXObjectGroup cctmxObjectGroup= mCctmxTiledMap.objectGroupNamed("road"); 

ArrayList<HashMap<String,String>> objects = cctmxObjectGroup.objects;

for(HashMap<String,String> hashMap:objects){  //加载地图的坐标(需要经过的坐标点)

Integer x =Integer.parseInt(hashMap.get("x"));

Integer y =Integer.parseInt(hashMap.get("y"));

CGPoint cgPoint =ccp(x,y);

mCGPoints.add(cgPoint);  }

this.addChild(mCctmxTiledMap);

在地图上添加精灵

mCCSprite.setPosition(mCGPoints.get(0));

mCctmxTiledMap.addChild(mCCSprite);

地图跟随精灵的移动而移动

CCFollow ccFollow =CCFollow.action(mCCSprite);

mCctmxTiledMap.runAction(ccFollow);

2、地图随手指触摸事件移动(重写触摸方法)

@Override

public boolean ccTouchesMoved(MotionEvent event) {

手指拖拽时,地图随手指移动

mCctmxTiledMap.touchMove(event,mCctmxTiledMap);

地图移动,地图上所有精灵都随之移动(地图是父亲,精灵是孩子)

mCctmxTiledMap.addChild(mCCSprite);

return super.ccTouchesMoved(event);

}


十 一、场景切换

创建场景

CCScene ccScene =CCScene.node();

场景添加图层

ccScene.addChild(ccLayer);

场景切换特效

CCJumpZoomTransition ccJumpZoomTransition =CCJumpZoomTransition.transition(2,ccScene);

导演切换场景

CCDirector.sharedDirector().replaceScene(ccJumpZoomTransition);



十二、CopyOnWriteArrayList

CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。用法和ArrayList相近。

CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList();


十三、点击事件

setIsTouchEnabled(true); //打开点击事件

@Override

public boolean ccTouchesBegan(MotionEvent event) {

return super.ccTouchesBegan(event);

}

@Override

public boolean ccTouchesCancelled(MotionEvent event) {

return super.ccTouchesCancelled(event);

}

@Override

public boolean ccTouchesMoved(MotionEvent event) {

return super.ccTouchesMoved(event);

}

@Override

public boolean ccTouchesEnded(MotionEvent event) {

return super.ccTouchesEnded(event);

}


十四、渲染过渡

描述:UI频繁刷新,造成主线程的堵塞或挂起

private CCGLSurfaceView mCCGLSurfaceView;

mCCGLSurfaceView = (CCGLSurfaceView) CCDirector.sharedDirector().getOpenGLView();

mCCGLSurfaceView.queueEvent(new Runnable() {

@Override

public void run() { //切换到主线程

}

});


十五、动画失效

描述:CCSprite运行动画时,没有表现出任何视觉效果。

原因:一个动画只能被一个CCSprite执行一次,执行完成后,原来的动画会失效。

解决:每次执行的动画,都需要重新生成,即使是相同的动画效果。

缓存:CCDirector.sharedDirector().purgeCachedData();

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容