共计 4792 个字符,预计需要花费 12 分钟才能阅读完成。
因为间接在 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 += 1
this.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 = 0
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) => {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
}
}
})
})
正文完