前言
在原有的基础上(原生js打砖块游戏(一)—— 基础框架)增加了障碍物,并将几个不同的模块分离,增加了关卡选择功能。
在调试方面,增加了简单的调试模块。
游戏效果
按“3”选择进入第三关卡(emmm就是三个block),其中最右边的block有两条命。
说明
首先将上次的代码分成guaGame.js/paddle.js/ball.js三个文件,又新添了level.js文件,代码如下:
var levels = [
[
[0, 0,],
],
[
[100, 0,],
[200, 200,],
],
[
[50, 30,],
[300, 200, 2,],
[400, 300,],
],
]
var loadLevel = function(n) {
n -= 1
var level = levels[n]
var blocks = []
for (var i=0; i<level.length; i++) {
var p = level[i]
var b = Block(p)
blocks.push(b)
}
return blocks
}
将每个关卡中block的数据单独保存起来,levels的前两个参数表示block的横纵坐标,第三个参数表示block的起始命数。
loadLevel将每个关卡的数据封装成blocks集合。
下面是block.js
var Block = function(position) {
// position 是 [0, 0, 0] 格式
var p = position
var image = imageFromPath('block.png')
var o = {
image: image,
x: p[0],
y: p[1],
w: 50,
h: 20,
alive: true,
lives: p[2] || 1
}
var rectIntersects = function(a, b) {
// a in b
var o = a
if (b.y > o.y && b.y < o.y + o.image.height) {
if (b.x > o.x && b.x < o.x + o.image.width) {
return true
}
}
return false
}
o.kill = function() {
o.lives--
if (o.lives < 1)
o.alive = false
}
o.collide = function(b) {
return o.alive && (rectIntersects(o, b) || rectIntersects(b, o))
}
return o
}
Block新增alive和lives属性,用以判断block的死亡。
优化了检测碰撞函数,可惜还是有bug(QAQ)。
kill函数判断lives的值决定block的死亡。
下面是新的html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>game 2</title>
</head>
<style>
canvas {
border: 1px solid black
}
</style>
<script src="guaGame.js"></script>
<script src="paddle.js"></script>
<script src="block.js"></script>
<script src="ball.js"></script>
<script src="utils.js"></script>
<script src="level.js"></script>
<body>
<canvas id="id-canvas" width="1000" height="900"></canvas>
<script>
var enableDebugMode = function(enable) {
if (!enable) {
return
}
window.addEventListener('keydown', function(event){
var k = event.key
if (k == 'p') {
paused = !paused
}
else if ('1234567'.includes(k)) {
blocks = loadLevel(Number(k))
}
})
}
var __main = function() {
paused = false
var game = GuaGame()
var paddle = Paddle()
var ball = Ball()
blocks = loadLevel(1)
enableDebugMode(true)
// events
game.registerAction('ArrowLeft', function(){
paddle.moveLeft()
})
game.registerAction('ArrowRight', function(){
paddle.moveRight()
})
game.registerAction('f', function(){
ball.fire()
})
game.update = function() {
if (paused) {
return
}
ball.move()
// 判断相撞
if (paddle.collide(ball)) {
// ball.反弹()
ball.bounce()
}
for (var i=0; i<blocks.length; i++) {
var block = blocks[i]
// 判断 ball 和 block 相撞
if (block.collide(ball)) {
block.kill()
// ball.反弹()
ball.bounce()
}
}
}
game.draw = function() {
// draw
game.drawImage(paddle)
game.drawImage(ball)
for (var i=0; i<blocks.length; i++) {
var block = blocks[i]
if (block.alive)
game.drawImage(block)
}
}
}
__main()
</script>
</body>
</html>
enableDebugMode模块新增两个功能,按“p”键使小球运动停止(主要是为了观察碰撞临界处的bug);按数组键选择不同的关卡(关卡的数据还没有完善)。
update函数中新增block的碰撞检测。