sprite.js 中的 constructor 函数中减少:
this.vx = 0
this.vy = 0
sprite.js 中的 update 函数:
this.x += this.vx
this.y += this.vy
这样,只有设置 vx 或 vy,它就能够本人动了。
在 Sprite.js 中的 constructor 函数设置:
this.on_update = () => {}
这是一个空办法,就是为了在实例化 sprite 时去设置 update 办法
相应地,Sprite.js 中:
update() {
this.x += this.vx
this.y += this.vy
this.on_update()}
则在更新本身坐标后调用了 on_update 办法。
在 Sprite.js 中新增:
remove_from(arr) {const index = arr.indexOf(this)
if (index != -1) {arr.splice(index, 1)
}
}
这样,就能够从 update 中写判断来从数组中移除本人。
在 game.js 中:
bullet.vy = -5
bullet.on_update = () => {if (bullet.y <= 0 - bullet.height) {bullet.remove_from(bullets)
}
}
即敌机坐标超过屏幕下方,就从敌机数组中移除。
同样,把碰撞检测函数放到 Sprite.js 里:
collision_with(arr) {
const self = this
return arr.filter(item => {
return item.x + item.width * this.collision_buff > self.x &&
item.x < self.x + item.width * this.collision_buff && self.y + self.height * this.collision_buff > item.y &&
self.y < item.y + item.height * this.collision_buff
})
}
这时,对 player 而言,如果找到产生碰撞的敌机,则游戏完结:
player.on_update = () => {const arr = player.collision_with(enemys)
if (arr.length > 0) {gameover = true}
}
对于子弹:
const collisioned = bullet.collision_with(enemys)
collisioned.map(item => {
score += 1
item.remove_from(enemys)
})
if (collisioned.length > 0) {bullet.remove_from(bullets)
}
当初,game.js 全副代码为:
import './libs/weapp-adapter'
import './libs/symbol'
import {
ResLoader,
Sprite
} from './codetyphon/index'
const context = canvas.getContext('2d')
const {
windowWidth,
windowHeight
} = wx.getSystemInfoSync()
let time = 0
let enemys = []
let bullets = []
let gameover = false
let score = 0
function rand(min, max) {return Math.round(Math.random() * (max - min) + min);
}
const loader = new ResLoader()
loader.add('player', 'images/player.png')
loader.add('enemy', 'images/enemy.png')
loader.add('gameover', 'images/gameover.png')
loader.add('bullet', 'images/bullet.png')
loader.on_load_finish((res) => {const player = new Sprite(0, 0, res['player'], 0.5)
player.setPosition(windowWidth / 2, windowHeight - player.height)
player.on_update = () => {const arr = player.collision_with(enemys)
if (arr.length > 0) {gameover = true}
}
const update = () => {player.update()
enemys.map((enemy, enemy_index) => {enemy.update()
})
bullets.map((bullet, bullet_index) => {bullet.update()
})
}
const draw = () => {player.draw(context)
enemys.map(enemy => {enemy.draw(context)
})
bullets.map(bullet => {bullet.draw(context)
})
context.font = 'normal 20px sans-serif';
context.fillStyle = '#fff'
context.fillText(score, 10, 30)
}
const step = (timestamp) => {context.clearRect(0, 0, windowWidth, windowHeight)
//update
if (!gameover) {
time += 1;
if (time % 60 == 0) {const enemy = new Sprite(0, 0, res['enemy'], 0.5)
enemy.setPosition(rand(0, windowWidth - enemy.width), 0)
enemy.vy = 3
enemy.on_update = () => {if (enemy.y > windowHeight) {enemy.remove_from(enemys)
}
}
enemys.push(enemy)
}
update()}
draw()
if (gameover) {context.drawImage(res['gameover'], windowWidth / 2 - res['gameover'].width / 4, windowHeight / 2 - res['gameover'].height / 4, res['gameover'].width / 2, res['gameover'].height / 2)
}
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
wx.onTouchMove(function (res) {if (!gameover) {const x = res.changedTouches[0].clientX
const y = res.changedTouches[0].clientY
player.setPosition(x, y)
}
})
wx.onTouchEnd((result) => {if (!gameover) {const bullet = new Sprite(0, 0, res['bullet'], 0.1)
bullet.setPosition(player.x, player.y)
bullet.vy = -5
bullet.on_update = () => {if (bullet.y <= 0 - bullet.height) {bullet.remove_from(bullets)
} else {const collisioned = bullet.collision_with(enemys)
collisioned.map(item => {
score += 1
item.remove_from(enemys)
})
if (collisioned.length > 0) {bullet.remove_from(bullets)
}
}
}
bullets.push(bullet)
}
})
})