共计 4721 个字符,预计需要花费 12 分钟才能阅读完成。
增加 gameover 素材。
loader.add('enemy', 'images/gameover.png')
减少一个 gameover 变量:
let gameover = false
在敌人的循环中,减少碰撞检测代码:
if(enemy.x + enemy.width > player.x &&
enemy.x < player.x + enemy.width &&
player.y + player.height > enemy.y &&
player.y < enemy.y + enemy.height){gameover = true}
在 step 中,减少:
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)
return
}
当初 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
const enemys = []
let gameover = false
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.on_load_finish((res) => {const player = new Sprite(0, 0, res['player'], 0.5)
player.setPosition(windowWidth / 2, windowHeight - player.height)
const step = (timestamp) => {context.clearRect(0, 0, windowWidth, windowHeight)
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)
return
}
time += 1;
if (time % 150 == 0) {const enemy = new Sprite(0, 0, res['enemy'], 0.5)
enemy.setPosition(rand(0, windowWidth), 0)
enemys.push(enemy)
}
player.update()
player.draw(context)
enemys.map(enemy => {
enemy.y++;
enemy.draw(context)
//collision
if (enemy.x + enemy.width > player.x &&
enemy.x < player.x + enemy.width && player.y + player.height > enemy.y &&
player.y < enemy.y + enemy.height) {gameover = true}
})
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
wx.onTouchMove(function (res) {const x = res.changedTouches[0].clientX
const y = res.changedTouches[0].clientY
player.setPosition(x, y)
})
})
当初成果如下:
gameover 进去后,之前的游戏界面就没了。
所以须要对 update 和 draw 拆开:
const step = (timestamp) => {context.clearRect(0, 0, windowWidth, windowHeight)
//update
if(!gameover){
time += 1;
if (time % 150 == 0) {const enemy = new Sprite(0, 0, res['enemy'], 0.5)
enemy.setPosition(rand(0, windowWidth), 0)
enemys.push(enemy)
}
player.update()
enemys.map(enemy => {
enemy.y++;
//collision
if (enemy.x + enemy.width > player.x &&
enemy.x < player.x + enemy.width && player.y + player.height > enemy.y &&
player.y < enemy.y + enemy.height) {gameover = true}
})
}
//draw
player.draw(context)
enemys.map(enemy => {enemy.draw(context)
})
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);
}
当初成果如下:
然而游戏完结后,player 居然还能够拖动。当初 wx.onTouchMove ~~~~ 这里再改一下:
wx.onTouchMove(function (res) {if (!gameover) {const x = res.changedTouches[0].clientX
const y = res.changedTouches[0].clientY
player.setPosition(x, y)
}
})
当初是成果:
然而发现,其实飞机并没有碰上。为什么呢?
因为这里的碰撞检测仅仅是用矩形。而飞机素材是通明的,因而碰撞到的其实是图片矩形,而飞机素材有透明度,所以看起来仿佛没有碰撞到。这怎么办呢?
要么做像素级的碰撞检测,要么进行多边形像素检测。简单的碰撞检测当前再做,这里先设置一个宽度,既碰撞到肯定水平才确定为碰撞到。
当初,碰撞检测代码变为:
const collision_buff = 0.8
if (enemy.x + enemy.width * collision_buff > player.x &&
enemy.x < player.x + enemy.width * collision_buff && player.y + player.height * collision_buff > enemy.y &&
player.y < enemy.y + enemy.height * collision_buff) {gameover = true}
当初,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
const enemys = []
let gameover = false
const collision_buff = 0.8
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.on_load_finish((res) => {const player = new Sprite(0, 0, res['player'], 0.5)
player.setPosition(windowWidth / 2, windowHeight - player.height)
const step = (timestamp) => {context.clearRect(0, 0, windowWidth, windowHeight)
//update
if (!gameover) {
time += 1;
if (time % 150 == 0) {const enemy = new Sprite(0, 0, res['enemy'], 0.5)
enemy.setPosition(rand(0, windowWidth), 0)
enemys.push(enemy)
}
player.update()
enemys.map(enemy => {
enemy.y++;
//collision
if (enemy.x + enemy.width * collision_buff > player.x &&
enemy.x < player.x + enemy.width * collision_buff && player.y + player.height * collision_buff > enemy.y &&
player.y < enemy.y + enemy.height * collision_buff) {gameover = true}
})
}
//draw
player.draw(context)
enemys.map(enemy => {enemy.draw(context)
})
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)
}
})
})
成果如下
正文完