Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在呈现JS画布之前加载图像_Javascript_Html_Canvas_Drawimage - Fatal编程技术网

Javascript 在呈现JS画布之前加载图像

Javascript 在呈现JS画布之前加载图像,javascript,html,canvas,drawimage,Javascript,Html,Canvas,Drawimage,我正在写一个简单的游戏来学习JS,我正在学习HTML5,所以我需要在画布上画东西 代码如下: let paddle = new Paddle(GAME_WIDTH,GAME_HEIGHT); new InputHandler(paddle); let lastTime = 0; const ball = new Image(); ball.src = 'assets/ball.png'; function gameLoop(timeStamp){ let dt = ti

我正在写一个简单的游戏来学习JS,我正在学习HTML5,所以我需要在画布上画东西

代码如下:

 let paddle = new Paddle(GAME_WIDTH,GAME_HEIGHT);

 new InputHandler(paddle);

 let lastTime = 0;

 const ball = new Image();
 ball.src = 'assets/ball.png';

 function gameLoop(timeStamp){
   let dt = timeStamp - lastTime;
   lastTime = timeStamp;

   ctx.clearRect(0,0,600,600);
   paddle.update(dt);
   paddle.draw(ctx);

   ball.onload = () => {
    ctx.drawImage(ball,20,20);
  }

  window.requestAnimationFrame(gameLoop);
 }

gameLoop();
截图:没有球

现在我注释掉
clearRect()

你好,鲍尔


画布底部还有一个桨,似乎不受
clearRect()
方法的影响。它很好用。我在这里遗漏了什么?

将图像的
onload
处理程序放在游戏循环中没有多大意义。这意味着游戏必须在图像的
onload
功能设置之前开始运行,从而导致相当混乱的情况

正确的顺序是在运行游戏循环之前设置
onload
处理程序,然后设置图像源,然后设置
wait
所有图像
onload
s触发。当您只有一张图像时,直接将主循环设置为
onload
非常容易,但是对于具有多个资源的游戏来说,这很快就会变得笨拙

下面是一个关于如何使用加载多个游戏资源的示例。很可能,您希望将加载的图像解压到更具描述性的对象中,而不是数组中,但这只是一个开始

const canvas=document.createElement(“canvas”);
document.body.appendChild(画布);
画布宽度=400;
canvas.height=250;
const ctx=canvas.getContext(“2d”);
常数资产=[
"http://placekitten.com/120/100",
"http://placekitten.com/120/120",
"http://placekitten.com/120/140",
];
const assetsload=assets.map(url=>
新承诺(解决=>{
const img=新图像();
img.onerror=e=>reject(`${url}未能加载`);
img.onload=e=>resolve(img);
img.src=url;
})
);
允诺
.全部(已加载资产)
。然后(图像=>{
(函数gameLoop(){
requestAnimationFrame(gameLoop);
clearRect(0,0,canvas.width,canvas.height);
图像。forEach((e,i)=>
ctx.drawImage(
E
i*120,//x
Math.sin(Date.now()*0.005)*20+40//y
)
);
})();
})
.catch(err=>console.error(err))

;“我在这里遗漏了什么?”至少一个
}
开始。另外,如果缩进是正确的,这将有助于阅读代码<代码>游戏循环
从未被调用。根据前两点,
ball.onload
如果确实在
gameLoop
内,可能永远不会开火,因为它是一个事件侦听器,只会开火一次;您最好使用
ball.onload=galeLoop@kaido我已经包含了其余的代码。谢谢你花时间来调查这件事。我会研究事件的听众这工作做得很好!我还没有完全做到这一点,但我开始掌握js事件的窍门。这可能会让人困惑是的,承诺和回访有一个学习曲线。坚持下去。