画布游戏,在哪里编写背景代码?

时间:2016-03-24 15:50:46

标签: javascript html5 canvas

问题

我一直在创造一个游戏,我已经到了一个阶段,我希望通过我创建的模型背景看到它的样子。

问题

在我的代码中,我应该将此代码放在当前不显示背景的位置。

https://stackoverflow.com/a/36203572/831138

我想在画布上使用此背景,尺寸是正确的。

what it currently looks like

守则

var game = create_game();
    game.init();

    function create_game() {
        debugger;
        var level = 1;
        var projectiles_per_level = 1;
        var min_speed_per_level = 1;
        var max_speed_per_level = 2;
        var last_projectile_time = 0;
        var next_projectile_time = 0;
        var width = 600;
        var height = 500;
        var delay = 1000;
        var item_width = 30;
        var item_height = 30;
        var total_projectiles = 0;
        var projectile_img = new Image();
        var projectile_w = 30;
        var projectile_h = 30;
        var player_img = new Image();
        var background_img = new Image();
        var c, ctx;

        var projectiles = [];
        var player = {
            x: 200,
            y: 400,
            score: 0
        };

        function init() {
            projectile_img.src = "projectile.png";
            player_img.src = "player.png";

            background_img.src = "background.png";
            background_img.onload = function(){
                context.drawImage(background_img, 0, 0);
                    }


            level = 1;
            total_projectiles = 0;
            projectiles = [];

            c = document.getElementById("c");
            ctx = c.getContext("2d");
            ctx.fillStyle = "#410b11";
            ctx.fillRect(0, 0, 500, 600);

            c.addEventListener("mousemove", function (e) {
                //moving over the canvas.
                var bounding_box = c.getBoundingClientRect();
                player.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - player_img.width / 2;
            }, false);

            setupProjectiles(); 
            requestAnimationFrame(tick);
        }

        function setupProjectiles() {
            var max_projectiles = level * projectiles_per_level;
            while (projectiles.length < max_projectiles) {
                initProjectile(projectiles.length);
            }
        }

        function initProjectile(index) {
            var max_speed = max_speed_per_level * level;
            var min_speed = min_speed_per_level * level;
            projectiles[index] = {
                x: Math.round(Math.random() * (width - 2 * projectile_w)) + projectile_w,
                y: -projectile_h,
                v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
                delay: Date.now() + Math.random() * delay
            }
            total_projectiles++;
        }

        function collision(projectile) {
            if (projectile.y + projectile_img.height < player.y + 20) {
                return false;
            }
            if (projectile.y > player.y + 74) {
                return false;
            }
            if (projectile.x + projectile_img.width < player.x + 20) {
                return false;
            }
            if (projectile.x > player.x + 177) {
                return false;
            }

            return true;
        }

        function maybeIncreaseDifficulty() {
            level = Math.max(1, Math.ceil(player.score / 10));
            setupProjectiles();
        }

        function tick() {
            var i;
            var projectile;
            var dateNow = Date.now();
            c.width = c.width;
            for (i = 0; i < projectiles.length; i++) {
                projectile = projectiles[i];
                if (dateNow > projectile.delay) {
                    projectile.y += projectile.v;
                    if (collision(projectile)) {
                        initProjectile(i);
                        player.score++;
                    } else if (projectile.y > height) {
                        initProjectile(i);
                    } else {
                        ctx.drawImage(projectile_img, projectile.x, projectile.y);
                    }
                }
            }

            ctx.font = "bold 24px sans-serif";
            ctx.fillStyle = "#410b11";
            ctx.fillText(player.score, c.width - 50, 50);
            ctx.fillText("Level: " + level, 20, 50);

            ctx.drawImage(player_img, player.x, player.y);
            maybeIncreaseDifficulty();
            requestAnimationFrame(tick);

            ctx.drawImage(background_img, 0, backgroundY);

        }

        return {
            init: init
        };
    }

2 个答案:

答案 0 :(得分:2)

你必须画画:

  1. 背景第一
  2. 玩家以后
  3. 等级/得分信息最后
  4. Background < Player < UI < You Looking

    绘图顺序是从后到上(painters algorithm

    另请注意,出于性能原因,如果您的背景永远不会改变,您可以将其绘制在另一个静态&#39;游戏画布下的画布。

    否则,背景将在播放器上方/上方绘制并隐藏它。

答案 1 :(得分:2)

正如评论中已经指出的那样,更确切地说:

首先,必须在每个动画帧中首先渲染背景图片。

然而,这张照片根本没有显示出来。这是因为使用了变量(backgroundY),它从未在某处声明过。

这实际上应该作为错误打印到控制台&#34; backgroundY&#34;没有定义。

每当图像对象的属性src设置为某个值时,它需要一些时间才能加载。因此,在许多情况下,有必要通过onload回调指示何时完成加载。

然而,在这种情况下,没有必要。勾选/动画循环函数将只绘制任何内容(空图像对象),直到它被加载。加载后,它将继续每帧绘制加载的图像。

如果背景非常重要,意思是应用程序应该只启动,当它在那里时,当然,只能从img.onload处理程序中启动整个游戏/动画。