微信小游戏 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. HDU 2473 Junk-Mail Filter 并查集,虚拟删除操作

    http://acm.hdu.edu.cn/showproblem.php?pid=2473 给定两种操作 第一种是合并X Y 第二种是把X分离出来,就是从原来的集合中分离出来,其它的关系不变. 关键 ...

  2. postman将上一个请求的结果作为下一个请求的数据

    需要在Tests中写入如下代码: var jsonData = JSON.parse(responseBody); postman.setGlobalVariable("token" ...

  3. linux 编程笔记1 crusher for linux

    1.反显示字符crusher #include <stdio.h> int main (int argc, char *argv[]) { printf("\033[7m mor ...

  4. 物体检测丨浅析One stage detector「YOLOv1、v2、v3、SSD」

    引言 之前做object detection用到的都是two stage,one stage如YOLO.SSD很少接触,这里开一篇blog简单回顾该系列的发展.很抱歉,我本人只能是蜻蜓点水,很多细节也 ...

  5. Cmd命令 关机

    at 22:00 Shutdown -s 到了22点电脑就会出现"系统关机"对话框,默认有30秒钟的倒计时并提示你保存工作 Shutdown.exe -s -t 3600 这里表示 ...

  6. 【踩坑】mysql LIMIT 与 ORDER BY位置问题

    今天在重做iblog项目后台时,当测试功能,发现后台报错,位置在 MyBatis 向 MySQL 取数据时的语法问题,如下: SELECT * FROM article WHERE authorID ...

  7. 如何下载最新的固件到Pixhawk

    连接Pixhawk至电脑 当Mission Planner 已经安装至你的电脑上,使用micro USB数据线连接pixhawk到您的计算机上. 使用一个USB端口直接在您的计算机上,不要用USB集线 ...

  8. contenttype组件、Django缓存机制以及跨域请求

    1 昨日回顾 版本控制 *** (1)url=127.0.0.1/course/?version=v100000 1 versioning_class=QueryParameterVersioning ...

  9. HTTP响应报文与工作原理详解(转)

    超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到 ...

  10. 【Android开发笔记】底部菜单栏 FragmentTabHost

    公司项目,需求本来是按照谷歌官方指南写的,菜单栏设计成在导航栏下方 结果呢,审评时,BOSS为了和iOS统一,改成了底部菜单栏(标准结局),我只能呵呵呵呵呵呵呵 查了查资料发现实现底部菜单栏用的是Fr ...