Egret实战开发笔记,飞行射击游戏(二)

今天是开发飞行射击游戏第二天,工厂实现子弹体系。欢迎大家和我一起学习哦~ 下面是详细过程代码,还有遇到的错误以及改正方法。
在这里插入图片描述

飞行射击 工厂实现子弹体系

1.实现子弹类

子弹放在Maingame,就需要在子弹类中存放Maingame对象

public game:MainGame;
public constructor(game:MainGame) {
super();

this.game = game;
}
}

移动速度原理:
在这里插入图片描述

n:角度
向上是正方向,向右顺时针旋转n角度 (子弹向上)
知道角度n 就可以用对边和斜边求V
VX = V * sin n
Vy = -V * cos n
为什么是-y: 因为向上走为 -

//sin用的是弧度制 n是角度制,所以 n* Math.PI / 180 转换为弧度制。

this.vx = v * Math.sin(n * Math.PI / 180);
this.vy= -v * Math.cos(n * Math.PI / 180);

若 需要用到任意角度移动,给出指定速度和角度,他的横向距离,横向速度,纵向速度。就是上面代码
前提 :图片竖直向上,正方向是顺时针方向、

在这里插入图片描述
出现这种情况 肯定是代码出错,但不是编译错误,是代码的逻辑错误,①空指针:使用了没有构造的对象
②反复移除了同一界面
一般情况下,什么都看不到,肯定是构造出现问题,而构造初的问题,往往会空指针

这里的构造zd使用this.player.x,然而player没有构造,不存在,就使用它的坐标,所以报错
图片叠加顺序跟构造没关系,addChild()才跟图片叠加有关系
所以先全部构造,再全部添加

this.bg = new BG(this);
this.player = new Player(this);
//              x,y, 速度,角度
this.zd = new ZD(this.player.x,this.player.y, 20 ,30,this);

this.addChild(this.bg);
this.addChild(this.zd);
this.addChild(this.player);

子弹体系:
首先子弹数量很多,子弹数量可变,发射就有,不发射就没有。这时候就得用工厂设计模式

二.工厂设计模式

用来解决个数可变的大量对象的生成和管理。在游戏中会大量使用工厂。

核心:create 方法

只要执行工厂的create,就会生成对象,对象会被放在工厂的仓库里管理。
不断的执行工厂create,工厂会有一个仓库,生产一个会放到仓库里,循环,但是在仓库里的产品,当满足一定条件时,会对仓库内的对象进行移除。
若用工厂管理对象,这个对象就必须有一个属性:
visible( vis)属性: boolean类型代表是否还能在工厂存放。
只要vis == false。这个对象就要移除,来保证仓库不会满。
vis == true 可以存放。

所有被工厂管理的对象都必须有离开工厂的条件,就是对象在什么情况下不需要再存在了。
比如子弹超出屏幕就不存在了。

ZD类申请public vis:boolean; //是否生存
构造:this.vis = true;
更新:
//子弹超出屏幕,子弹消失
//被工厂管理的对象一定要有销毁条件。
子弹类update()方法
if(this.x < -100 || this.x > 580 || this.y < -100 || this.y > 900)
this.vis = false;

三.子弹管理类ZDManager

实现工厂就需要有一个管理子弹的对象。子弹管理者类。以后管理某个对象都需要一个管理者类
子弹管理者也要构建在game里,需要上一级的指针。
仓库是有关子弹的数组
申请:public zm:Array; //Array动态数组(容器),通过添加,添加对象,移除对象。
public game:MainGame;
构造:this.game = game;
this.zm = new Array();

增加生产对象的方法
//每create一次就new一个,仓库对象也越多,子弹也就越多

public create(x:number,y:number,v:number,n:number,game:MainGame){
		//生成子弹
		let one = new ZD(x,y,v,n,game);
		//添加到世界
		this.addChild(one);
		//放到仓库数组最后
		this.zm.push(one);
		//
	}

更新方法
//更新所有子弹,找到每一颗子弹,每颗更新

public update(){
	//整个仓库长度 ,利用循环可以循环出所有子弹
	for(let i = 0 ; i < this.zm.length ; i++){
		//找到每颗子弹
		let one = this.zm[i];
		one.update();
		//若子弹太多,仓库会满,所以子弹需要移除
		//子弹出屏,vis == false。移除
		if(one.vis == false){
			//先从场景移除
			this.removeChild(one);
			//仓库移除 
			this.zm.splice(i ,1);
			//移除一个对象,长度-1
			i--;
		}
	}
}

比如现在0,1,2,3 ,4,5更新到3,发现3已经移除,执行移除方法,3消失,4跑到3的位置。5跑到4的位置再更新的时候,需要重新更新3,所以移除完 需要 i --;

此时在Maingame中把zd改为 public zm:ZDManager; //多个子弹

Maingame中的更新方法public update()


	 public update()
    {
       this.bg.update();
       this.player.update();
       this.zm.update();
       //时间间隔
       this.t++;
       if(this.t >= 4){
           //调用create才会生成一颗子弹
           //这里加了2条弹道,一共5条弹道,更有视觉效果
            this.zm.create(this.player.x,this.player.y,20,0, this );
            this.zm.create(this.player.x,this.player.y,20,-15, this );
            this.zm.create(this.player.x,this.player.y,20,-30, this );
            this.zm.create(this.player.x ,this.player.y,20,15, this );
            this.zm.create(this.player.x,this.player.y,20,30, this );
            this.t = 0;
       }
    }

至此,第二天的开发笔记已经完成,学习需要坚持,坚持到最后一定会有结果,每天写下笔记来记录自己的学习内容, 以后有需要也可以查看,大家可以一起学习。

想要我一起学习的可以关注我的公众号 知言不尽 找到我,交流学习,获取图片素材和源代码。

发布了3 篇原创文章 · 获赞 3 · 访问量 148

猜你喜欢

转载自blog.csdn.net/qq_39207481/article/details/105596006
今日推荐