微信小游戏 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对象

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

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)的更多相关文章

  1. 微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)

    微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码 ...

  2. 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)

    微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  3. 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)

    微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  4. Python小游戏之 - 飞机大战美女 !

    用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...

  5. Python小游戏之 - 飞机大战 !

    用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...

  6. 微信demo小游戏:飞机大战从无到有

    微信demo游戏飞机大战从无到有 现在创建新项目会默认给飞机大战的demo,这里给大家从基础开始讲解游戏的从无到有是怎么实现的. 具体实现步骤: 创建背景图->背景图运动起来->创建飞机并 ...

  7. 微信小游戏的本地缓存和清除的使用 (text.js image.js file-util.js)

    参考: 微信小游戏,文件系统 UpdateManager-小游戏 一.Egret提供的本地缓存工具类( 备注:新版本进行了修改,并增加了sound.js等) 在微信小游戏项目中,Egret提供了fil ...

  8. 三、微信小游戏开发 --- 小游戏API调用Platform

    微信小游戏API Platform主要是Egret用于来调用平台的SDK的. 在Egret中使用接口定义Platform. Egret项目中默认的platform值是DebugPlatform. 发布 ...

  9. 二、微信小游戏开发 多线程Worker

    微信多线程Worker教程 微信多线程Worker API 一.创建Worker,并和当前线程通讯 多线程worker只能创建1个.能和当前线程互传数据. 创建worker 在微信开发者工具中,在当前 ...

随机推荐

  1. lintcode 解码方法

    简单的动态规划 class Solution { public: /* * @param s: a string, encoded message * @return: an integer, the ...

  2. ZC01

    1.苏州市住房公积金管理中心 http://www.szgjj.gov.cn/szgjj/ 2.苏州社保 http://www.szsbzx.net.cn:9900/web/website/index ...

  3. count(1), count(*), count(col) 的区别

    1.count(1)和count(*)都是统计表的总行数,两者执行结果相同.表没有主键或者唯一键索引时,两者都进行全表扫描:表上主键或者唯一键索引时,使用主键或者唯一键索引. 2.count(col) ...

  4. linux读取yaml文件的某个属性值

    trigger=$(cat test.yaml | grep "trigger" | awk '{print $2}') 该条命令的意思是:读取test.yaml文件中的trigg ...

  5. vbox和宿主机共享文件夹

    首先,查看vbox安装的ubuntu是否支持vboxsf模块 sudo modprobe vboxsf dmesg | grep vboxsf 如果没有安装,需要安装vboxsf模块:(如果安装了请跳 ...

  6. 网络编程——TCP协议

    1.TCP程序概述 TCP是一个可靠的协议,面向连接的协议. 实现TCP程序,需要编写服务器和客户端,Java API为我们提供了java.net包,为实现网络应用程序提供类. ServerSocke ...

  7. Linux安装配置相关

    1.常用汇总 useradd usertemp //添加用户 passwd usertemp //修改/设置密码 userdel usertemp //删除用户 2. profile/baserc等配 ...

  8. 在loader程序中涉及到的CPU模式切换

    在实模式下开启4GB的物理内存地址寻址(称之为Big Real Mode) 通过A20快速门(Fast Gate)修改0x90端口的数据, 对其进行置位(类似于打开一个开关), 开启 使用CLI汇编指 ...

  9. springcloud中servcie层调用fegin异常以及异步方法的实现

    近日在做业务上的短信推送和APP消息推送,通过调用别的模块的接口来实现,在springcloud中通过fegin进行调用.这里要说明的事情并不是如何开发推送功能,而是在调试过程中碰到的一些小问题.我把 ...

  10. 扩展(spread)/收集(rest)运算符

    一.扩展运算符(spread)    场景:使用在数组之前. 作用:将一个数组转为用逗号分隔的参数序列 举例1:数组之前 function foo(x, y, z){ console.log(x, y ...