如何让图像显示在 html canvas 中的背景之上?
How do I make an image appear above the background in html canvas?
我正在尝试制作一个非常简单的迷你游戏,角色可以通过按键移动。多个障碍物从右侧向您袭来,您必须避开它们。
问题是 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;
}
基于 的评论:
you need to be careful about the order in which things are drawn!
我在你的代码中看到的问题是 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()
我减少了很多你的代码以获得一个工作片段,当 post 提出问题时你应该这样做,这有助于你在 90% 的时间里专注于错误,你会在你之前修复它post 一个问题,也有助于其他人调试您的代码。
如果你认真使用游戏引擎,有很多好的开源引擎:
https://github.com/collections/javascript-game-engines
我正在尝试制作一个非常简单的迷你游戏,角色可以通过按键移动。多个障碍物从右侧向您袭来,您必须避开它们。
问题是 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;
}
基于
you need to be careful about the order in which things are drawn!
我在你的代码中看到的问题是 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()
我减少了很多你的代码以获得一个工作片段,当 post 提出问题时你应该这样做,这有助于你在 90% 的时间里专注于错误,你会在你之前修复它post 一个问题,也有助于其他人调试您的代码。
如果你认真使用游戏引擎,有很多好的开源引擎: https://github.com/collections/javascript-game-engines