Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Creating An Enemy Array

This thread is locked; no one can reply to it. rss feed Print
Creating An Enemy Array
allegro programmer
Member #15,653
June 2014

i was wondering how could i create an enemy array of sprites in which I could insert new images for each one(if necessary) and place them where i wanted on my map.
right now I have

I would like to modify the current code if possible.

#SelectExpand
1void InitSprites(Sprite &sprite, ALLEGRO_BITMAP *image=NULL,ALLEGRO_FONT*font=NULL,ALLEGRO_BITMAP*image1=NULL) 2{ 3 4 sprite.health=100; 5 6 sprite.live=true; 7 sprite.x =500; 8 sprite.y = 500; 9 sprite.boundx=20; 10 sprite.boundy=20; 11 sprite.velX = 2; 12 sprite.velY = 2; 13 sprite.dirX = -1; 14 sprite.dirY = -1; 15 16 sprite.maxFrame = 2; 17 sprite.curFrame = 0; 18 sprite.frameCount = 0; 19 sprite.frameDelay = 5; 20 sprite.frameWidth = 64; 21 sprite.frameHeight = 64; 22 sprite.animationColumns = 2; 23 sprite.animationDirection = 1; 24 if (sprite.health<0){ 25 sprite.live=false; 26 sprite.x=3200; 27 } 28 29 if(image != NULL) 30 sprite.image = image; 31 if(image1 != NULL) 32 sprite.image1 = image1; 33 if(font !=NULL) 34 sprite.font=font; 35} 36void UpdateSprites(Sprite &sprite,SpaceShip &ship) 37{ 38 39 if(sprite.live=true) 40 { 41 if(++sprite.frameCount >= sprite.frameDelay) 42 { 43 sprite.curFrame += sprite.animationDirection; 44 if(sprite.curFrame >= sprite.maxFrame) 45 sprite.curFrame = 0; 46 else if(sprite.curFrame <= 0) 47 sprite.curFrame = sprite.maxFrame - 1; 48 49 sprite.frameCount = 0; 50 } 51 52al_draw_filled_rectangle((sprite.x - sprite.boundx)-cameraPosition[0]-100, (sprite.y - sprite.boundy)-cameraPosition[1]-100, (sprite.x + sprite.boundx)-cameraPosition[0]+100, 53 (sprite.y + sprite.boundy)-cameraPosition[1]+100, al_map_rgba(0,0,0, 0)); 54 55 if(sprite.x - sprite.boundx < ship.x + ship.boundx+100 && 56 sprite.x + sprite.boundx > ship.x - ship.boundx-100 && 57 sprite.y - sprite.boundy < ship.y + ship.boundy+100 && 58 sprite.y + sprite.boundy > ship.y - ship.boundy-100) 59 { 60 61 62 if (sprite.x < ship.x) 63 { 64 sprite.x = sprite.x + 1; 65 } 66 else if (sprite.x > ship.x) 67 { 68 sprite.x =sprite.x - 1; 69 } 70 71 if (sprite.y < ship.y) 72 { 73 sprite.y = sprite.y + 1; 74 } 75 else if (sprite.y > ship.y) 76 { 77 sprite.y =sprite.y - 1; 78 } 79 if(sprite.health<1) 80 { 81 sprite.x=3200; 82 sprite.live=false; 83 } 84if (sprite.live=false) 85{ 86 sprite.x=3200; 87 } 88 89 90} 91} 92} 93 94void DrawSprites(Sprite &sprite) 95{ 96 97 if (sprite.live=true) 98 { 99 100 cameraPosition[0] = ship.x-WIDTH/2; 101 cameraPosition[1] = ship.y-HEIGHT/2; 102 103 if(cameraPosition[0] < 0) 104 cameraPosition[0] = 0; 105 if(cameraPosition[1] < 0) 106 cameraPosition[1] = 0; 107 if(cameraPosition[0] > (mapwidth * mapblockwidth) - WIDTH) 108 cameraPosition[0] = (mapwidth * mapblockwidth) - WIDTH; 109 if(cameraPosition[1] > (mapheight * mapblockheight) - HEIGHT) 110 cameraPosition[1] = (mapheight * mapblockheight) - HEIGHT; 111 int fx =(ship.curFrame % ship.animationColumns) * ship.frameWidth; 112int fy = (sprite.curFrame / sprite.animationColumns) * sprite.frameHeight; 113 114al_draw_bitmap_region(sprite.image, fx, fy, sprite.frameWidth,sprite.frameHeight,sprite.x-sprite.boundx-cameraPosition[0],sprite.y-sprite.boundy-cameraPosition[1],0); 115al_draw_filled_rectangle((sprite.x - sprite.boundx)-cameraPosition[0], (sprite.y - sprite.boundy)-cameraPosition[1], (sprite.x + sprite.boundx)-cameraPosition[0], 116 (sprite.y + sprite.boundy)-cameraPosition[1], al_map_rgba(255, 0, 255, 100)); 117 118 119 120 }

This puts only 1 sprite on a map at a given location.

Dizzy Egg
Member #10,824
March 2009
avatar

Sprite sprite[10]; //0 indexed, so 0-9, not 1-10!!

Sprite[0].x = 10   //Sprite 1
Sprite[0].y = 20

Sprite[1].x = 10   //Sprite 2
Sprite[1].y = 10

etc etc

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

allegro programmer
Member #15,653
June 2014

Wow that's easy enough.

Where would I initiate that in the prototype as InitSprite(Sprite &sprite[10])?
or in the code as

void InitSprites(Sprite &sprite)
Sprite sprite[10]; //0 indexed, so 0-9, not 1-10!!

Sprite[0].x = 10   //Sprite 1
Sprite[0].y = 20
ect
ect
  sprite.live=true;

i was also recommended a double linked list, still trying to figure that out atm.

#00JMP00
Member #14,740
November 2012

you still can do this:

struct MovingObject {

int posx;
float posy;
float deltax;
float deltay;
BITMAP * MyBitmap;

}

Now you can go along and create such
objects

MovingObject EvilEnemy1;
vector <MovingObject> MoVos;

MoVos.pushback (EvilEnemy1);

Thus you can store all enemies in one vector and manipulate them as wished.
Further, you don't have to know the end number hold in vector.

Later, you can think of a class, having a move method, which could be called via vector too, which would further facilitate things.

allegro programmer
Member #15,653
June 2014

Ok so if i were going to use vectors Id have my struct

#SelectExpand
1struct Sprite 2{ 3 bool live; 4 int damage; 5 int health; 6 float x; 7 float y; 8//.... 9}; 10 11//prototypes 12InitSprite(Sprite &sprite..); 13DrawSprite(Sprite &sprite..); 14UpdateSprite(Sprite &sprite..); 15 16int main() 17{ 18//would this go in main or my init sprite function 19std::vector<Sprite>Enemy[1]; 20Enemy.pushback("enemy0.png") 21Enemy.pushback("enemy1.png") 22 return 0; 23} 24InitSprite(sprite &sprite, vector<sprite> Enemy) 25{ 26sprite.Enemy[0]10//x value- 27sprite.Enemy[0]=10//y value- 28sprite.Enemy[1]=40//how would I establish their x and y 29sprite.Enemy[1]=40 30} 31 32DrawSprite(sprite &sprite, vector<sprite> Enemy) 33{ 34al_draw_bitmap(sprite.Enemy[0]) 35al_draw_bitmap(sprite.Enemy[1])

I would normally std::cout<< Enemy;//print out enemy0 and 1.

How do I draw these on the screen using allegro and then be able to manipulate each one interdependently.

above is a failed attempt of what I want to do.

David Sopala
Member #5,056
September 2004

Vectors are much better than using an array so you can just push things on to the stack in the long run. It would be better to start using them now before you have to break your old habits of arrays.

Edgar Reynaldo
Member #8,592
May 2007
avatar

You don't want an array of vectors, just a vector of Sprites. If you don't know the STL (Standard Template Library) very well yet, take a look at this great reference :

https://www.sgi.com/tech/stl/

and specifically for std::vector :

https://www.sgi.com/tech/stl/Vector.html

std::vector<Sprite> my_vector;

Sprite s;
s.bmp = al_load_bitmap("my_sprite.png");
s.x = 30;
// ...

my_vector.push_back(s);

To alter the contents of your vector you need to use a reference :

Sprite& s1 = my_vector[0];
s1.bmp = al_load_bitmap("my_sprite.png");

// alternatively use the reference the vector accessor gives you :
my_vector[0].bmp = al_load_bitmap("my_sprite.png");

You can access a vector just like an array, using indices ie... my_vector[zero_based_index].

Quote:

How do I draw these on the screen using allegro and then be able to manipulate each one interdependently.

RTFM?

al_draw_bitmap(bmp , x , y , flags);

See

http://alleg.sourceforge.net/a5docs/5.0.10/

and

http://alleg.sourceforge.net/a5docs/refman/index.html

for the latest allegro 5 docs.

allegro programmer
Member #15,653
June 2014

this is exactly what I needed, thank you.

I know how to draw bitmaps on a screen.I meant doing it using vectors, because initially I thought it would be like an array(having different images for each item in array for example).

If I get it working I will post the code.

Edgar Reynaldo
Member #8,592
May 2007
avatar

allegro programmer
Member #15,653
June 2014

ok at this point im lost..

I tried doing basic c++ code using vectors /vectors with functions it worked perfectly.

when I tried to implement in allegro Had no idea how to use it with my code, no code worth posting(just wasnt doing even close to anything)

Im trying to create a war scene later in my game where several sprites follow my player

I want the all lets say 50 sprites be hosted in 4 functions like so

#SelectExpand
1void InitWarrior(Warrior warriors[], int size) 2{ 3 for(int i = 0; i < size; i++) 4 { 5 warriors[i].ID = ENEMY; 6 warriors[i].live = false; 7 warriors[i].speed = 5; 8 warriors[i].boundx = 18; 9 warriors[i].boundy = 18; 10 } 11} 12void DrawWarrior(Warrior warriors[], int size) 13{ 14 for(int i = 0; i < size; i++) 15 { 16 if(warriors[i].live) 17 { 18 al_draw_filled_circle(warriors[i].x, warriors[i].y, 20, al_map_rgb(255, 0, 0)); 19 } 20 } 21} 22void StartWarrior(Warrior warriors[], int size) 23{ 24 for(int i = 0; i < size; i++) 25 { 26 if(!warriors[i].live) 27 { 28 if(rand() % 500 == 0) 29 { 30 warriors[i].live = true; 31 warriors[i].x = WIDTH; 32 warriors[i].y = 30 + rand() % (HEIGHT - 60); 33 34 break; 35 } 36 } 37 } 38} 39void UpdateWarrior(Warrior warriors[], int size) 40{ 41 for(int i = 0; i < size; i++) 42 { 43 if(warriors[i].live) 44 { 45 warriors[i].x -= warriors[i].speed; 46 47 if(warriors[i].x < 0) 48 y warriors[i].live = false; 49 } 50 } 51}

this code is from an old game that creates random sprites on the screen coming from one side of the screen to the other. They act independently as well.

Is their a way to manipulate this code? to make it spawn 50 at once on the screen?
Also id love to know how to implement vectors instead if anyone has some example code.( I took a look at vectors through the link it didn't really say how to initiate them with bitmaps and large functions)

Edgar Reynaldo
Member #8,592
May 2007
avatar

vectors are easy. You only need to know a few things about them to use them.

1. vector is a template class, which means you need to instantiate the type when you instantiate the vector object.

vector<Sprite> sprite_vector;

2. Access to elements is done using array style indices.

sprite_vector[0] = s;
sprite_vector[0].x = 10;
//...

3. Adding an element to the vector is done using push_back.

sprite_vector.push_back(s);

4. Removing an element can be done using erase and iterators :

vector<Sprite>::iterator it = sprite_vector.begin();
if (it != sprite_vector.end()) {
   sprite_vector.erase(it);
}

5. Iterators can be incremented and the underlying element can be accessed through them.

++it;
Sprite s = *it;

That should be most of what you need.

The other thing to keep in mind is that vectors perform copy operations during resize and anything else that changes the structure of the vector so you need to keep in mind the difference between shallow and deep copies of the objects that you add to your vector. Generally vectors store pointers, which can be copied without altering the underlying object they point to.

Go to: