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. [Angular] Alternative Themes - Learn the Host-Context Selector

    To add alernative theme, we can use :host-context() selector from Angular. //au-fa-input-red-theme.c ...

  2. JNI——Java调用C/C++函数

    从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java.C/C++的桥梁——JNI.哈哈!分享一下!   一.简介 JNI是Java native interface的简 ...

  3. php 删除数组指定元素,下标还不乱

    $arr是目标数组 $offset是要删除的元素的key 1是指删除的长度 array_splice($arr, $offset, 1); 之前用的unset,但是比如删除的是第三个,那么下标的2就会 ...

  4. 设置secureCRT中vim的字体颜色 分类: B3_LINUX 2014-07-12 22:01 1573人阅读 评论(0) 收藏

    1.在/etc/vimrc新增以下一行 syntax on 注:上述方法对root用户无效,原因为在一般用户中,alias vi=vim,而在root用户中默认无此设置,因此若需要root用户也显示颜 ...

  5. 《大型网站技术架构》1:概述 分类: C_OHTERS 2014-05-07 20:40 664人阅读 评论(0) 收藏

    参考自<大型网站技术架构>第1~3章 1.大型网站架构演化发展历程 (1)初始阶段的网站架构:一台服务器分别作为应用.数据.文件服务器 (2)应用服务和数据服务分离:三台服务器分别承担上述 ...

  6. 【2001】关于N!的问题

    Time Limit: 3 second Memory Limit: 2 MB 编写程序,计算n!以十进制数形式表示的数中最右边一个非零数字,并找出在它右边有几个零. 例如:12!=1*2*3*4*5 ...

  7. android Navigator的高度计算和推断是否显示

    进入互联网行业几天了, 从手机行业转到互联网行业也在慢慢的适应: IDE工具的使用(之前一直在Ubuntu 命令行进行开发). 版本号管理工具,代码架构等等这些都须要又一次适应. 好在本人另一些底子, ...

  8. php实现表示数值的字符串(is_numeric($s))

    php实现表示数值的字符串(is_numeric($s)) 一.总结 is_numeric($s) 二.php实现表示数值的字符串 题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数) ...

  9. nopCommerce 3.9 大波浪系列 之 使用部署在Docker中的Redis缓存主从服务

    一.概述 nop支持Redis作为缓存,Redis出众的性能在企业中得到了广泛的应用.Redis支持主从复制,HA,集群. 一般来说,只有一台Redis是不可行的,原因如下: 单台Redis服务器会发 ...

  10. Django之文章归档

    1.任务描述:将博文按照时间月份归档 2.源代码: views.py def getPage(request, article_list): paginator = Paginator(article ...