微信小游戏 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. Spring学习(二)Spring的bean管理(XML)

    Bean的实例化方式 1.在Spring里面通过配置文件创建对象 2.bean实例化的三种方式第一种:使用类的无参数构造函数创建(最常用的方式,第2种和第3种方法一般不用) 如果类里面没有无参的构造函 ...

  2. dotnet core 命令行使用web deploy 部署项目到远程IIS

    众所周知dotnet cli可以用来编译和生成发布.net core,其实dotnet publish 还能进行WebDeploy.先解释一下使用场景一般是用于持续部署 dotnet publish进 ...

  3. aop 切面配置

    <bean id="userServiceImpl" class="com.bj.aop.xml.before.UserServiceImpl">& ...

  4. Hystrix核心基础 - 滑动窗口创建过程及demo

    前言 RxJava可能有些小伙伴没有听过是什么东西,可能是因为大家平时在做业务需求的时候对异步编程了解得比较少,而RxJava就是这么一个响应式编程框架,RxJava在安卓上面用得非常多,做安卓的朋友 ...

  5. Maven基本使用汇总

    1. 基础问题 0.eclipse工程转maven工程:工程->右键->configure->convert to maven project 1.pom.xml总是在项目的根目录. ...

  6. 用汇编实现add函数

    平台 macOS 工具 nasm clang 文件 main.c #include <stdio.h> int add(int a, int b); int main() { printf ...

  7. Django之model基础(增删改查)

    一.ORM 映射关系 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象二.创建表(建立模型) 在创建表之前的准备 ...

  8. Javascript Events

    事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行. 事件句柄 html4.0的新特性之一是有能力使html事件触发浏览器中的动作action,比如当用户点击某个html元素时启动一段Ja ...

  9. laydate 显示结束时间不小于开始时间

    jsp: <div class="form-group">    <label >交易时间:</label>        <input ...

  10. Node.js连接MongoDB

    使用monk访问mongodb mongodb.monk都安装了依赖的前提下: 首先启动MongoDB 服务:mongod: 进入了mongodb后台管理,再通过终端创建数据库:use monk-ap ...