简体   繁体   English

如何使图像出现在 html canvas 的背景上方?

[英]How do I make an image appear above the background in html canvas?

I'm trying to make a very simple mini-game where a character moves with keys.我正在尝试制作一个非常简单的迷你游戏,其中角色用按键移动。 Multiple obstacles come at you from the right and you have to avoid them.多个障碍物从右侧向您袭来,您必须避开它们。

The problem is that the obstacles in the myObstacles array appear behind the background image.问题是 myObstacles 数组中的障碍物出现在背景图像的后面。 Why is it doing that and is there an easy fix that I'm missing?为什么要这样做,我是否缺少一个简单的解决方法?

Let me know if anything is unclear or I left out information.如果有任何不清楚或我遗漏了信息,请告诉我。 First time posting a question on here:)第一次在这里发问题:)

var myGamePiece;
var myObstacles = [];
var myBackground;

function startGame() { 
    myGamePiece = new component(50, 50, "still.png", 10, 120, "image");
    myBackground = new component(1600, 400, "gamebkg.png", 0, 0, "background");
    myGameArea.start();
}


//board
var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 600;
        this.canvas.height = 600;
        this.context = this.canvas.getContext("2d");
        this.context.translate(0.5, 0.5);
        this.context.imageSmoothingQuality = "high";
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateGameArea, 20);
        //keys to move
        window.addEventListener('keydown', function (e) {
        myGameArea.key = e.keyCode;
        })
        window.addEventListener('keyup', function (e) {
        myGameArea.key = false;
        })
    },
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    stop : function() {
        clearInterval(this.interval);
    }
}



function component(width, height, color, x, y, type) {
    this.type = type;
    if (type == "image" || type == "background") {
        this.image = new Image();
        this.image.src = color;
    }
    this.width = width;
    this.height = height;
    this.speedX = 0;
    this.speedY = 0;    
    this.x = x;
    this.y = y;    
    this.update = function() {
        ctx = myGameArea.context;
        if (type == "image" || type == "background") {
            ctx.drawImage(this.image, 
                this.x, 
                this.y,
                this.width, this.height);
        if (type == "background") {
            ctx.drawImage(this.image, 
                this.x + this.width, 
                this.y,
                this.width, this.height);
        }
        } else {
            ctx.fillStyle = color;
            ctx.fillRect(this.x, this.y, this.width, this.height);
        }
    }
    this.newPos = function() {
        this.x += this.speedX;
        this.y += this.speedY;
        if (this.type == "background") {
            if (this.x == -(this.width)) {
                this.x = 0;
            }
        }
    }    
    this.crashWith = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
    if ((mybottom < othertop) ||
        (mytop > otherbottom) ||
        (myright < otherleft) ||
        (myleft > otherright)) {
        crash = false;
    }
    return crash;
  }
}

function updateGameArea() {
   var x, y;
   for (i = 0; i < myObstacles.length; i += 1) {
        if (myGamePiece.crashWith(myObstacles[i])) {
            myGameArea.stop();
            return;
        }
    }

    myGameArea.clear();
    myGameArea.frameNo += 1;

    if (myGameArea.frameNo == 1 || everyinterval(150)) {
        x = myGameArea.canvas.width;
        y = myGameArea.canvas.height - 500;
        myObstacles.push(new component(30, 30, "feesh.png", x, y, "image"))
    }

    for (i = 0; i < myObstacles.length; i += 1) {
        myObstacles[i].x += -1;
        myObstacles[i].update();
    }

    myGamePiece.speedX = 0;
    myGamePiece.speedY = 0;
        if (myGameArea.key && myGameArea.key == 37) {myGamePiece.speedX = -5; }
        if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 5; }
        if (myGameArea.key && myGameArea.key == 38) {myGamePiece.speedY = -5; }
        if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 5; }
    myBackground.speedX = -1;
    myBackground.newPos();    
    myBackground.update();
    
    myGamePiece.newPos();    
    myGamePiece.update();
  
}

function everyinterval(n) {
    if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
    return false;
}

Building on the comment from @AHaworth :基于@AHaworth的评论:

you need to be careful about the order in which things are drawn!您需要注意绘制事物的顺序!

The problem I see in your code is on function updateGameArea() the background should be at the top of the stuff you do, see my fix below.我在您的代码中看到的问题是在function updateGameArea()上,背景应该在您所做的事情的顶部,请参阅下面的修复。

 var myGamePiece; var myObstacles = []; var myBackground; function startGame() { myGamePiece = new component(50, 50, "red", 10, 60, "rect"); myBackground = new component(1600, 400, "blue", 0, 0, "rect"); myGameArea.start(); } function updateGameArea() { myGameArea.clear(); myGameArea.frameNo += 1; myBackground.speedX = -1; myBackground.newPos(); myBackground.update(); if (myGameArea.frameNo == 1 || everyinterval(150)) { myObstacles.push(new component(30, 30, "pink", myGameArea.canvas.width, 50, "rect")) } for (i = 0; i < myObstacles.length; i += 1) { myObstacles[i].x += -0.5; myObstacles[i].update(); } myGamePiece.speedX = 0; myGamePiece.speedY = 0; myGamePiece.newPos(); myGamePiece.update(); } //board var myGameArea = { canvas: document.createElement("canvas"), start: function() { this.canvas.width = 400; this.canvas.height = 150; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.frameNo = 0; this.interval = setInterval(updateGameArea, 20); }, clear: function() { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } } function component(width, height, color, x, y, type) { this.width = width; this.height = height; this.speedX = 0; this.speedY = 0; this.x = x; this.y = y; this.update = function() { ctx = myGameArea.context; ctx.fillStyle = color; ctx.fillRect(this.x, this.y, this.width, this.height); } this.newPos = function() { this.x += this.speedX; this.y += this.speedY; } } function everyinterval(n) { return ((myGameArea.frameNo / n) % 1 == 0) } startGame()

I reduced a lot of your code to get a working snippet, you should do the same when posting question, that helps you focus on the error 90% of the time you will fix it before you post a question and also helps other debug your code.我减少了很多代码以获得工作片段,您在发布问题时也应该这样做,这可以帮助您在 90% 的时间内专注于错误,然后再发布问题并帮助其他人调试您的代码.

If you are serious about it use a game engine, there a lot of good Open Source ones: https://github.com/collections/javascript-game-engines如果你认真使用游戏引擎,有很多好的开源引擎: https://github.com/collections/javascript-game-engines

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM