原生js打砖块游戏(二)—— 增加障碍物

前言

    在原有的基础上(原生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的碰撞检测。


总结

    碰撞检测好难啊,我一定会回来的。。。。。




猜你喜欢

转载自blog.csdn.net/qq_40950957/article/details/80572474