今天记录工厂实现子弹体系,包括实现子弹类、工厂设计模式、子弹管理类ZDManager三部分内容,详细代码过程见下:
实现目标
一、实现子弹类
子弹放在Maingame,就需要在子弹类中存放Maingame对象。
1public game:MainGame;
2public constructor(game:MainGame) {
3super();
4
5this.game = game;
6}
7}
移动速度原理:
n:角度
向上是正方向,向右顺时针旋转n角度 (子弹向上)
知道角度n 就可以用对边和斜边求V
VX = V * sin n
Vy = -V * cos n
为什么是-y: 因为向上走为 -
//sin用的是弧度制 n是角度制,所以 n* Math.PI / 180 转换为弧度制。
1this.vx = v * Math.sin(n * Math.PI / 180);
2this.vy= -v * Math.cos(n * Math.PI / 180);
若 需要用到任意角度移动,给出指定速度和角度,他的横向距离,横向速度,纵向速度。就是上面代码
前提 :图片竖直向上,正方向是顺时针方向
出现这种情况 肯定是代码出错,但不是编译错误,是代码的逻辑错误,
①空指针:使用了没有构造的对象
②反复移除了同一界面
一般情况下,什么都看不到,肯定是构造出现问题,而构造初的问题,往往会空指针
这里的构造zd使用this.player.x,然而player没有构造,不存在,就使用它的坐标,所以报错
图片叠加顺序跟构造没关系,addChild()才跟图片叠加有关系
所以先全部构造,再全部添加
1this.bg = new BG(this);
2this.player = new Player(this);
3// x,y, 速度,角度
4this.zd = new ZD(this.player.x,this.player.y, 20 ,30,this);
5
6this.addChild(this.bg);
7this.addChild(this.zd);
8this.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一个,仓库对象也越多,子弹也就越多
1public create(x:number,y:number,v:number,n:number,game:MainGame){
2 //生成子弹
3 let one = new ZD(x,y,v,n,game);
4 //添加到世界
5 this.addChild(one);
6 //放到仓库数组最后
7 this.zm.push(one);
8 //
9 }
更新方法
//更新所有子弹,找到每一颗子弹,每颗更新
1public update(){
2 //整个仓库长度 ,利用循环可以循环出所有子弹
3 for(let i = 0 ; i < this.zm.length ; i++){
4 //找到每颗子弹
5 let one = this.zm[i];
6 one.update();
7 //若子弹太多,仓库会满,所以子弹需要移除
8 //子弹出屏,vis == false。移除
9 if(one.vis == false){
10 //先从场景移除
11 this.removeChild(one);
12 //仓库移除
13 this.zm.splice(i ,1);
14 //移除一个对象,长度-1
15 i--;
16 }
17 }
18}
比如现在0,1,2,3 ,4,5更新到3,发现3已经移除,执行移除方法,3消失,4跑到3的位置。5跑到4的位置再更新的时候,需要重新更新3,所以移除完 需要 i --;
此时在Maingame中把zd改为 public zm:ZDManager; //多个子弹
Maingame中的更新方法public update()
1 public update()
2 {
3 this.bg.update();
4 this.player.update();
5 this.zm.update();
6 //时间间隔
7 this.t++;
8 if(this.t >= 4){
9 //调用create才会生成一颗子弹
10 //这里加了2条弹道,一共5条弹道,更有视觉效果
11 this.zm.create(this.player.x,this.player.y,20,0, this );
12 this.zm.create(this.player.x,this.player.y,20,-15, this );
13 this.zm.create(this.player.x,this.player.y,20,-30, this );
14 this.zm.create(this.player.x ,this.player.y,20,15, this );
15 this.zm.create(this.player.x,this.player.y,20,30, this );
16 this.t = 0;
17 }
18 }
至此,第二天的开发笔记已经完成,学习需要坚持,坚持到最后一定会有结果,每天写下笔记来记录自己的学习内容, 以后有需要也可以查看,大家可以一起学习。