Egret学习笔记 (Egret打飞机-5.实现子弹对象)
上一章把飞机添加到屏幕上,但是飞机要发射子弹对吧?那么这一章我们就来实现一下发射子弹,并实现一个简单的子弹对象池
先来捋一捋思路
1.创建一个子弹对象
2.然后添加一个bitmap,显示子弹贴图
3.判断子弹类型(我们这里是一个子弹是敌人和主角都在使用,根据不同的状态类型,显示不同的图和往不同的方向飞行)
4.子弹回收(回收子弹的意思就是把子弹状态还原,并且从界面中移除)
5.子弹对象池的设计(综合上面四点,设计一个简单的对象池)
6.主角发射子弹
首先,我们先新建一个IdentityType.ts的文件,这是一个标识身份的枚举。用来区别是主角发射的子弹还是敌人发射的子弹
/**
* 子弹类型
*/
enum IdentityType {
/**
* 敌人
*/
ENEMY,
/**
* 主角
*/
HERO
}
然后创建一个BulletObject.ts,顾名思义就是子弹对象的意思。子弹的一切操作,都在这个类里面完成
class BulletObject extends egret.DisplayObjectContainer {
_bullet: egret.Bitmap;
public btype: IdentityType;
/**
* 是否使用
*/
public IsUse: boolean = false;
_main: Main;
_speed = 5;
public constructor(main: Main) {
super();
this.width = 9;
this.height = 21;
this._main = main;
this._bullet = new egret.Bitmap();
this.addChild(this._bullet)
}
frame() {
// console.log("Bullet Frame")
if (this.IsUse) {
if (this.btype == IdentityType.ENEMY) {
this.y += this._speed;
}
if (this.btype == IdentityType.HERO) {
this.y -= this._speed;
if (this.y <= 0) {
//从父节点中移除
if (this.parent) {
this.parent.removeChild(this);
this.Recycle();
}
}
}
}
}
/**
* 使用
*/
public Use(type: IdentityType, x: number, y: number) {
this.IsUse = true;
this.x = x;
this.y = y;
this.btype = type;
if (type == IdentityType.ENEMY) {
this._bullet.texture = RES.getRes("bullet1_png")
}
else {
this._bullet.texture = RES.getRes("bullet2_png")
}
this._main.addChildAt(this, 10)
this.addEventListener(egret.Event.ENTER_FRAME, this.frame, this)
}
/**
* 回收
*/
public Recycle() {
console.log("回收子弹:" + this.btype)
this.IsUse = false;
this.removeEventListener(egret.Event.ENTER_FRAME, this.frame, this)
}
}
在构造方法中,我们初始化了子弹对象的宽高和图片显示对象,但是这里不给bitmap的texture赋值,需要再使用的时候赋值
Use和Recycle方法都是在外部调用。
Use是使用这个对象,做的操作是根据外部传递进来的值来确定自己的主角的子弹还是敌人的子弹,并给texture赋值一个对应身份状态的图片对象,并且监听Enter_frame事件,在每一帧,对应移动当前子弹的坐标
Recycle方法是回收当前子弹,把子弹状态都还原,并且移除ENTER_FRAME事件的监听
然后实现一个简单的对象池
/**
* 初始化对象池
*/
InitPool() {
for (var i = 0; i < 50; i++) {
var bullet = new BulletObject(this);
this._bullet.push(bullet)
}
}
/**
* 从对象池获取一个Bullet
*/
public GetBullet(): BulletObject {
for (var i = 0; i < this._bullet.length; i++) {
if (this._bullet[i].IsUse == false) {
return this._bullet[i];
}
}
console.log("对象池已经用光了,可能是没有回收")
}
对象池这个东西按我个人的理解就是先初始化一堆东西放到一个篮子里,然后需要的时候,就去篮子里拿,用完再放回去,实现资源的重复利用,避免频繁的对象new的操作。
子弹和对象池都搞定了,然后来实现主角发射子弹
玩过微信打飞机游戏的都知道,主角飞机是不停的发射子弹。飞机移动位置,子弹也对应从飞机的头部发射子弹
我的思路就是,在飞机对象里面放一个Timer定时器,500毫秒发射一个子弹。然后自定义一个子弹发射的事件,飞机发射子弹的时候,只触发发射事件,并不实际发射子弹,我们在飞机的外部容器,也就是我们的Main这个容器中,监听对象,把子弹对象添加到Main中
先新建一个文件OpenFireEvent.ts
class OpenFireEvent extends egret.Event {
public static EventString = "开火";
/**
* 事件类型默认是Hero
*/
public Btype: IdentityType = IdentityType.HERO;
public constructor(type: string, bubbles: boolean = false, cancelable: boolean = false) {
super(type, bubbles, cancelable);
}
}
然后再HeroObject.ts的ADDED_TO_STAGE事件里面添加一个timer
this._heroOpenFireEvent = new OpenFireEvent(OpenFireEvent.EventString);
this._heroOpenFireEvent.Btype = IdentityType.HERO;
this.addEventListener(egret.Event.ENTER_FRAME, this.frame, this);
this._timer = new egret.Timer(GameConfig.HeroOpenFireTime);
this._timer.addEventListener(egret.TimerEvent.TIMER, this.timerFunc, this);
this._timer.addEventListener(egret.TimerEvent.COMPLETE, this.timerComplete, this);
this._timer.start();
.....
public timerFunc(e: egret.TimerEvent) {
// console.log("定时开火--------------------")
this.dispatchEvent(this._heroOpenFireEvent);
}
在Timer的每次调用中,我们触发开火事件。
这里触发了开火的事件,需要让这个事件生效,我们就需要在其他的地方监听这个事件
所以在Main的添加主角对象的地方
this._Hero.addEventListener(OpenFireEvent.EventString, (e: OpenFireEvent) => {
var b = this.GetBullet();
if (b == undefined) {
console.log("对象池中没有对象")
return;
}
var x = this._Hero.x + this._Hero.width / 2 - 5;
var y = this._Hero.y - 18;
b.Use(IdentityType.HERO, x, y)
}, this)
监听到事件之后,从对象池中取出一个子弹对象,然后计算这个子弹应该出现的坐标x=(英雄的X坐标+英雄的宽度/2),y=(英雄的Y坐标-子弹的高度) ,不要问我为啥我还有一个-5在后面,估计是我的图片大小不标准,然后我对坐标进行微调了一下。。这样看起来正常一点。。。
需要源码的,可以加QQ群来问我要哈,等这一系列学习笔记写完了,我再上传到github去
Egret学习笔记 (Egret打飞机-5.实现子弹对象)的更多相关文章
- Egret学习笔记 (Egret打飞机-9.子弹对敌机和主角的碰撞)
运行起来,虽然主角飞机和敌机都在互相发射子弹,但是子弹打中了就和没打中效果是一样的.. 这一章我们就来处理子弹和飞机的碰撞问题. 我们所有的操作都是基于Main这个容器来做的.所以我就把这个处理放到M ...
- Egret学习笔记 (Egret打飞机-8.敌机和主角飞机发射子弹)
经过前面几章的准备,我们差不多已经具备了一个基本的框架,这一章我们就开始添砖加瓦了. 敌机定时发射一个子弹,子弹的方向是从上到下,但是发射子弹的代码应该放在哪儿呢? 从面向对象编程的思想来说,子弹是敌 ...
- Egret学习笔记 (Egret打飞机-7.实现敌机工厂)
在游戏过程之,敌机是源源不断的冲屏幕上方往下飞,如果我们每一架敌机都直接new的话,在飞机很多的情况下,也许有性能问题. 就像前面子弹对象池一样,我们也要实现一个飞机对象池,也就是标题说的敌机工厂(之 ...
- Egret学习笔记 (Egret打飞机-6.实现敌机飞起来)
有了子弹,总得有敌人来打吧,不然游戏有啥意思呢?今天我们来实现敌机从屏幕上边往下飞 参考微信打飞机游戏里面,敌机分为3种 1是特小飞机,2是小飞机,还有一种就是大飞机 面向对象编程提倡抽象,实现代码复 ...
- Egret学习笔记 (Egret打飞机-4.添加主角飞机和实现飞行效果)
今天继续写点击了开始之后,添加一个飞机到场景中,然后这个飞机的尾巴还在冒火的那种感觉 先拆解一下步骤 1.首先完成飞机容器的图片加载 2.然后把容器添加到场景中 3.然后实现动画 -首先,我们新建一个 ...
- Egret学习笔记 (Egret打飞机-3.实现背景循环滚动)
游戏背景里面的猪脚飞机看起来是一直在向前飞,但是实际上只是一个视觉差而已. 猪脚是出于不动的状态,背景从上到下滚动,然后让玩家觉得飞机在不停的往前飞.(当然这只是其中一种实现思路) 差不多就是这样,然 ...
- Egret学习笔记 (Egret打飞机-1.大致思路)
大致看了一遍Egret的官方文档,就开始打算使用Egret来开发一个打飞机游戏. 首先来捋一捋思路,先来看一看一个打飞机游戏的图片 基本上一个打飞机游戏分为 开始游戏 ----------进入游戏 ...
- Egret学习笔记 (Egret打飞机-2.开始游戏)
打开 Egret Wing,新建一个Egret游戏项目,然后删掉默认生成的createGameScene方法里面的东西 然后新建一个BeginScene.ts的文件,作为我们的游戏的第一个场景 cla ...
- matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象
一起来学matlab-matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matl ...
随机推荐
- mybatis用spring的动态数据源实现读写分离
一.环境: 三个mysql数据库.一个master,两个slaver.master写数据,slaver读数据. 二.原理: 借助Spring的 AbstractRoutingDataSource 这个 ...
- python_爬校花图片
如何用python爬取校花图片并保存到本地来? 1. 获取什么数据? 校花名字 name 校花所在学校 school 校花图片的url img_ulr 2.如何获取? 打开网页http://ww ...
- 模态框zeroModal快速引入
最基本快速接入 <%@ page language="java" contentType="text/html; charset=UTF-8" pageE ...
- Java多线程之线程其他类
Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...
- 《共享库PATH与ld.so.conf简析》
这是摘抄<共享库PATH与ld.so.conf简析>1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个 ...
- css 块状元素与行内元素(内联元素)的理解
块状元素: 它一般是其他元素的容器元素,可以容纳块状元素和行内元素,它默认是不会和其他元素同一行的,即相当于两个块状元素写一起是垂直布局的.最常用的是div和p 行内元素: 行内元素又称内联元素,它只 ...
- 布衣之路(一):VMware虚拟机+CentOS系统安装
前言:布衣博主乃苦逼的Java程序猿一枚,虽然工作中不会涉及系统运维,但是开发的项目总还是要部署到服务器做一些负载均衡.系统兼容性测试.系统集成等等骚操作,而这些测试性的操作不可能直接SSH远程运维的 ...
- awk的+=用法
awk增加统计列值为增加列数或进行运行结果统计,使用符号 + =.增加的结果赋给符号左边变量值,增加到变量的域在符号右边.例如将 $ 1加入变量total,表达式为toatl+=$1.列值增加很有用. ...
- Oracle中 in、exists、not in,not exists的比较
最基本的区别: in 对主表使用索引 exists 对子表使用索引 not in 不使用索引 not exists 对主子表都使用索引 写法: exist的where条件是: "...... ...
- 【OH】Oracle软件安装需要的软件包(官方文档)
1 安装12c 1.1 Table 3 x86-64 Supported Linux 7 Operating System Requirements Item Requirements SSH R ...