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

版权声明:本文博客原创文章,博客,未经同意,不得转载。

第四十天 阿乐在其中—Android小游戏的飞机(四)加入敌人的更多相关文章

  1. android小游戏模版—重力感应

               好久没更新博客了,今天来谈谈android小游戏---重力感应,一般在游戏里运用的比較多,比方这类游戏有:神庙逃亡.极品飞车,平衡球.三围重力迷宫,重力赛车等. 首先什么是重力感 ...

  2. 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)

    微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...

  3. 微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)

    微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码 ...

  4. 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)

    微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  5. 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)

    微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  6. Android开发系列(十六):【Android小游戏成语连连看】第二篇

    写的晚了,在分工个Z市高中的一个成绩查询的系统,原系统居然是用VB写的,我不得不佩服原本写系统的那位哥们真能耐得住. 明天搭建下SVN就等着先发project款然后開始项目了.想想有工资进账,心里也为 ...

  7. Android开发系列(十五):【Android小游戏成语连连看】第一篇

            学了一个多月安卓.由于暑假的时候要给朋友说写个小游戏.并且也想检測下自己的能力,所以说从7号開始就着手写这个小游戏了,前前后后带上课到今天总算是写完了,可是写的这个小游戏还是有非常多问 ...

  8. 软件工程 Android小游戏 猜拳大战

    一.前言 最近学校举办的大学生程序设计竞赛,自己利用课余时间写了一个小游戏,最近一直在忙这个写这个小游戏,参加比赛,最终是老师说自己写的简单,可以做的更复杂的点的.加油 二.内容简介 自己玩过Andr ...

  9. 介绍一款Android小游戏--交互式人机对战五子棋

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6589025 学习Android系统开发之余,编 ...

随机推荐

  1. php实现反转链表(链表题一定记得画图)(指向链表节点的指针本质就是一个记录地址的变量)($p->next表示的是取p节点的next域里面的数值,next只是p的一个属性)

    php实现反转链表(链表题一定记得画图)(指向链表节点的指针本质就是一个记录地址的变量)($p->next表示的是取p节点的next域里面的数值,next只是p的一个属性) 一.总结 链表反转两 ...

  2. term- xshell VS securecrt

    Xshell使用技巧总结 https://www.cnblogs.com/zhangwuji/p/7155575.html SecureCRT与Xshell简单对比 http://ju.outofme ...

  3. 最简单的基于FFmpeg的移动端样例:IOS HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  4. kernel build &amp; preempt-rt patch &amp; xenomai

    提前准备好 linux 内核源代码,假设是 x86 系统.能够去下载原生内核(Vanilla kernel): wget https://www.kernel.org/pub/linux/kernel ...

  5. 在Excel中粘贴时怎样跳过隐藏行

    http://www.excel123.cn/Article/exceljichu/201203/932.html 有时在筛选后需要将其他区域中的连续行数据复制粘贴到筛选区域,以替换筛选后的数据.由于 ...

  6. cocos2d-x win8下的环境配置和建立项目

    cocos2dx 跨平台.可是看网上说开发最合适还是在vs2010中,基本是编完后再移植到安卓. 1.去官网下载源代码2.2.3版本号的. 2.然后运行根文件夹下的build-win32.bat(须要 ...

  7. 在CentOS上使用Nginx和Tomcat搭建高可用高并发网站

    目录 目录 前言 创建CentOS虚拟机 安装Nginx 安装Tomcat 安装lvs和keepalived 反向代理 部署网站 搭建数据库 编写网站项目 解决session一致性 注意 参考资料 前 ...

  8. PHP移动互联网开发笔记(1)——环境搭建及配置

    开篇说明:记得我上大二的时候第一次听到PHP,当时只知道这是一个开发网站的语言,并没有深入学习,在学了Java Web开发和Android开发之后我对互联网的发展方向有了一个我自己的认识,现在我们不能 ...

  9. js 进阶 10 js选择器大全

    js 进阶 10 js选择器大全 一.总结 一句话总结:和css选择器很像 二.JQuery选择器 原生javaScript中,只能使用getELementById().getElementByNam ...

  10. Hierarchical Tree Traversal in Graphics Pipeline Stages

    BACKGROUND Many algorithms on a graphics processing unit (GPU) may benefit from doing a query in a h ...