什么是游戏引擎
游戏引擎是指一些已编写好的可编辑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。
Cocos2d家族
cocos2d是一个开源的游戏开发框架,利用它可以非常容易的开发2D游戏。 包括以下成员
- Cocos2d-x
- Cocos2d-iphone
- Cocos2d-android
本质区别:开发的语言不一样:Cocos2d-x使用c++、Cocos2d-iphone使用Object-C;共同点:api名字基本一致
我们为什么要使用cocos2d
- 一款开源的,跨平台,轻量级的2D游戏引擎。
- 性能良好
- 广泛的社区支持
- 拥护很多成功案例。比如捕鱼达人,三国塔防等
- 使用MIT授权协议。可以自由使用,修改源码,不需要像GPL一样公开源码,可以商用
架构
![cocos](https://img-blog.csdn.net/20161115103832547)
- 图形引擎Cocos2D Graphic
- 声音引擎CocosDenshion
- 物理引擎:Box2d、Chipmunk
![cocos](https://img-blog.csdn.net/20161115105344602)
架构说明
- Cocos2D Graphic图形引擎
- CocosDenshion Audio声音引擎
- 物理引擎
- Lua脚本库
Box2D是一个用于模拟2D刚体物体的C++引擎。作者为Erin Catto。
chipmunk本是一个独立的开源项目,用纯c编写
Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
图形引擎Cocos2D Graphic
CCDirector界面的统一管理者
![cocos](https://img-blog.csdn.net/20161115104234791)
图形引擎说明
![cocos](https://img-blog.csdn.net/20161115104308705)
- CCDirector(导演):引擎的控制者,控制场景的切换,游戏引擎属性的设置
- CCScene (场景):场景类,例如游戏的闪屏,主菜单,游戏主界面等。
- CCLayer(布景):图层类,每个图层都有自己的触发事件,该事件只能对其拥有的元素有效,而图层之上的元素所包含的元素,是不受其事件管理的
- CCSprite(人物):精灵类,界面上显示的最小单元
- CCNode:引擎中最重要的元素,所有可以被绘制的东西都是派生于此。它可以包含其它CCNode,可以执行定时器操作,可以执行CCAction。
- CCAction(动作):动作类,如平移、缩放、旋转等动作
CCDirector
CCGLSurfaceView
引擎中SurfaceView的子类,实现了SurfaceHolder.Callback接口,但并未实现Runnable接口。
存在问题:
1、绘制界面的线程是谁?
2、该线程是如何启动的?
CCDirector的作用
界面的绘制工作是由GLThread来完成,而GLThread的开启是在CCDirector的attachInView方法中完成的。
管理场景CCScene
CCDirector,导演类,负责管理和切换场景。还负责初始化openGL各项参数。
CCDirector引擎的控制者,控制场景的切换,游戏引擎属性的设置
单例模式,sharedDirector()取得对象
方法 | 功能描述 |
---|
sharedDirector() | 获取CCDirector对象,单例模式 |
attachInView() | 连接OpenGL的SurfaceView |
runWithScene() | 运行场景 |
replaceScene() | 替换场景 |
setDeviceOrientation() | 设置横屏竖屏 |
setDisplayFPS(true) | 显示fps帧率 |
setAnimationInterval(1.0f / 60) | 设置帧率,每秒刷新60次 |
setScreenSize(480, 320) | 设置屏幕分辨率,高于设置的分辨率时,引擎会自动适配 |
resume() | 进入运行状态 |
pause() | 暂停 |
end() | 结束 |
public class MainActivity extends Activity {
private CCDirector director;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CCGLSurfaceView surfaceView=new CCGLSurfaceView(this);
setContentView(surfaceView);
director = CCDirector.sharedDirector();
director.attachInView(surfaceView);
director.setDeviceOrientation(CCDirector.kCCDeviceOrientationLandscapeLeft);
director.setDisplayFPS(true);
director.setScreenSize(480, 320);
CCScene ccScene=CCScene.node();
ccScene.addChild(new ActionLayer());
director.runWithScene(ccScene);
}
@Override
protected void onResume() {
super.onResume();
director.resume();
}
@Override
protected void onPause() {
super.onPause();
director.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
director.end();
}
}
FirstLayer
public class FirstLayer extends CCLayer {
private CCSprite ccSprite;
public FirstLayer() {
setIsTouchEnabled(true);
init();
}
@Override
public boolean ccTouchesBegan(MotionEvent event) {
CGPoint convertTouchToNodeSpace = this.convertTouchToNodeSpace(event);
System.out.println("我被按下了");
CGRect boundingBox = ccSprite.getBoundingBox();
boolean containsPoint = CGRect.containsPoint(boundingBox, convertTouchToNodeSpace);
if(containsPoint){
ccSprite.setScale(ccSprite.getScale()+0.2);
}else{
ccSprite.setScale(ccSprite.getScale()-0.2);
}
return super.ccTouchesBegan(event);
}
private void init() {
CCSprite bg = CCSprite.sprite("bbg_arena.jpg");
bg.setAnchorPoint(0, 0);
this.addChild(bg,0);
ccSprite = CCSprite.sprite("z_1_attack_01.png");
ccSprite.setAnchorPoint(0,0);
ccSprite.setPosition(100, 100);
ccSprite.setScale(1);
ccSprite.setVisible(true);
this.addChild(ccSprite);
this.addChild(ccSprite, 1, 10);
}
}
ActionLayer
public class ActionLayer extends CCLayer {
public ActionLayer(){
init();
}
private void init() {
JumpBy();
}
private void blink() {
CCBlink blink=CCBlink.action(3, 3);
getSprite().runAction(blink);
}
private void tint() {
CCLabel label=CCLabel.labelWithString("那些年,我们在黑马的苦逼日子", "hkbd.ttf", 24);
label.setColor(ccc3(50, 0, 255));
label.setPosition(200,200);
this.addChild(label);
ccColor3B c=ccc3(100, 255, -100);
CCTintBy by=CCTintBy.action(1, c);
CCTintBy reverse = by.reverse();
CCSequence actions = CCSequence.actions(by, reverse);
CCRepeatForever forever=CCRepeatForever.action(actions);
label.runAction(forever);
}
private void ease() {
CCMoveTo ccMoveTo=CCMoveTo.action(10, CCNode.ccp(200, 0));
CCEaseIn easeOut=CCEaseIn.action(ccMoveTo,9);
getSprite().runAction(easeOut);
}
private void fadeIn() {
CCFadeIn fadeIn=CCFadeIn.action(10);
getSprite().runAction(fadeIn);
}
private void bezierBy() {
CCBezierConfig c=new CCBezierConfig();
c.controlPoint_1=ccp(0, 0);
c.controlPoint_2=ccp(100, 100);
c.endPosition=ccp(200, 0);
CCBezierBy bezierBy=CCBezierBy.action(2, c);
getSprite().runAction(bezierBy);
}
private void rotateTo() {
CCSprite heart = getHeart();
heart.setPosition(200, 100);
CCRotateTo rotateTo=CCRotateTo.action(3, 240);
heart.runAction(rotateTo);
}
private void rotateBy() {
CCRotateBy by=CCRotateBy.action(3, 240);
getHeart().runAction(by);
}
private void scaleBy() {
CCScaleBy ccScaleBy=CCScaleBy.action(1f, 0.65f);
CCScaleBy reverse = ccScaleBy.reverse();
CCSequence sequence=CCSequence.actions(ccScaleBy, reverse);
CCRepeatForever forever=CCRepeatForever.action(sequence);
getHeart().runAction(forever);
}
private void JumpBy() {
CCJumpBy ccJumpBy=CCJumpBy.action(4, ccp(200, 100), 100, 2);
CCRotateBy ccRotateBy=CCRotateBy.action(2, 360);
CCSpawn ccSpawn=CCSpawn.actions(ccJumpBy, ccRotateBy);
CCSequence sequence=CCSequence.actions(ccSpawn, ccSpawn.reverse());
CCRepeatForever forever=CCRepeatForever.action(sequence);
CCSprite sprite = getSprite();
sprite.setAnchorPoint(0.5f, 0.5f);
sprite.setPosition(50, 50);
sprite.runAction(forever);
}
private void moveBy() {
CCSprite sprite = getSprite();
sprite.setPosition(0, 100);
CCMoveBy ccMoveBy=CCMoveBy.action(2, CCNode.ccp(200, 0));
CCMoveBy reverse = ccMoveBy.reverse();
CCSequence sequence=CCSequence.actions(ccMoveBy, reverse);
sprite.runAction(sequence);
}
public void moveTo() {
CCSprite sprite = getSprite();
CCMoveTo ccMoveTo=CCMoveTo.action(2, CCNode.ccp(200, 0));
CCIntervalAction reverse = ccMoveTo.reverse();
CCSequence sequence=CCSequence.actions(ccMoveTo, reverse);
sprite.runAction(sequence);
}
public CCSprite getSprite() {
CCSprite sprite=CCSprite.sprite("z_1_attack_01.png");
sprite.setAnchorPoint(0,0);
this.addChild(sprite);
return sprite;
}
public CCSprite getHeart() {
CCSprite sprite=CCSprite.sprite("heart.png");
sprite.setPosition(100, 100);
this.addChild(sprite);
return sprite;
}
}
CCAction
对于一个游戏来说,动作是非常重要的,好的动作可以使游戏的可玩性大大提高,在cocos2d引擎中有一个动作类,CCAction是动作类的基类,动作是定义在节点(CCNode)上的,以节点为目标,主要分为两类瞬时动作和延时动作
![CCAction](https://img-blog.csdn.net/20161115133619172)
基本动作
Cocos2d提供的基本动作:瞬时动作、延时动作、运作速度。
1、瞬时动作:就是不需要时间,马上就完成的动作。瞬时动作的共同基类是 InstantAction。
Cocos2d提供以下瞬时动作:
放置 – Place
效果类似于 node.Position = ccp(x, y)。之所以作为一个动作来实现是为了可以与其他动作形成一个连续动作。
隐藏 – Hide
效果类似于 [node setVisible:NO]. 之所以作为一个劢作来实现是为了可以与其他动作形成一个连续动作。
显示 – Show
效果类似于 [node setVisible:YES]. 之所以作为一个动作来实现是为了可以与其他动作形成一个连续动作。
可见切换 – ToggleVisibility
2.延时动作
延时动作就是指动作的完成需要一定时间。因此actionWithDuration 是延时动作执行时的第一个参数,延时动作的共同基类是 CCIntervalAction(包含了组合动作类)。
Cocos2d提供以下瞬时动作(函数命名规则是:XxxxTo: 意味着运动到指定的位置, XxxxBy:意味着运动到按照指定的 x、y 增量的位置。[x、y 可以是负值]):
移动到 – CCMoveTo
移动– CCMoveBy
跳跃到 – CCJumpTo 设置终点位置和跳跃的高度和次数。
跳跃 – CCJumpBy 设置终点位置和跳跃的高度和次数。
贝塞尔 – CCBezierBy 支持 3 次贝塞尔曲线:P0-起点,P1-起点切线方向,P2-终点切线方向,P3-终点。
放大到 – CCScaleTo 设置放大倍数,是浮点型。
放大 – CCScaleBy
旋转到 – CCRotateTo
旋转 – CCRotateBy
闪烁 – CCBlink 设定闪烁次数
色调变化到 – CCTintTo
色调变换 – CCTintBy
变暗到 – CCFadeTo
由无变亮 – CCFadeIn
由亮变无 – CCFadeOut
3.组合动作
按照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作。组合动作包括以下几类:
序列 – CCSequence
Sequence 的使用非常简单,该类也从 CCIntervalAction 派生,本身就可以被 CocosNode 对象执行。该类的作用就是线序排列若干个动作,然后按先后次序逐个执行。
同步 – Spawn
Spawn 的使用非常简单,该类也从 IntervalAction 派生,本身就可以被CocosNode 对象执行。该类的作用就是同时并列执行若干个动作,但要求动作都必须是可以同时执行的。比如:移动式翻转、变色、变大小等。
需要特别注意的是,同步执行最后的完成时间由基本动作中用时最大者决定。
重复有线次数 – Repeate
重复有限次数的动作,该类也从 IntervalAction 派生,可以被 CocosNode 对象执行。
反动作 – Reverse
反动作就是反向(逆向)执行某个动作,支持针对动作序列的反动作序列。反动作不是一个专门的类,而是 CCFiniteAction 引入的一个接口。不是所有的类都支持反动作,XxxxTo 类通常不支持反动作,XxxxBy 类通常支持。
动画 – Animation
动画就是让精灵自身连续执行一段影像,形成模拟运动的效果:行走时的精灵状态、打斗时的状态等。
无限重复 – RepeatForever
RepeatForever 是从 Action 类直接派生的,因此无法参与序列和同步;自身也无法反向执行。该类的作用就是无限期执行某个动作或动作序列,直到被停止。
4.速度变化
基本动作和组合动作实现了针对精灵的各种运动、动画效果的改变,但这样的改变的速度是不变的,通过 CCEaseAction 为基类的类系和 CCSpped 类我们可以很方便的修改精灵执行劢作的速度:由快至慢还是由慢至快。
EaseIn 由慢至快。
EaseOut 由快至慢
EaseInOut 由慢至快再由快至慢。
EaseSineIn
由慢至快。
EaseSineOut 由快至慢
EaseSineInOut 由慢至快再由快至慢。
EaseExponentialIn 由慢至极快。
EaseExponentialOut 由极快至慢。
EaseExponentialInOut 由慢至极快再由极快至慢。
Speed 人工设定速度,还可通过 SetSpeed 不断调整。
5.扩展动作
延时动作 – Delay ,比如在动作序列中增加一个时间间歇
函数调用
函数在动作序列中间或者结束调用某个函数,执行任何需要执行的任务:动作、状态修改等。id acf = [CCCallFunc actionWithTarget:self selector:@selector(CallBack1)];对应的函数为:- (void) CallBack1 {
[sprite runAction:[CCTintBy actionWithDuration:0.5 red:255 green:0 blue:255]]; }
带对象参数–调用自定义函数时,传递当前对象。id acf = [CallFuncN actionWithTarget:self selector:@selector(CallBack2:)];对应的自定义函数:(这里,我们直接使用了该对象)
- (void) CallBack2:(id)sender {
[sender runAction:[CCTintBy actionWithDuration:1 red:255 green:0 blue:255]]; }
带 对象、数据参数–用自定义函数时,传递当前对象和一个常量(也可以是指针)。id acf = [CCCallFuncND actionWithTarget:self selector:@selector(CallBack3:data:) data:(void*)2];对应的自定义函数,我们使用了传递的对象和数据:
-(void) CallBack3:(id)sender data:(void*)data {
[sender runAction:[CCTintBy actionWithDuration:(NSInteger)data red:255 green:0 blue:255]]; }
游戏地图制作
工具: Tiled绘图工具
图层:展示整体效果
块层:依据块划分图片后,整张图片会变成一个块层
块:块层中的一个单元
对象层:单独一层,放置一些指定的对象
地图制作,使用Tiled 制作地图。地图大小的宽度表示地图的一行有14 块组成,地图大小的高度表示地图一列有6 块组成,块大小的宽度表示每块的宽度为46px,块大小的高度表示每块的高度为53px。
新建地图文件,如下图1,生成的地图如下图2
![游戏地图](https://img-blog.csdn.net/20161118102827972)
![游戏地图](https://img-blog.csdn.net/20161118102913926)
接着将下图3中标红的图片拖入Tiled 的图层中。在下图4中直接点击确定
![这里写图片描述](https://img-blog.csdn.net/20161118103145494)
![这里写图片描述](https://img-blog.csdn.net/20161118103155385)
在图2.5 中选择一块草地点击,将鼠标移动到新建的地图中点击鼠标左键安放草块,如图2.6。
![这里写图片描述](https://img-blog.csdn.net/20161118103251713)
![这里写图片描述](https://img-blog.csdn.net/20161118103300370)
在图层中选择一块道路点击,如图2.7,将鼠标移动到新建的地图中点击鼠标左键安放道路,做出一条九曲十八弯的小路,如图2.8。
![这里写图片描述](https://img-blog.csdn.net/20161118103408964)
![这里写图片描述](https://img-blog.csdn.net/20161118103419558)
设置拐点。先添加一个对象层,如图2.9。然后在工具栏点击添加对象,如图2.10,最后在地图上的拐点处单击鼠标左键,如图2.11。
![这里写图片描述](https://img-blog.csdn.net/20161118103546871)
![这里写图片描述](https://img-blog.csdn.net/20161118103557201)
![这里写图片描述](https://img-blog.csdn.net/20161118103607215)
步骤:
1、新建地图,设置地图大小(以块为单位),设置块大小(以像素为单位)
2、显示网格需要设置视图中的显示网格选项
3、通过地图—新图块,来导入地图资源,从而利用工具进行地图的编辑
4、对象层,通过在图层里右键添加。
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="14" height="6" tilewidth="46" tileheight="54">
<tileset firstgid="1" name="bk1" tilewidth="46" tileheight="54">
<image source="bk1.jpg" width="678" height="320"/>
</tileset>
<layer name="block" width="14" height="6">
<data encoding="base64" compression="zlib">
eJwTY2BgECMDW6BhQuK4zCDEprY+YtxMyBx8GADLYgpH
</data>
</layer>
<objectgroup name="road" width="14" height="6">
<object x="22" y="80"/>
<object x="160" y="82"/>
<object x="161" y="244"/>
<object x="299" y="243"/>
<object x="298" y="82"/>
<object x="436" y="83"/>
<object x="436" y="246"/>
<object x="620" y="246"/>
</objectgroup>
</map>
生成的tmx文件说明:
1、Image source属性中填写相对路径
2、层和对象命名尽量使用英文
3、关于对象层中信息,封装在objectgroup中
4、objectgroup中信息按照操作顺序进行排列object
游戏地图加载
加载:CCTMXTiledMap.tiledMap(name);
添加到当前显示层,存在问题:
无法进行图片的移动
用户的touch事件处理:
setIsTouchEnabled(true);
CCTMXTiledMap.touchMove(MotionEvent event, CCTMXTiledMap tiledMap);
存在问题:地图移动
获取图片大小,设置图片位置为宽高的一半
设置锚点为0.5,0.5
public class DemoLayer extends CCLayer {
private CCTMXTiledMap map;
private List<CGPoint> roadPoits;
public DemoLayer() {
this.setIsTouchEnabled(true);
init();
}
private void init() {
loadMap();
parserMap();
loadParticle();
loadZombies();
}
private void loadParticle() {
system = CCParticleSnow.node();
system.setTexture(CCTextureCache.sharedTextureCache().addImage("f.png"));
this.addChild(system, 1);
}
int position = 0;
private CCSprite sprite;
private CCParticleSystem system;
private void loadZombies() {
sprite = CCSprite.sprite("z_1_01.png");
sprite.setPosition(roadPoits.get(0));
sprite.setAnchorPoint(0.5f, 0);
sprite.setScale(0.65f);
sprite.setFlipX(true);
map.addChild(sprite);
ArrayList<CCSpriteFrame> frames = new ArrayList<CCSpriteFrame>();
String format = "z_1_%02d.png";
for (int i = 1; i <= 7; i++) {
CCSpriteFrame displayedFrame = CCSprite.sprite(
String.format(format, i)).displayedFrame();
frames.add(displayedFrame);
}
CCAnimation anim = CCAnimation.animation("走路", 0.2f, frames);
CCAnimate animate = CCAnimate.action(anim);
CCRepeatForever forever = CCRepeatForever.action(animate);
sprite.runAction(forever);
moveToNext();
}
int speed=40;
public void moveToNext() {
position++;
if (position < roadPoits.size()) {
CGPoint cgPoint = roadPoits.get(position);
float t=CGPointUtil.distance(roadPoits.get(position-1), cgPoint)/speed;
CCMoveTo moveTo = CCMoveTo.action(t, cgPoint);
CCSequence ccSequence = CCSequence.actions(moveTo,
CCCallFunc.action(this, "moveToNext"));
sprite.runAction(ccSequence);
} else {
system.stopSystem();
sprite.stopAllActions();
dance();
SoundEngine engine=SoundEngine.sharedEngine();
engine.playSound(CCDirector.theApp, R.raw.psy, true);
}
}
private void dance() {
sprite.setAnchorPoint(0.5f, 0.5f);
CCJumpBy ccJumpBy=CCJumpBy.action(2, ccp(-20,10), 10, 2);
CCRotateBy by=CCRotateBy.action(1, 360);
CCSpawn ccSpawn=CCSpawn.actions(ccJumpBy, by);
CCSequence sequence=CCSequence.actions(ccSpawn, ccSpawn.reverse());
CCRepeatForever forever=CCRepeatForever.action(sequence);
sprite.runAction(forever);
}
private void parserMap() {
roadPoits = new ArrayList<CGPoint>();
CCTMXObjectGroup objectGroupNamed = map.objectGroupNamed("road");
ArrayList<HashMap<String, String>> objects = objectGroupNamed.objects;
for (HashMap<String, String> hashMap : objects) {
int x = Integer.parseInt(hashMap.get("x"));
int y = Integer.parseInt(hashMap.get("y"));
CGPoint cgPoint = ccp(x, y);
roadPoits.add(cgPoint);
}
}
@Override
public boolean ccTouchesMoved(MotionEvent event) {
map.touchMove(event, map);
return super.ccTouchesMoved(event);
}
private void loadMap() {
map = CCTMXTiledMap.tiledMap("map.tmx");
map.setAnchorPoint(0.5f,0.5f);
map.setPosition(map.getContentSize().width/2,map.getContentSize().height/2);
this.addChild(map);
}
@Override
public boolean ccTouchesBegan(MotionEvent event) {
this.onExit();
this.getParent().addChild(new PauseLayer());
return super.ccTouchesBegan(event);
}
private class PauseLayer extends CCLayer{
private CCSprite heart;
public PauseLayer(){
this.setIsTouchEnabled(true);
heart = CCSprite.sprite("heart.png");
CGSize winSize = CCDirector.sharedDirector().getWinSize();
heart.setPosition(winSize.width/2, winSize.height/2);
this.addChild(heart);
}
@Override
public boolean ccTouchesBegan(MotionEvent event) {
CGRect boundingBox = heart.getBoundingBox();
CGPoint convertTouchToNodeSpace = this.convertTouchToNodeSpace(event);
if(CGRect.containsPoint(boundingBox, convertTouchToNodeSpace)){
this.removeSelf();
DemoLayer.this.onEnter();
}
return super.ccTouchesBegan(event);
}
}
}
粒子系统
什么是粒子系统
粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的 game physics。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。
![粒子系统](https://img-blog.csdn.net/20161118104337375)
实现方式:
使用代码设置参数
导入属性列表文件的方式来配置所要添加的粒子系统。
实现步骤:
CCParticleSystem system= CCParticleSnow.node()
system.setTexture(CCTextureCache.sharedTextureCache().addImage("f.png"))
this.addChild(system, 1)
自定义效果:
制作工具ParticleDesigner,使用工具将效果导出成.plist文件
CCParticleSystem ps=CCParticleSystemPoint.particleWithFile("f.plist")
ps.setPosition(0,winSize.height)
addChild(ps)
CocosDenshion Audio声音引擎
SoundEngine处理声音,内部封装的是MediaPlayer和SoundPool
声音类型:音乐和音效
可以从长短上来做区分,音乐一般用于游戏的背景声音,音效主要是短小的声音,如植物发射子弹,僵尸吃植物时发出的声音
声音控制,如播放、暂停、声音大小调节、静音
通过缓存音乐和音效文件来提高声音处理的效率
SoundEngine engine=SoundEngine.sharedEngine();
engine.playSound(CCDirector.theApp, R.raw.psy, true);
游戏暂停处理
处理游戏暂停思路
当前的主CCLayer处于暂停状态,处于暂停状态的CCLayer无法接收到用户的触摸事件
在主CCLayer暂停之前需要启动另外一个CCLayer显示,除提示玩家游戏已经暂停外,如果玩家需要切换到游戏界面需要点击当前的CCLayer中的按钮完成继续游戏的处理。
注意:
1、该暂停用CCLayer必须添加到与主CCLayer相同的parent下,不能再主CCLayer继续添加
2、点击完成时需要清除当前显示的CCLayer
核心方法:onEnter()——游戏继续
onExit——游戏暂停
@Override
public boolean ccTouchesEnded(MotionEvent event) {
PauseLayer pauseLayer=new PauseLayer();
this.getParent().addChild(pauseLayer);
onExit();
return super.ccTouchesEnded(event);
}
private class PauseLayer extends CCLayer
{
CCSprite sprite ;
public PauseLayer() {
setIsTouchEnabled(true);
sprite = CCSprite.sprite("ZombiesWon.jpg");
sprite.setScale(0.3);
sprite.setPosition(240, 160);
this.addChild(sprite);
}
@Override
public boolean ccTouchesEnded(MotionEvent event) {
if (isClick(event, sprite)) {
MyDemoLayer.this.onEnter();
this.removeSelf();
}
return true;
}
}
protected boolean isClick(MotionEvent event,CCNode sprite)
{
CGPoint clickPoint = this.convertTouchToNodeSpace(event);
return CGRect.containsPoint(sprite.getBoundingBox(), clickPoint);
}
原文链接:http://blog.csdn.net/axi295309066/article/details/53169104