8月9日,晴。
“江城如画里,山晓望晴空。
雨水夹明镜。双桥落彩虹。
人烟寒橘柚,秋色老梧桐。”
上篇已经让飞机载入子弹和音效及背景音乐,本篇主要加入敌机。
本篇要用到的几个函数解说:
1、voidsetTag (int nTag) 设置动作的标记。
2、CCRANDOM_0_1()函数生成的是 [0, 1] 之间的随机数。要生成 [0-100] 之间的数CCRANDOM_0_1 * 100;生成 [1,5] 之间的float 数。就是 CCRANDOM_0_1 * 4 + 1。
3、sprite.getContentSize 得到精灵的矩形区域宽、高。获得节点原始的大小,仅仅是逻辑尺寸,不是像素。
float initX = (winSize.width - sprite.getContentSize().width) * ccMacros.CCRANDOM_0_1() + sprite.getContentSize().width/2;
表示敌机在X轴上的任何位置。sprite.getContentSize().width/2是为了防止出现半个敌机。
MainActivity.java
一、
package edu.eurasia.cocos2d_game04; import org.cocos2d.layers.CCScene; import org.cocos2d.nodes.CCDirector; import org.cocos2d.opengl.CCGLSurfaceView; import org.cocos2d.sound.SoundEngine; import android.os.Bundle; import android.app.Activity; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { // 创建一个view对象,cocos2d引擎会把图形绘制在该view对象上面 private CCGLSurfaceView view = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 不显示标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置当前程序全屏显示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置不同意屏幕自己主动休眠 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); view = new CCGLSurfaceView(this); setContentView(view); // 获取导演对象 CCDirector director = CCDirector.sharedDirector(); // 设置游戏引擎画面的输出目标View director.attachInView(view); // 设置游戏是否显示FPS值 // director.setDisplayFPS(true); // 设置游戏的刷新率 FPS = frame per second director.setAnimationInterval(1 / 60.0f); // 生成场景对象 CCScene scene = CCScene.node(); // 生成图层对象 PlaneLayer layer = new PlaneLayer(this); // 将图层加入至场景其中 scene.addChild(layer, 1); // 通知导演,执行场景 director.runWithScene(scene); } @Override protected void onDestroy() { super.onDestroy(); //清理全部的音效 SoundEngine.sharedEngine().realesAllSounds(); SoundEngine.sharedEngine().realesAllEffects(); // 全然关闭音响系统 SoundEngine.purgeSharedEngine(); } }二、PlaneLayer.java
package edu.eurasia.cocos2d_game04; import java.util.ArrayList; import java.util.List; import org.cocos2d.actions.instant.CCCallFuncN; import org.cocos2d.actions.interval.CCMoveTo; import org.cocos2d.actions.interval.CCSequence; import org.cocos2d.config.ccMacros; import org.cocos2d.layers.CCLayer; import org.cocos2d.nodes.CCDirector; import org.cocos2d.nodes.CCSprite; import org.cocos2d.sound.SoundEngine; import org.cocos2d.types.CGPoint; import org.cocos2d.types.CGRect; import org.cocos2d.types.CGSize; import android.content.Context; import android.view.MotionEvent; public class PlaneLayer extends CCLayer { // 声明一个精灵对象 private CCSprite plane; private CCDirector director; private CGSize winSize; private CGPoint offset; private boolean flag = false; // 定义子弹的速度为每秒500像素 private float bulletSpeed = 500; private Context context; private List<CCSprite> bullets = new ArrayList<CCSprite>(); private List<CCSprite> enemies = new ArrayList<CCSprite>(); private static final int E1_TAG = 1; private static final int E2_TAG = 2; public PlaneLayer(Context context) { super(); this.context = context; // 设置当前图层是否接受触摸事件 this.setIsTouchEnabled(true); director = CCDirector.sharedDirector(); winSize = director.winSize(); // 初始化精灵对象 plane = CCSprite.sprite("p.png"); // 设置精灵对象的位置 plane.setPosition(CGPoint.ccp(winSize.width / 2, 200)); this.addChild(plane); // 定时器schedule,加入子弹,每隔0.5秒调用一次 schedule("addBullet", 0.5f); //加入敌人,每隔一秒调用一次 schedule("addEnemy",1f); // 背景音乐 SoundEngine.sharedEngine().playSound(context, R.raw.game_music, true); } // 当用户開始触摸屏幕,运行该方法 @Override public boolean ccTouchesBegan(MotionEvent event) { CGPoint point = director.convertToGL(CGPoint.ccp(event.getX(), event.getY())); CGRect rect = plane.getBoundingBox(); flag = CGRect.containsPoint(rect, point); if (flag) { offset = CGPoint.ccpSub(plane.getPosition(), point); } return super.ccTouchesBegan(event); } // 当用户手指离开屏幕时,运行该方法 @Override public boolean ccTouchesEnded(MotionEvent event) { flag = false; return super.ccTouchesEnded(event); } // 当用户手指在屏幕移动时,运行该方法 @Override public boolean ccTouchesMoved(MotionEvent event) { if (flag) { CGPoint point = director.convertToGL(CGPoint.ccp(event.getX(), event.getY())); point = CGPoint.ccpAdd(point, offset); plane.setPosition(point); } return super.ccTouchesMoved(event); } public void addBullet(float delta) { // 生成一个子弹精灵对象 CCSprite bullet = CCSprite.sprite("bullet.png"); // 将子弹对象加入至图层其中 this.addChild(bullet); // 将新加入的子弹对象放置在bullets集合其中 bullets.add(bullet); // 获得精灵的大小,getContentSize函数来获得节点原始的大小 CGSize planeSize = plane.getContentSize(); CGSize bulletSize = bullet.getContentSize(); CGPoint initPos = plane.getPosition(); // 子弹的y轴的初始位置 initPos.y = initPos.y + planeSize.height / 2 + bulletSize.height / 2; bullet.setPosition(initPos); // 创建一个代表坐标的对象 CGPoint targetPos = CGPoint.ccp(initPos.x, winSize.height); // 计算两个坐标点之间的距离,计算子弹运行的距离 float distance = CGPoint.ccpDistance(initPos, targetPos); // 计算子弹运行的时间 float t = distance / bulletSpeed; // 生成一个动画对象。让子弹移动到屏幕的上端 CCMoveTo moveTo = CCMoveTo.action(t, targetPos); // 生成一个动作对象,该动作运行时,将会调用当前对象的onBulletMoveToFinished方法 // CCCallFuncN: // 它能够让你为某个运行此action的对象指定一个回调函数。我们指定的回调函数是:onBulletMoveToFinished CCCallFuncN func = CCCallFuncN.action(this, "onBulletMoveToFinished"); // CCSequence: // 它同意我们把一系列的action组成一个action序列。而且这些action能够按顺序运行。一次运行全然部的action。 CCSequence seq = CCSequence.actions(moveTo, func); // 通知精灵运行动作 bullet.runAction(seq); // 子弹声效 SoundEngine.sharedEngine().playEffect(context, R.raw.bullet); } public void onBulletMoveToFinished(Object sender) { if (sender instanceof CCSprite) { CCSprite sprite = (CCSprite) sender; // 将子弹对象从集合中移除 bullets.remove(sprite); // 将子弹对象从屏幕中移除 this.removeChild(sprite, true); } } public void addEnemy(float delta){ String imgName = "e1a0.png"; int tag = E1_TAG; //生成的是 [0, 1] 之间的随机数 float ran = ccMacros.CCRANDOM_0_1(); if(ran > 0.8){ imgName = "e2a0.png"; tag = E2_TAG; } //生成代表敌机的精灵对象 CCSprite sprite = CCSprite.sprite(imgName); // 设置动作的标记 sprite.setTag(tag); //将敌机加入到当前图层中 this.addChild(sprite); // 将新加入的敌机对象放置在benemies集合其中 enemies.add(sprite); //计算敌机的初始化位置 float initY = winSize.height + sprite.getContentSize().height/2; float initX = (winSize.width - sprite.getContentSize().width) * ccMacros.CCRANDOM_0_1() + sprite.getContentSize().width/2; //创建一个代表坐标的对象 CGPoint initPos = CGPoint.ccp(initX, initY); //设置敌机的位置 sprite.setPosition(initPos); //计算敌机运行的终点位置 float targetX = initX; float targetY = -sprite.getContentSize().height/2; //创建一个代表坐标的对象 CGPoint targetPos = CGPoint.ccp(targetX, targetY); //计算敌机运行的时间 float t = 3 * ccMacros.CCRANDOM_0_1() + 2; //生成用于移动敌机的MoveTo对象 CCMoveTo moveTo = CCMoveTo.action(t, targetPos); CCCallFuncN func = CCCallFuncN.action(this, "onEnemyMoveToFinished"); CCSequence seq = CCSequence.actions(moveTo, func); // 通知精灵运行动作 sprite.runAction(seq); } public void onEnemyMoveToFinished(Object sender){ if(sender instanceof CCSprite){ CCSprite sprite = (CCSprite)sender; //将飞出屏幕的敌机从集合中移除 enemies.remove(sprite); // 将敌机对象从屏幕中移除 this.removeChild(sprite, true); } } }
三、
执行结果
源码下载地址:http://download.csdn.net/detail/zwszws/7734537
版权声明:本文博客原创文章,博客,未经同意,不得转载。