nats0128
nats0128

Reputation: 509

Html5 canvas how to generate multiple images

Im making a simple zombie game in html5 canvas and wanted to know how to create a zombie every x seconds in a random place? so far i have

var zombies = new Array();

function SummonZombies (){
    TotalZombies++;
    zombies[TotalZombies] = new Image();
    zombies[TotalZombies].src = 'images/monster.png';
    ctx.drawImage(zombies[TotalZombies], zombie_x, zombie_y);
}

Only one zombie is being created with this? how would i get it to generate more.

Upvotes: 0

Views: 412

Answers (3)

GameAlchemist
GameAlchemist

Reputation: 19294

You must separate a Zombi from your zombies :
create a class that will describe what a Zombi is, and only after you will define a collection of such lovely guys and girls :

 // This Class defines what a Zombi is.
 function Zombi(x,y) {
     this.x = x;
     this.y = y;
 }

 var ZombiImage = new Image();
 ZombiImage.src = "images/monster.png";

 // image of a zombi is shared amongst all zombies, so it is
 // defined on the prototype
 Zombi.prototype.image = ZombiImage;

 // draw the zombi on provided context
 Zombi.prototype.draw = function(ctx) {
      ctx.drawImage(this.image, this.x, this.y);
 } 

Now for the collection :

// This class defines a collection of Zombies.
function Zombies() {
     this.zombies = [];
}

// summons a zombi at a random place. returns the summoned zombi.
myZombies.prototype.summon() {
   var randX = Math.random()*100;
   var randY = Math.random()*100;
   return this.summonAt(randX, randY);
}

// summons a zombi at x,y. returns the summoned zombi.
myZombies.prototype.summonAt = function (x,y) {
   var newZombi = new Zombi(x,y);  
   this.zombies.push();
   return newZombi;
}

// draws all zombies on provided context.
myZombies.prototype.drawAll = function (ctx) {
    var i=0;
    var __zombies = this.zombies;
    for (;i<__zombies.length; i++) {
        __zombies[i].draw(ctx);
    }
}

// collection of all zombies for your game.
var zombies = new Zombies();

// here you can call zombies.summon(); or zombies.drawAll();
// and even zombies.summonAt(x,y);

In fact the code above is simplified : you must handle the onload event of the image to start the game only after the image was loaded.
But you should get the idea : separate the issues (handle ONE zombi vs a collection of zombies) will get you faster to your goal.
With this -simple- design, you'll be able to easily add-up behaviour to your zombies.

Just one more example in which i will add the seekBrain and walk behaviour :

 // This Class defines what a Zombi is.
 function Zombi(x,y) {
     this.x = x;
     this.y = y;
     this.dirX = 0 ; // direction X
     this.dirY = 0;  // direction Y
     this.speed = 0.1; // common speed for all zombies
 }

 // have the zombi seek the brain located at (x,y)
 Zombi.prototype.seekBrain = function (x,y) {
    this.dirX = (x - this.x );
    this.dirY = (y - this.y );
    // normalize direction
    var norm = Math.sqrt( this.dirX*this.dirX + this.dirY*this.dirY  );
    this.dirX/=norm;
    this.dirY/=norm;
 }

 // Have the zombi walk in its current direction
 Zombi.prototype.walk = function() {
      this.x += this.dirX * this.speed;
      this.y += this.dirY * this.speed;
 }

 // image and draw remains the same

And now you might want for your collection :

// makes all zombies walk.
  Zombies.walkAll = function() {
    var i=0;
    var __zombies = this.zombies;
    for (;i<__zombies.length; i++) {
        __zombies[i].walk();
    }
}

// constructor, summon, summonAt, and drawAll remains the same.

So to summon a zombi at random place every xxx ms, do something like :

// summons a zombi at a random place every 2 seconds (==2000 ms)
setTimeInterval(2000, function() { zombies.summon(); } );

now, if hero.x and hero.y are what we guess, you can do :

// Have a random zombi hunt for hero's brain every 2 seconds
setTimeInterval(2000, function() { 
          var which = Math.floor(zombies.zombies.length * Math.random()); 
          zombies.zombies[which].seekBrain(hero.x, hero.y);
} );

provided you call to zombies.walkAll(); and zombies.drawAll(); on a regular basis, you've got the start of a game ! (i love so much zombies :-) )

Upvotes: 0

Zachary Carter
Zachary Carter

Reputation: 373

First of all, where are you declaring the variable TotalZombies?

Try something like this :

var zombies = new Array();

for (var i = 0; i < 100; i++) {
   var zombie = new Image();
   zombie.src = 'images/monster.png';
   ctx.drawImage(zombie, Math.floor((Math.random()*100)+1), Math.floor((Math.random()*100)+1));
   zombies.push(zombie);
}

This will create 100 zombies, with random x and y positions between 1 and 100. It will add each zombie to the zombies array after they have been instantiated.

Upvotes: 1

AbstractProblemFactory
AbstractProblemFactory

Reputation: 9811

You should iterate through zombies array, and invoke drawImage() on everyone.

Extra tip: remember to change x and y after all iteration.

Upvotes: 0

Related Questions