因为间接在game.js中写了很多逻辑,因而须要提取一些性能到Game对象中。
新建codetyphon/game.js
把之前在./game.js中的代码移过去
const context = canvas.getContext('2d')const { windowWidth, windowHeight} = wx.getSystemInfoSync()
类对象Game,具备一些属性。
export default class Game { constructor(res_gameover) { this.score = 0 this.life = 1 this.gameover = false this.time = 0 this.on_times = [] this.on_update = () => {} this.player = null this.enemys = [] this.bullets = [] this.foods = [] this.res_gameover = res_gameover }}
如果从新开始游戏,须要从新初始化
restart() { this.enemys = [] this.bullets = [] this.foods = [] this.score = 0 this.life = 1 this.gameover = false this.time = 0}
它得有update、render、start等办法
update(){}render(){}start(){}
把step移过去
start() { const step = (timestamp) => { context.clearRect(0, 0, windowWidth, windowHeight) if (!this.gameover) { this.update() } this.render() if (this.gameover) { this.render_gameover() } window.requestAnimationFrame(step); } window.requestAnimationFrame(step); }
设置增加不同品种的精灵
set_player(player) { this.player = player}add_enemy(enemy) { this.enemys.push(enemy)}add_bullet(bullet) { this.bullets.push(bullet)}add_food(food) { this.foods.push(food)}
对工夫距离的解决:
this.on_times = []
增加一个间隔时间的函数
on_time(time = 100, fn = () => {}) { this.on_times.push({ time: time, fn: fn })}
在update中,解决工夫距离
this.time += 1this.on_times.map(item => { if (this.time % item.time == 0) { item.fn() }})
全副代码如下:
export default class Game { constructor(res_gameover) { this.score = 0 this.life = 1 this.gameover = false this.time = 0 this.on_times = [] this.on_update = () => {} this.player = null this.enemys = [] this.bullets = [] this.foods = [] this.res_gameover = res_gameover } restart() { this.enemys = [] this.bullets = [] this.foods = [] this.score = 0 this.life = 1 this.gameover = false this.time = 0 } set_player(player) { this.player = player } add_enemy(enemy) { this.enemys.push(enemy) } // remove_enemy(enemy) { // } // remove_bullet(bullet) { // } // remove_food(food) { // } add_bullet(bullet) { this.bullets.push(bullet) } add_food(food) { this.foods.push(food) } on_time(time = 100, fn = () => {}) { this.on_times.push({ time: time, fn: fn }) } update() { if (this.player) { this.player.update() } this.enemys.map(item => item.update()) this.bullets.map(item => item.update()) this.foods.map(item => item.update()) } render_life(x = 8, y = 30, fontSize = 20) { context.font = `normal ${fontSize}px serif` context.fillStyle = '#fff' context.fillText(` x ${this.life}`, x, y) } render_score(x = 10, y = 60, fontSize = 20) { context.font = `normal ${fontSize}px sans-serif` context.fillStyle = '#fff' context.fillText(`score: ${this.score}`, x, y) } render() { if (this.player) { this.player.draw(context) } this.enemys.map(item => item.draw(context)) this.bullets.map(item => item.draw(context)) this.foods.map(item => item.draw(context)) this.render_life() this.render_score() } render_gameover() { context.drawImage(this.res_gameover, windowWidth / 2 - this.res_gameover.width / 4, windowHeight / 2 - this.res_gameover.height / 4, this.res_gameover.width / 2, this.res_gameover.height / 2) } start() { const step = (timestamp) => { context.clearRect(0, 0, windowWidth, windowHeight) if (!this.gameover) { this.time += 1 this.on_times.map(item => { if (this.time % item.time == 0) { item.fn() } }) this.update() this.on_update() } this.render() if (this.gameover) { this.render_gameover() } window.requestAnimationFrame(step); } window.requestAnimationFrame(step); }}
这样,./game.js 就变为:
import './libs/weapp-adapter'import './libs/symbol'import { ResLoader, Sprite, Game} from './codetyphon/index'const { windowWidth, windowHeight} = wx.getSystemInfoSync()function rand(min, max) { return Math.round(Math.random() * (max - min) + min);}let click = 0const 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) => { let game = new Game(res['gameover']) game.life = 3 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(game.enemys) if (arr.length > 0) { game.life -= 1 if (game.life <= 0) { game.gameover = true } else { arr.map(item => { item.remove_from(game.enemys) game.score += 1 }) } } } game.set_player(player) game.on_time(200, () => { //add food }) game.on_time(80, () => { const enemy = new Sprite(0, 0, res['enemy'], 0.5) enemy.setPosition(rand(0, windowWidth - enemy.width), 0) enemy.vy = rand(3, 10) enemy.on_update = () => { if (enemy.y > windowHeight) { enemy.remove_from(game.enemys) } } game.add_enemy(enemy) }) game.on_update = () => { } game.start() wx.onTouchMove(function (res) { if (!game.gameover) { const x = res.changedTouches[0].clientX const y = res.changedTouches[0].clientY player.setPosition(x, y) } }) wx.onTouchEnd((result) => { if (!game.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(game.bullets) } else { const collisioned = bullet.collision_with(game.enemys) collisioned.map(item => { game.score += 1 item.remove_from(game.enemys) }) if (collisioned.length > 0) { bullet.remove_from(game.bullets) } } } game.add_bullet(bullet) } if (game.gameover) { click++ if (click >= 2) { game.restart() click = 0 } } })})