微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)
微信小游戏 demo 飞机大战 代码分析(一)(main.js)
微信小游戏 demo 飞机大战 代码分析(二)(databus.js)
微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js)
本博客将使用逐行代码分析的方式讲解该demo,本文适用于对其他高级语言熟悉,对js还未深入了解的同学,博主会尽可能将所有遇到的不明白的部分标注清楚,若有不正确或不清楚的地方,欢迎在评论中指正
本文的代码均由微信小游戏自动生成的demo飞机大战中获取
enemy.js
用于实现敌人对象
代码
import Animation from '../base/animation'
import DataBus from '../databus'
const ENEMY_IMG_SRC = 'images/enemy.png'
const ENEMY_WIDTH = 60
const ENEMY_HEIGHT = 60
const __ = {
speed: Symbol('speed')
}
let databus = new DataBus()
function rnd(start, end){
return Math.floor(Math.random() * (end - start) + start)
}
export default class Enemy extends Animation {
constructor() {
super(ENEMY_IMG_SRC, ENEMY_WIDTH, ENEMY_HEIGHT)
this.initExplosionAnimation()
}
init(speed) {
this.x = rnd(0, window.innerWidth - ENEMY_WIDTH)
this.y = -this.height
this[__.speed] = speed
this.visible = true
}
// 预定义爆炸的帧动画
initExplosionAnimation() {
let frames = []
const EXPLO_IMG_PREFIX = 'images/explosion'
const EXPLO_FRAME_COUNT = 19
for ( let i = 0;i < EXPLO_FRAME_COUNT;i++ ) {
frames.push(EXPLO_IMG_PREFIX + (i + 1) + '.png')
}
this.initFrames(frames)
}
// 每一帧更新子弹位置
update() {
this.y += this[__.speed]
// 对象回收
if ( this.y > window.innerHeight + this.height )
databus.removeEnemey(this)
}
}
初始化
导入相应文件
创建所需常量
分别是敌机的图片位置,高度和宽度
创建symbol常量和databus对象
- symbol的解释见 微信小游戏 demo 飞机大战 代码分析 2(databus.js)
rnd(start,end)
- Math.random() 用于提供[0,1)区间的浮点数
- Math.floor() 返回小于等于该数字最大的整数
- 该函数的作用是返回一个start到end区间(end不取)返回内的一个随机数
- 在后面该函数用于生成敌机的位置
Enemy
敌人类,继承与Animation类
constructor()
构造器
- 根据提供的常量初始化敌机对象
- 并且初始化爆炸动画,该函数在之后实现
init(speed)
初始化敌机速度
- 获取随机生成x坐标作为起始x位置
- 获取其本身的高度取负值作为起始y坐标(一开始整个敌机还未进入屏幕,慢慢一点一点进入)
- js中坐标原点为屏幕左上角,以原点向左为x正方向,原点向下为y正方向,
initExplosionAnimation()
定义爆炸帧动画
- 创建一个数组
- 设定爆炸的每一帧动画的具体位置,以及数量
- 创建一个frames数组,将图片按顺序读取并加入数组中
- 将该数组作为Animation类中定义的方法initFrames的参数初始化爆炸动画
update()
逻辑更新函数,更新物体的参数,基本每个具体物体都具有该函数
按速度没回合加上一定的y坐标(由于敌机是往下走的,因此加上)
若发现对象移动出屏幕,则将其回收
bullet.js
子弹的实现
初始化
导入相应包
定义需要的基本常量
定义symbol和生成databus
- symbol的解释见 微信小游戏 demo 飞机大战 代码分析 2(databus.js)
Bullet
子弹实现类,继承于精灵类(没有继承于动画类,其无需动画)
代码
import Sprite from '../base/sprite'
import DataBus from '../databus'
const BULLET_IMG_SRC = 'images/bullet.png'
const BULLET_WIDTH = 16
const BULLET_HEIGHT = 30
const __ = {
speed: Symbol('speed')
}
let databus = new DataBus()
export default class Bullet extends Sprite {
constructor() {
super(BULLET_IMG_SRC, BULLET_WIDTH, BULLET_HEIGHT)
}
init(x, y, speed) {
this.x = x
this.y = y
this[__.speed] = speed
this.visible = true
}
// 每一帧更新子弹位置
update() {
this.y -= this[__.speed]
// 超出屏幕外回收自身
if ( this.y < -this.height )
databus.removeBullets(this)
}
}
constructor
构造器
- 通过预设置的常量初始化超类
init(x, y, speed)
初始化坐标位置和速度
update()
逻辑更新函数
- 为y坐标向上增加速度的大小,即应该减去速度的数值
- 将整个子弹超出屏幕外的(因此是小于-this.height而不是0)移入对象池中,即出游戏
index.js
玩家类
代码
import Sprite from '../base/sprite'
import Bullet from './bullet'
import DataBus from '../databus'
const screenWidth = window.innerWidth
const screenHeight = window.innerHeight
// 玩家相关常量设置
const PLAYER_IMG_SRC = 'images/hero.png'
const PLAYER_WIDTH = 80
const PLAYER_HEIGHT = 80
let databus = new DataBus()
export default class Player extends Sprite {
constructor() {
super(PLAYER_IMG_SRC, PLAYER_WIDTH, PLAYER_HEIGHT)
// 玩家默认处于屏幕底部居中位置
this.x = screenWidth / 2 - this.width / 2
this.y = screenHeight - this.height - 30
// 用于在手指移动的时候标识手指是否已经在飞机上了
this.touched = false
this.bullets = []
// 初始化事件监听
this.initEvent()
}
/**
* 当手指触摸屏幕的时候
* 判断手指是否在飞机上
* @param {Number} x: 手指的X轴坐标
* @param {Number} y: 手指的Y轴坐标
* @return {Boolean}: 用于标识手指是否在飞机上的布尔值
*/
checkIsFingerOnAir(x, y) {
const deviation = 30
return !!( x >= this.x - deviation
&& y >= this.y - deviation
&& x <= this.x + this.width + deviation
&& y <= this.y + this.height + deviation )
}
/**
* 根据手指的位置设置飞机的位置
* 保证手指处于飞机中间
* 同时限定飞机的活动范围限制在屏幕中
*/
setAirPosAcrossFingerPosZ(x, y) {
let disX = x - this.width / 2
let disY = y - this.height / 2
if ( disX < 0 )
disX = 0
else if ( disX > screenWidth - this.width )
disX = screenWidth - this.width
if ( disY <= 0 )
disY = 0
else if ( disY > screenHeight - this.height )
disY = screenHeight - this.height
this.x = disX
this.y = disY
}
/**
* 玩家响应手指的触摸事件
* 改变战机的位置
*/
initEvent() {
canvas.addEventListener('touchstart', ((e) => {
e.preventDefault()
let x = e.touches[0].clientX
let y = e.touches[0].clientY
//
if ( this.checkIsFingerOnAir(x, y) ) {
this.touched = true
this.setAirPosAcrossFingerPosZ(x, y)
}
}).bind(this))
canvas.addEventListener('touchmove', ((e) => {
e.preventDefault()
let x = e.touches[0].clientX
let y = e.touches[0].clientY
if ( this.touched )
this.setAirPosAcrossFingerPosZ(x, y)
}).bind(this))
canvas.addEventListener('touchend', ((e) => {
e.preventDefault()
this.touched = false
}).bind(this))
}
/**
* 玩家射击操作
* 射击时机由外部决定
*/
shoot() {
let bullet = databus.pool.getItemByClass('bullet', Bullet)
bullet.init(
this.x + this.width / 2 - bullet.width / 2,
this.y - 10,
10
)
databus.bullets.push(bullet)
}
}
初始化
导入相应文件
获取屏幕大小作为常量
创建基本常量
Player
玩家类,继承于Spirit类
构造器
- 初始化超类
- 设置玩家初始位置,位于屏幕底部并且居中(应注意判断位置是判断其左上角位置)
- 设定判断是否有触碰的变量和子弹数组
- 初始化事件监听函数
- 事件监听相当于是在等待事件的发生,一旦发生就会随之执行的函数
checkIsFingerOnAir(x, y)
判断玩家手指是否在飞机上
- deviation变量相当于是扩展玩家手指对飞机控制的范围设定的参数
- 判断手指与飞机的关系和位置
setAirPosAcrossFingerPosZ(x, y)
根据手指的位置设置飞机的位置
保证手指处于飞机中间
同时限定飞机的活动范围限制在屏幕中
initEvent()
监听函数
- 绑定touchstart事件, 即开始触碰事件,并传入一个匿名函数作为回调函数,作为触发该事件时的回调
- 若触碰时触碰的是飞机则将飞机被触碰设置为真并且将飞机中心移动到手指中心
- e.preventDefault() 这是取消事件本身的默认动作的函数
- 绑定touchmove事件,即触碰移动
- 若触碰飞机情况为真,则将飞机移动到相应位置
- 绑定touchend事件,即触碰结束
shoot()
玩家射击函数
- 从对象池中取一个子弹
- 根据玩家位置初始化子弹位置
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)的更多相关文章
- 微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)
微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码 ...
- 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)
微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)
微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- Python小游戏之 - 飞机大战美女 !
用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...
- Python小游戏之 - 飞机大战 !
用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...
- 微信demo小游戏:飞机大战从无到有
微信demo游戏飞机大战从无到有 现在创建新项目会默认给飞机大战的demo,这里给大家从基础开始讲解游戏的从无到有是怎么实现的. 具体实现步骤: 创建背景图->背景图运动起来->创建飞机并 ...
- 微信小游戏的本地缓存和清除的使用 (text.js image.js file-util.js)
参考: 微信小游戏,文件系统 UpdateManager-小游戏 一.Egret提供的本地缓存工具类( 备注:新版本进行了修改,并增加了sound.js等) 在微信小游戏项目中,Egret提供了fil ...
- 三、微信小游戏开发 --- 小游戏API调用Platform
微信小游戏API Platform主要是Egret用于来调用平台的SDK的. 在Egret中使用接口定义Platform. Egret项目中默认的platform值是DebugPlatform. 发布 ...
- 二、微信小游戏开发 多线程Worker
微信多线程Worker教程 微信多线程Worker API 一.创建Worker,并和当前线程通讯 多线程worker只能创建1个.能和当前线程互传数据. 创建worker 在微信开发者工具中,在当前 ...
随机推荐
- 练习二十:python计算皮球下落速度练习题
问题简述:假设一个皮球从100米高度自由落下.条件,每次落地后反跳回原高度的一般,在落下 要求:算出皮球,在第十次落地时,共经过多少米?第十次反弹多高? 方法一: h,sum1 = 100,100 # ...
- AJAX下拉框联动
function getProvince() { var ProName = $("#dvProv").val(); LoadProvince(ProName); } functi ...
- Java文件与io——装饰者模式
意图: 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比于生成子类更为灵活.该模式以对客户端透明的方式扩展对象的功能. 适用环境 在不影响其他对象的情况下,以动态.透明的 ...
- vs2017通过snippet代码片断进行标准化注释
我们在进行团队开发时,类的注释已经可以做到自定义了,详细看上篇文章<vs2017通过模块文件添加自定义注释>,而对于方法的注释,我们也需要完善一下,这里我们用到了“代码片断”插件,VS里有 ...
- 【Linux】Linux常用命令大全
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- 【Unity3D】Unity中用C#读取CSV文件
1.创建csv文件 既然做实验嘛,没有资源怎么行,自己徒手写个csv文件吧,打开Numbers工具,新建一个表格文件,我的文件编辑截图如下: 创建完成后,导出成csv格式,我这里文件名为test.cs ...
- arcgis js 几种拓扑关系详解
arcgis js的拓扑关系,在处理复杂逻辑和分析时,可以通过拓扑关系,减小客户端的工作量 拓扑关系: 1.overlaps 重叠 这里的重叠跟平时我们理解的不太一样,这里的重叠,必须是A与B有交集, ...
- Java学习笔记--关于面向对象的思考
1.不可改变的类生成对象以及变量的范围 2. 关键词this的使用 3.用类抽象的思想制作软件 4.通过关系模型建立类 5.使用面向对象的范例来设计程序,遵循类设计指导. 已经学习了:怎么定义类已经创 ...
- 安卓usb数据接收
之前在论坛里面求助了关于监听数据接收的问题,因为第一次做这方面,可能我提的问题太简单了,大神都不愿意回答我,(之前的帖子)晚上FQ浏览网站发现问题的解决办法, 原文是:最近老板让弄安卓和一块板子通信, ...
- 面向对象设计与构造:JML规格单元作业总结
面向对象设计与构造:JML规格单元作业总结 第一部分:JML语言理论基础 JML语言是什么:对Java程序进行规格化设计的一种表示语言 使用JML语言有什么好处: 用逻辑严格的规格取代自然语言,照顾马 ...