首页 > 解决方案 > 如何使图像出现在 html 画布的背景上方?

问题描述

我正在尝试制作一个非常简单的迷你游戏,其中角色用按键移动。多个障碍物从右侧向您袭来,您必须避开它们。

问题是 myObstacles 数组中的障碍物出现在背景图像的后面。为什么要这样做,我是否缺少一个简单的解决方法?

如果有任何不清楚或我遗漏了信息,请告诉我。第一次在这里发问题:)

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;
}

标签: htmlcsscanvashtml5-canvas

解决方案


基于@AHaworth的评论:

您需要注意绘制事物的顺序!

我在您的代码中看到的问题是在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()

我减少了你的很多代码以获得一个工作片段,你应该在发布问题时做同样的事情,这可以帮助你在 90% 的时间里专注于错误,然后你会在发布问题之前修复它,还可以帮助其他人调试你的代码.

如果你认真使用游戏引擎,有很多好的开源引擎: https ://github.com/collections/javascript-game-engines


推荐阅读