简体   繁体   English

在JavaScript中加载要在画布上绘制的图像

[英]Loading images for drawing on canvas in javascript

I have been trying to teach my 11 year old son to program in javascript, but being a java programmer myself, I'm not too sure to get the below to work. 我一直在尝试教我11岁的儿子用JavaScript进行编程,但是我自己是一名Java程序员,因此我不太确定如何完成以下工作。 The code, as written, displays a simple block in the drawRocket method, but my son wants it to display an image of a rocket instead. 所编写的代码在drawRocket方法中显示了一个简单的块,但是我儿子希望它显示火箭的图像。 However, if I comment in the drawImage method and comment out the drawRect method, then it doesn't display the rocket image. 但是,如果我在drawImage方法中添加注释并在drawRect方法中添加注释,则它不会显示火箭图像。

I understand, from reading the various threads on this topic on stackoverflow, that the issue is that javascript doesn't load images synchronously, and therefore I need to write the code with an onload listener on the rocket image object. 通过阅读有关stackoverflow上该主题的各个线程,我了解到问题在于javascript无法同步加载图像,因此我需要在火箭图像对象上使用onload侦听器编写代码。 However, I tried replacing the main() call with this code (and removing the two lines from the main method): 但是,我尝试用此代码替换main()调用(并从main方法中删除两行):

var rocket = new Image();
rocket.onload = main(rocket);
rocket.src = "rocket.jpg";

And it still didn't work. 而且仍然没有用。 I tried various other things, but nothing seems to work for me. 我尝试了其他各种方法,但似乎无济于事。 The rocket.jpg image is fine. rocket.jpg图片很好。

No doubt the answer is very simple, but I'm still struggling after 2 hours. 毫无疑问,答案很简单,但是2小时后我仍然在挣扎。 Any help please? 有什么帮助吗?

Thanks! 谢谢!

C. C。

PS Coal powered rockets are the next big thing ;) PS煤动力火箭是下一件大事;)

<head>
<script>

function drawSky(ctx) {
   ctx.fillStyle = "rgb(0,0,50)";
   ctx.fillRect(0, 0, 300, 300);
}

function drawGround(ctx) {
   ctx.fillStyle = "rgb(150,150,127)";
   ctx.fillRect(0, 295, 300, 5);
}

function drawRocket(ctx, rocket, height) {
   var drawHeight = 250 - height*2;
   if (drawHeight > 245)
      drawHeight = 245;

//   ctx.drawImage(rocket, 140, drawHeight, 20, 50);

   ctx.fillStyle = "rgb(255,0,0)";
   ctx.fillRect(140, drawHeight, 20, 50);
}

function drawExplosion(ctx, size) {
   ctx.fillStyle = "rgb(255,102,0)";
   ctx.beginPath();
   ctx.arc(150, 295, size, 180*Math.PI/180, 360*Math.PI/180);
   ctx.fill();
}

function drawCoalBar(ctx, coal) {

   ctx.fillStyle = "rgb(255,255,255)";
   ctx.fillText("COAL", 10, 25);   


   if (coal <= 15)
      ctx.fillStyle = "rgb(255,0,0)";  
   else if (coal <= 30)
      ctx.fillStyle = "rgb(255,125,0)";
   else
      ctx.fillStyle = "rgb(255,225,0)";


   ctx.fillRect(45, 15, coal*4, 10);   
   ctx.strokeStyle = "rgb(255,255,255)";
   ctx.strokeRect(45, 15, 60*4, 10);   

}

function main() {

var canvas = document.getElementById('gameview');
var ctx = canvas.getContext('2d');

var rocket = new Image();
rocket.src = "rocket.jpg";

drawSky(ctx);
drawGround(ctx);

var name = prompt("What is your name?");
document.write("<p>Good luck Captain " + name + "!</p>");

var height = 100;
var speed = 0;
var coal = 60;
var burn = 0;
var gravity = 5;
var maxSpeedForSafeLanding = 8;

document.write("<p>");
document.write("The maximum speed for a safe landing is " + maxSpeedForSafeLanding + "m/s.");
document.write("<p>");

while (height > 0)
{
   document.write("Burn: " + burn + "kg");
   document.write(" - Height: " + height + "m");
   document.write(" - Speed: " + speed + "m/s");
   document.write(" - Coal: " + coal + "kg");
   document.write("<br />"); 

   drawSky(ctx);
   drawGround(ctx);
   drawRocket(ctx, rocket, height);
   drawCoalBar(ctx, coal);   


   // Ask for ammount of coal to burn
   var burn = prompt("How much coal do you want to burn?");
   burn = Number(burn);

   if (burn > coal)
     burn = coal;

   if (-burn > coal)
     burn = -coal;


   if (burn >= 0)
     coal = coal - burn;
   else
     coal = coal + burn;

   speed = speed + gravity - burn;

   height = height - speed; 
}

document.write("</p>");

drawSky(ctx);
drawGround(ctx);


if (speed <= maxSpeedForSafeLanding) {
   drawRocket(ctx, 0);

   document.write("<p>Congratulations Captain " + name + ".  You landed safely with a speed of " + speed + "m/s and you still have " + coal + "kg of coal left.</p>");
} else {
   drawExplosion(ctx, 25+coal*2+speed*2);

   document.write("<p>Rest In Peace Captain " + name + ".  You crashed with a speed of " + speed + "m/s and you still had " + coal + "kg of coal left.You will be burried on the planet you crashed on.</p>");
}

drawCoalBar(ctx, coal);
}
</script>
</head>

<body>

<h1>Rocket Lander Game</h1>

<canvas id="gameview" width="300" height="300"></canvas>

<script>
main();
</script>

</body>

Try this: 尝试这个:

var rocket = new Image();
rocket.onload = function(){ main(rocket) };
rocket.src = "rocket.jpg";

What is happening is that you are invoking the function main() and the result of main is given to the onload instead. 发生的情况是您正在调用函数main() main结果改为提供给onload

You can simply write it as this to give a reference to main instead:: 您可以这样简单地编写它,以提供对main引用

rocket.onload = main;  //main will be invoked when image is loaded

or 要么

rocket.onload = function(e) { main() };

In the latter we give an anonymous function as argument and when that is called main() gets invoked inside of it. 在后者中,我们提供了一个匿名函数作为参数,当它被调用时, main()在其内部被调用。 This is useful if you want to do other things with the image before calling main() . 如果要在调用main()之前对图像进行其他操作,这很有用。

As rocket is globally available in this case there is no need to give it as argument to main but if you need to call main with other images this is of course a good way of doing it. 因为在这种情况下, rocket是全球可用的,所以不需要将它作为main参数,但是如果您需要使用其他图像调用main ,那么这当然是一个很好的方法。 But you can then add a argument variable to main: 但是您可以在main中添加一个参数变量:

function main(image) {

    /// ctx.drawImage(image, 0, 0); etc..
}

Also consider to implement an onerror callback handler for image in case something goes wrong duing image loading. 还考虑为图像实现onerror回调处理程序,以防在图像加载期间出现问题。

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

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