Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

javascript - Images onload in one function

I'm trying to learn JavaScript, making my first game. How I can make all images onload in one function and later draw it in the canvas making my code shorter?

How can I put a lot of images in an array and later us it in a function.

This is my third day of learning JavaScript.

Thanks in advance.

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

//load images

var bird = new Image();
var bg = new Image();
var fg = new Image();
var pipeNorth = new Image();
var pipeSouth = new Image();

//images directions 
bg.src = "assets/bg.png";
bird.src = "assets/bird.png";
fg.src = "assets/fg.png";
pipeNorth.src = "assets/pipeNorth.png";
pipeSouth.src = "assets/pipeSouth.png";

var heightnum = 80;
var myHeight = pipeSouth.height+heightnum;
var bX = 10;
var bY = 150;
var gravity = 0.5;

// Key Control :D
 document.addEventListener("keydown",moveUP)
function moveUP(){
bY -= 20;
}
//pipe coordinates

var pipe = [];

pipe[0] = {
  x : cvs.width,
  y : 0
}
//draw images 


//Background img
  bg.onload = function back(){
    ctx.drawImage(bg,0,0);

  }
  //pipe north
  pipeNorth.onload = function tubo(){

    for(var i = 0; i < pipe.length; i++){

    ctx.drawImage(pipeNorth,pipe[i].x,pipe[i].y);
    pipe[i].x--;
    }
  }

  pipeSouth.onload = function tuba(){
    ctx.drawImage(pipeSouth,pipe[i].x,pipe[i].y+myHeight);

  }



  bird.onload = function pajaro(){
    ctx.drawImage(bird,bX,bY);
    bY += gravity;

    requestAnimationFrame(pajaro);  
  } 


  fg.onload = function flor(){
    ctx.drawImage(fg,0,cvs.height - fg.height);

  }




moveUP();
   back();
   tuba();
   pajaro();
   flor();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This can be done with Promise.all. We'll make a new promise for each image we want to load, resolving when onload is called. Once Promise.all resolves, we can call our initialize function and continue on with the rest of our logic. This avoids race conditions where the main game loop's requestAnimationFrame is called from bird.onload, but it's possible that pipe entities and so forth haven't loaded yet.

Here's a minimal, complete example:

const initialize = images => {

  // images are loaded here and we can go about our business
  
  const canvas = document.createElement("canvas");
  document.body.appendChild(canvas);
  canvas.width = 400;
  canvas.height = 200;
  const ctx = canvas.getContext("2d");

  Object.values(images).forEach((e, i) =>
    ctx.drawImage(e, i * 100, 0)
  );
};

const imageUrls = [
  "http://placekitten.com/90/100",
  "http://placekitten.com/90/130",
  "http://placekitten.com/90/160",      
  "http://placekitten.com/90/190",
];

Promise.all(imageUrls.map(e =>
  new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = reject;
    img.src = e;
  })
)).then(initialize);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...