• 【笔记】直播编程写游戏


    饮水思源: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 + '
    ';
    };
    
    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

  • 相关阅读:
    spring bean的生命周期
    02-MySQL主要配置文件
    01-MySQL Linux安装
    spring自动装配
    JVMGC+Spring Boot生产部署和调参优化
    java面试-生产环境出现CPU占用过高,谈谈你的分析思路和定位
    java面试-G1垃圾收集器
    java面试-垃圾回收器谈谈你的理解
    java面试-谈谈你对OOM的理解
    RPC介绍以及编程
  • 原文地址:https://www.cnblogs.com/xkxf/p/9836595.html
Copyright © 2020-2023  润新知