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

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

自定义log &显示分数:

//let log = console.log.bind(console);
let e = sel => document.querySelector(sel);

let log = function(s) {
    e("#id-text-log").value += s + '\n';
};

let imgFromPath = function(path) {
    let img = new Image(path);
    img.src = path;
    return img;
};
utils.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 + 1; // 防止为0
                });
            };
            
            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.score++;
                        }
                    }
                };
                
                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.context.font = "48px serif";
                    game.context.fillText("你的分数:" + game.score, 30, 100);
                };        
                
                game.begin();
            };            
            
            __main();
        </script>
    </body>
</html>
index.html

图片加载相关的问题,例如游戏里有3个砖块,那么brick.png就会被反复加载3次,这样很浪费时间,我想到的解决方法是用map保存加载过的图片,在拿图片的时候进行一次判断,加载过就直接返回,没加载过才加载,这样就可以确保每张图片只会被加载一次,并且实现上只需要重写imgFromPath方法而不用改其它地方:

let imgMap = new Map();
// let count = 0;
let imgFromPath = function(path) {
    let img = imgMap.get(path);
    if (img != undefined) {
        return img;
    }
    img = new Image();
    img.src = path;
//    img.onload = function() {
//        ++count;
//        log(count, path);
//    }; 用来调试的时候观察实际加载的次数
    
    imgMap.set(path, img);
    return img;
};

在游戏开始前加载所有图片:

let log = console.log.bind(console);

let imgPaths = {
    ball: "img/ball.png",
    brick: "img/brick.png",
    paddle: "img/paddle.png",
};

let imgMap = new Map();
let imgFromPath = function(path) {
    let img = imgMap.get(path);
    if (img != undefined) {
        return img;
    }
    img = new Image();
    img.src = path;
    imgMap.set(path, img);
    return img;
};

let loadImgs = function() {
    let imgLoads = 0; // 已经加载完毕的图片数量
    let imgNames = Object.keys(imgPaths);
    return new Promise(resolve => {
        for (let name of imgNames) {
            let img = imgFromPath(imgPaths[name]);
            img.onload = function() {
                log('imgLoads=' + imgLoads);
                if (++imgLoads >= imgNames.length) {
                    resolve();
                }
            };
        }
    });
};
utils.js
    loadImgs().then(() => {
        game.begin();        
    });
main.js

 

 

posted @ 2018-10-26 22:06  xkfx  阅读(276)  评论(0编辑  收藏  举报