【笔记】直播编程写游戏 - 2

饮水思源:https://www.bilibili.com/video/av12168808

添加砖块(先写一个砖块 再弄成n个)&通过暂停与减速来debug:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            canvas {
                border: 1px black solid;
            }
        </style>
    </head>
    <body>
        <canvas id="id-canvas" width="400" height="300"></canvas>
        <script>    
            let makeGuaGame = function(fps) {
                let g = {
                    actions: {},
                    keydowns: {},
                };
                g.canvas = document.querySelector("#id-canvas");
                g.context = g.canvas.getContext('2d');
                
                g.registerAction = function(key, callback) {
                    g.actions[key] = callback;
                };
                
                g.drawImage = function(guaImage) {
                    this.context.drawImage(guaImage.img, guaImage.x, guaImage.y);    
                }
                
                window.addEventListener("keydown", event => {
                    g.keydowns[event.key] = true;
                });
    
                window.addEventListener("keyup", event => {
                    g.keydowns[event.key] = false;
                });                
 
                setInterval(function() {
                    // events
                    let keys = Object.keys(g.keydowns);
                    for (let i = 0; i != keys.length; ++i) {
                        let k = keys[i];
                        if (g.keydowns[k]) {
                            g.actions[k]();
                        }
                    }
                    // update 
                    g.update();
                    // clear
                    g.context.clearRect(0, 0, g.canvas.width, g.canvas.height);
                    // draw
                    g.draw();            
                }, 1000/fps); 
                
                return g;
            };

            let imgFromPath = function(path) {
                let img = new Image(path);
                img.src = path;
                return img;
            };
            
            let makePaddle = function() {
                let img = imgFromPath('img/paddle.png');
                let o = {
                    img: img,
                    x: 200,
                    y: 250,
                    speed: 5,
                };
                o.moveLeft = function() {
                    this.x -= this.speed;
                    if (this.x < 0) {
                        this.x = 0;
                    }
                };
                o.moveRight = function() {
                    this.x += this.speed;
                    if (this.x > 400 - this.img.naturalWidth) {
                        this.x = 400 - this.img.naturalWidth;
                    }
                };
                o.collide = function(guaImg) {
                    if (Math.abs(o.x - guaImg.x) < o.img.naturalWidth/2 + guaImg.img.naturalWidth/2 
                      && Math.abs(o.y - guaImg.y) < o.img.naturalHeight/2 + guaImg.img.naturalHeight/2 
                    ) {
                      return true;
                    }
                    return false;
                };
                
                return o;
            };
            
            let makeBall = function() {
                let img = imgFromPath('img/ball.png');
                let o = {
                    img: img,
                    x: 200, 
                    y: 250,
                    speedX: 7,
                    speedY: -7,
                    fired: false,
                };
                o.fire = function() {
                    this.fired = true;
                }
                
                o.move = function() {
                    if (this.fired) {    
                        if (this.x > 400 || this.x < 0) {
                            this.speedX *= -1;
                        } else if (this.y > 300 || this.y < 0) {
                            this.speedY *= -1;
                        }    
                        this.x += this.speedX;
                        this.y += this.speedY;                        
                    }
                };
                o.反弹 = function() {
                    this.speedY *= -1;
                }
                
                return o;                
            };
            
            let makeBrick = function() {
                let img = imgFromPath('img/brick.png');
                let o = {
                    img: img,
                    x: 50, 
                    y: 50,
                    alive: true,
                };        
                o.kill = function() {
                    this.alive = false;
                }
                o.collide = function(guaImg) {
                    if (!this.alive) return false;
                    if (Math.abs(o.x - guaImg.x) < o.img.naturalWidth/2 + guaImg.img.naturalWidth/2 
                      && Math.abs(o.y - guaImg.y) < o.img.naturalHeight/2 + guaImg.img.naturalHeight/2 
                    ) {
                      return true;
                    }
                    return false;
                };
                
                return o;
            };
            
            let __main = function() {
                let game = makeGuaGame(fps=30);
                
                let paddle = makePaddle();
                
                let ball = makeBall();
                
                let bricks = [];
                for (let i = 0; i != 3; ++i) {
                    let b = makeBrick();
                    b.x = i * 150;
                    bricks.push(b);
                }
                
                game.registerAction('a', function() {
                    paddle.moveLeft();
                });
                
                game.registerAction('d', function() {
                    paddle.moveRight();    
                });

                game.registerAction('f', function() {
                    ball.fire();    
                });
                
                let pause = false;
                window.addEventListener("keydown", event => {
                    if (event.key == 'p') {
                        pause = !pause;
                    }
                });
                game.update = function() {    
                    if (pause) { // 暂停的移动
                        return;
                    }
                    
                    ball.move();
                    if (paddle.collide(ball)) {
                        ball.反弹();
                    }
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].collide(ball)) {
                            bricks[i].kill();
                            ball.反弹();
                        }
                    }
                };
                
                game.draw = function() {
                    game.drawImage(paddle);    
                    game.drawImage(ball);    
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].alive) {
                            game.drawImage(bricks[i]);    
                        }    
                    }
                };            
            };            
            
            __main();
        </script>
    </body>
</html>
View Code

将各部分代码拆分为独立文件 &添加关卡以及debug模式:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            canvas {
                border: 1px black solid;
            }
        </style>
        <script src="js/utils.js"></script>
        <script src="js/guagame.js"></script>
        <script src="js/paddle.js"></script>
        <script src="js/ball.js"></script>
        <script src="js/brick.js"></script>
        <script src="js/levels.js"></script>
    </head>
    
    <body>
        <canvas id="id-canvas" width="400" height="300"></canvas>
        <script>    
            
            let pause = false;                    
            let enableDebugMode = function(enable) {
                if (!enable) {
                    return;
                }
                window.addEventListener("keydown", event => {
                    if (event.key == 'p') {
                        pause = !pause;
                    }
                });                    
            };
            
            let __main = function() {
                enableDebugMode(false);
                
                let game = makeGuaGame(fps=40);                
                let paddle = makePaddle();                
                let ball = makeBall();                
                let bricks = loadLevel(0);
                
                game.registerAction('a', function() {
                    paddle.moveLeft();
                });            
                game.registerAction('d', function() {
                    paddle.moveRight();    
                });
                game.registerAction('f', function() {
                    ball.fire();    
                });
                        
                game.update = function() {    
                    if (pause) { // 暂停球的移动
                        return;
                    }                    
                    ball.move();
                    if (paddle.collide(ball)) {
                        ball.反弹();
                    }
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].collide(ball)) {
                            bricks[i].kill();
                            ball.反弹();
                        }
                    }
                };
                
                game.draw = function() {
                    game.drawImage(paddle);    
                    game.drawImage(ball);    
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].alive) {
                            game.drawImage(bricks[i]);    
                        }    
                    }
                };            
            };            
            
            __main();
        </script>
    </body>
</html>
View Code

砖块生命值 &动态调fps :

let makeBrick = function(x, y, HP=1) {
    // x, y 是砖块的坐标
    let img = imgFromPath('img/brick.png');
    let o = {
        img: img,
        x: x,
        y: y,
        HP: HP,
        alive: true,
    };
    o.kill = function() {
        this.alive = false;
        // 根据生命值改变图片?先初始化一个img数组
    };
    o.hit = function() {
        console.log(this.HP);
        this.HP--;
        if (this.HP == 0) {
            this.kill();
        }
    };
    o.collide = function(guaImg) {
        if(!this.alive) return false;
        if(Math.abs(o.x - guaImg.x) < o.img.naturalWidth / 2 + guaImg.img.naturalWidth / 2 &&
            Math.abs(o.y - guaImg.y) < o.img.naturalHeight / 2 + guaImg.img.naturalHeight / 2
        ) {
            return true;
        }
        return false;
    };

    return o;
};
brick.js
let levels = [
    [
        [100, 50],
    ],
    [
        [0, 50],
        [150, 50, 50],
        [300, 50],
    ],
];


let loadLevel = function(n) {
    // n表示第几关,该函数返回一个砖块数组
    let level = levels[n];
    
    let bricks = [];
    for (let i = 0; i != level.length; ++i) {
        let param = level[i];
        let b = makeBrick(param[0], param[1], param[2] || 1);
        bricks.push(b);
    }    
    
    return bricks;
};
levels.js
let makeGuaGame = function() {
    let g = {
        actions: {},
        keydowns: {},
        fps: 40,
    };
    g.canvas = document.querySelector("#id-canvas");
    g.context = g.canvas.getContext('2d');

    g.registerAction = function(key, callback) {
        g.actions[key] = callback;
    };

    g.drawImage = function(guaImage) {
        this.context.drawImage(guaImage.img, guaImage.x, guaImage.y);
    };

    window.addEventListener("keydown", event => {
        g.keydowns[event.key] = true;
    });

    window.addEventListener("keyup", event => {
        g.keydowns[event.key] = false;
    });

    let repaintInfinitely = function() { 
        // events
        let keys = Object.keys(g.keydowns);
        for(let i = 0; i != keys.length; ++i) {
            let k = keys[i];
            if(g.keydowns[k] && g.actions[k] != null) {
                g.actions[k]();
            }
        }
        // update 
        g.update();
        // clear
        g.context.clearRect(0, 0, g.canvas.width, g.canvas.height);
        // draw
        g.draw();
        setTimeout(function() {
            repaintInfinitely(); // 递归调用setTimeout
        }, 1000 / g.fps);    
    };
    
    g.begin = function() { // 在一切就绪的时候调用(update和draw定义后)
        repaintInfinitely();    
    };

    return g;
};
guagame.js
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            canvas {
                border: 1px black solid;
            }
        </style>
        <script src="js/utils.js"></script>
        <script src="js/guagame.js"></script>
        <script src="js/paddle.js"></script>
        <script src="js/ball.js"></script>
        <script src="js/brick.js"></script>
        <script src="js/levels.js"></script>
    </head>
    
    <body>
        <canvas id="id-canvas" width="400" height="300"></canvas>
        <p>fps:<input id="id-input-speed" type="range" /></p>
        <script>    
            let pause = false;
            let enableDebugMode = function(game, enable) {
                if (!enable) {
                    return;
                }
                window.addEventListener("keydown", event => {
                    if (event.key == 'p') {
                        pause = !pause;
                    }
                });
                document.querySelector("#id-input-speed").addEventListener("input", event => {
                    let newFps = Number(event.target.value);
                    game.fps = newFps;
                });
            };
            
            let __main = function() {                
                let game = makeGuaGame();
                enableDebugMode(game, true);
                
                let paddle = makePaddle();                
                let ball = makeBall();                
                let bricks = loadLevel(1);
                
                game.registerAction('a', function() {
                    paddle.moveLeft();
                });            
                game.registerAction('d', function() {
                    paddle.moveRight();    
                });
                game.registerAction('f', function() {
                    ball.fire();    
                });
                        
                game.update = function() {    
                    if (pause) { // 暂停球的移动
                        return;
                    }    
                    
                    ball.move();
                    if (paddle.collide(ball)) {
                        ball.反弹();
                    }
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].collide(ball)) {
                            bricks[i].hit();
                            ball.反弹();
                        }
                    }
                };
                
                game.draw = function() {
                    game.drawImage(paddle);    
                    game.drawImage(ball);    
                    for (let i = 0; i != bricks.length; ++i) {
                        if (bricks[i].alive) {
                            game.drawImage(bricks[i]);    
                        }    
                    }
                };        
                
                game.begin();
            };            
            
            __main();
        </script>
    </body>
</html>
index.html

 

 截屏留念,这是一个血很厚的砖块。。

猜你喜欢

转载自www.cnblogs.com/xkxf/p/9832699.html