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. Canvas基础知识总结之中的一个

    canvas的HTML语法: <canvas> Canvas not supported </canvas> 上面这句代码中内容部分所含的文本,这种文本的叫法"后备内 ...

  2. html表单元素及表单元素详解

    原文 https://www.jianshu.com/p/b427daa8663d 大纲 1.认识表单 2.认识表单元素 3.表单元素的分类 4.表单元素——文本框 5.表单元素button 6.表单 ...

  3. Android 利用线程运行栈StackTraceElement设计Android日志模块

    如果你想在你的Android程序中自动打印MainActivity.onCreate(line:37)这种类名.方法名(行数)的日志该如何实现呢? 1.引入Java的线程运行栈 Java.lang包中 ...

  4. 【41.43%】【codeforces 560C】Gerald's Hexagon

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. [Angular Directive] 3. Handle Events with Angular 2 Directives

    A @Directive can also listen to events on their host element using @HostListener. This allows you to ...

  6. [转] Valgrind使用

    http://www.cnblogs.com/napoleon_liu/articles/2001802.html 调不尽的内存泄漏,用不完的Valgrind Valgrind 安装 1. 到www. ...

  7. PHP移动互联网开发笔记(5)——基础函数库

    一.数学函数库 ● floor 舍一取整(向下取整) float floor (float $value); <?php echo(floor(0.60)."<br>&qu ...

  8. Android EditText文本内容变化监听方法

    package com.google; import android.app.Activity; import android.os.Bundle; import android.text.Edita ...

  9. c++11之初始化列表

    一.前言     C++的学习中.我想每一个人都被变量定义和申明折磨过,比方我在大学笔试过的几家公司.都考察了const和变量,类型的不同排列组合,让你差别有啥不同.反正在学习C++过程中已经被折磨惯 ...

  10. 5.7-GTID复制搭建

    基本环境   Master Slave MySQL版本 MySQL-5.7.16-X86_64 MySQL-5.7.16-X86_64 IP 192.168.56.156 192.168.56.157 ...