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

简介

Egret实战开发,记录每天的学习进度,欢迎和我一起学习交流~

目录

    • 简介
    • 实现目标
    • 一、实现子弹类
    • 二.工厂设计模式
    • 三.子弹管理类ZDManager

实现目标

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

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

一、实现子弹类

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

1public game:MainGame;
2public constructor(game:MainGame) {
3super();
4
5this.game = game;
6}
7}

移动速度原理:
Egret实战开发笔记,飞行射击游戏(二)_第1张图片

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);
若 需要用到任意角度移动,给出指定速度和角度,他的横向距离,横向速度,纵向速度。就是上面代码
前提 :图片竖直向上,正方向是顺时针方向、
Egret实战开发笔记,飞行射击游戏(二)_第2张图片
出现这种情况 肯定是代码出错,但不是编译错误,是代码的逻辑错误,
①空指针:使用了没有构造的对象
②反复移除了同一界面
一般情况下,什么都看不到,肯定是构造出现问题,而构造初的问题,往往会空指针
Egret实战开发笔记,飞行射击游戏(二)_第3张图片
这里的构造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    }

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

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

你可能感兴趣的:(vs,code)