微信小遊戲 demo 飛機大戰 代碼分析(一)(main.js)html
微信小遊戲 demo 飛機大戰 代碼分析(二)(databus.js)canvas
微信小遊戲 demo 飛機大戰 代碼分析(三)(spirit.js, animation.js)數組
本博客將使用逐行代碼分析的方式講解該demo,本文適用於對其餘高級語言熟悉,對js還未深刻了解的同窗,博主會盡量將全部遇到的不明白的部分標註清楚,如有不正確或不清楚的地方,歡迎在評論中指正瀏覽器
本文的代碼均由微信小遊戲自動生成的demo飛機大戰中獲取微信
用於實現敵人對象dom
代碼函數
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) } }
分別是敵機的圖片位置,高度和寬度動畫
敵人類,繼承與Animation類this
構造器code
初始化敵機速度
定義爆炸幀動畫
邏輯更新函數,更新物體的參數,基本每一個具體物體都具備該函數
按速度沒回合加上必定的y座標(因爲敵機是往下走的,所以加上)
若發現對象移動出屏幕,則將其回收
子彈的實現
子彈實現類,繼承於精靈類(沒有繼承於動畫類,其無需動畫)
代碼
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) } }
構造器
初始化座標位置和速度
邏輯更新函數
玩家類
代碼
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) } }
玩家類,繼承於Spirit類
判斷玩家手指是否在飛機上
根據手指的位置設置飛機的位置
保證手指處於飛機中間
同時限定飛機的活動範圍限制在屏幕中
監聽函數
玩家射擊函數