2017-08-01 43 views
0

尝试在HTML画布游戏中的障碍物上绘制图像时,出现以下错误消息:Uncaught InvalidStateError:未能执行'drawimage 'CanvasRenderingContext2D':提供的HTMLImageElement处于'破碎'状态。错误消息在推送的画布对象上使用drawimage()时,未通过预加载帮助()

障碍物是看不见的,但如果玩家碰撞到应该在的位置,游戏仍会停止。游戏中的其他固定障碍物图像是可见的。我该怎么办?

我尝试上传图像在我的HTML作为preload()函数,但它仍然无法正常工作。关于类似情况的其他文章没有涉及这个相同的背景,也没有帮助我对编程颇为陌生的人。

下面是代码:

<!DOCTYPE html> 
<html> 
<head> 

<meta name="viewport" content="width=device-width, initial-scale=1.0"/> 
<link rel="stylesheet" type="text/css" href="stylesheet.css"> <link/> 

<script> 

function preloader() 

{ 

// counter 
var i = 0; 

// create object 
imageObj = new Image(); 

// set image list 
images = new Array(); 
images[0]="player.jpg" 
images[1]="player2.jpg" 
images[2]="obstacle.jpg" 
images[3]="obstacle2.jpg" 
images[3]="obstacle3.jpg" 

// start preloading 
for(i=0; i<=3; i++) 
{ 
     imageObj.src=images[i]; 
} 


} 

</script> 

</head> 
<body onload="startGame(), preloader()"> 

<h2> My Lost Game </h2> 

<p>Press the 'up', 'down', 'left' and 'right' keys on your keyboard to move. Avoid the obstacles and reach the goal.</p><br> 

<p></p> 

<script> 

var myObstacle = []; 


function startGame() { 
myGameArea.start(); 
myGameGoal = new component(75, 95, "player2.jpg", 710, 215, "image"); 
myGamePiece = new component(75, 95, "player.jpg", 10, 215, "image"); 

myObstacle2 = new component (110, 150, "obstacle2.jpg", 350, 0, "image"); 
myObstacle3 = new component (110, 150, "obstacle3.jpg", 530, 350, "image"); 

} 

var myGameArea = { 
canvas : document.createElement("canvas"), 
start : function() { 
this.canvas.width = 800; 
this.canvas.height = 500; 
this.context = this.canvas.getContext("2d"); 
document.body.insertBefore(this.canvas, document.body.childNodes[4]); 
this.frameNo = 0; 
this.interval = setInterval(updateGameArea, 20); 
window.addEventListener('keydown', function (e) { 
    myGameArea.keys = (myGameArea.keys || []); 
    myGameArea.keys[e.keyCode] = true; 
}) 
window.addEventListener('keyup', function (e) { 
    myGameArea.keys[e.keyCode] = 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") { 
this.image = new Image(); 
this.image.src = color; 
} 
this.width = width; 
this.height = height; 
this.x = x; 
this.y = y;  

this.update = function() { 
ctx = myGameArea.context; 
if (type == "image") { 
    ctx.drawImage(this.image, 
     this.x, 
     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;   
} 
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 < myObstacle.length; i += 1) { 
if (myGamePiece.crashWith(myObstacle[i])) { 
    myGameArea.stop(); 
    return; 
} 
} 
myGameArea.clear(); 
myGameArea.frameNo += 1; 
if (myGameArea.frameNo == 1 || everyinterval(150)) { 
x = 200; 
y = 300; 
myObstacle.push(new component(110, 150, "obstacle1.jpg", x, y, "image")); 
} 
for (i = 0; i < myObstacle.length; i += 1) { 
myObstacle[i].y += -1; 
myObstacle[i].update(); 
} 




myGameArea.clear(); 
myGamePiece.speedX = 0; 
myGamePiece.speedY = 0; 
if (myGameArea.keys && myGameArea.keys[37]) {myGamePiece.speedX = -3; } 
if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.speedX = 3; } 
if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speedY = -3; } 
if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speedY = 3; } 


myObstacle2.update(); 
myObstacle3.update(); 
myGameGoal.update(); 
myGamePiece.newPos(); 
myGamePiece.update(); 
} 

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

</script> 



</body> 
</html> 

回答

0

需要创建一个单独的图像对象的每个图像

下面负载图像的代码从图像的URL的阵列,并且在所述返回图像的阵列顺序相同的URL名称

var loading = 0; // number of images still loading 
function preloader(imageURLs){ 
    // function creates and loads an image 
    function createImage(url){ 
     loading += 1; // count up when loading images 
     const image = new Image; 
     image.src = url; 
     image.onload =() => loading -= 1; // count down when loaded 
     return image; 
    } 
    const images = imageURLs.map(createImage); 
    return images; 
}  
const imageList = preloader(["player.jpg", "player2.jpg", "obstacle3.jpg"]); 
// at this point loading greater than zero 

loading为0,你知道的所有图像都加载

因此,在渲染循环

function mainLoop(){ 

    if(loading === 0){ // all images have loaded 
     ctx.drawImage(imageList[0],0,0); // draw first image 
     ctx.drawImage(imageList[1],0,0); // draw second image 
     ctx.drawImage(imageList[2],0,0); // draw third image 
    } 

    requestAnimationFrame(mainLoop); 
} 
requestAnimationFrame(mainLoop); 

或者你可以把它调用一个函数时,所有加载的

var loading = 0; // number of images still loading 
function preloader(imageURLs, callback){ 
    // function creates and loads an image 
    function createImage(url, callback){ 
     loading += 1; // count up when loading images 
     const image = new Image; 
     image.src = url; 
     image.onload =() => { 
      loading -= 1; // count down when loaded 
      if(loading === 0){ // all done 
       callback(); // call callback 
      } 
     } 
     return image; 
    } 
    const images = imageURLs.map(createImage); 
    return images; 
}  
function start(){ // function to start main loop when images have loaded 
    requestAnimationFrame(mainLoop);  
} 
// second argument is the callback function that is called when all images have loaded 
const imageList = preloader(["player.jpg", "player2.jpg", "obstacle3.jpg"], start); 
function mainLoop(){ 
    ctx.drawImage(imageList[0],0,0); // draw first image 
    ctx.drawImage(imageList[1],0,0); // draw second image 
    ctx.drawImage(imageList[2],0,0); // draw third image 
    requestAnimationFrame(mainLoop); 
}