• 第四十天 阿乐在其中—Android小游戏的飞机(四)加入敌人


              

                 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


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

  • 相关阅读:
    钉钉内网穿透一键启动cmd脚本
    vscode的开发配置文件
    'scope' is defined but never used解决方法
    微信小程序使用echarts不跟随父元素滑动
    小程序图片开发工具能显示真机调试和体验版不显示
    Web端在线实时聊天,基于WebSocket(前后端分离)
    在vue项目中使用scss,以及vscode适配scss语法(解决使用scss语法编辑器报错)
    自动按需引入组件用不了(Vant)
    npm ERR! Unexpected end of JSON input while parsing near '...'解决方法
    div和img垂直居中的方法
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4710105.html
Copyright © 2020-2023  润新知