Sign in to follow this  

Enemy Array

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Could someone explain how I would go about making an enemy array. For example if I have 5 enemies walking forward and one bumps into the wall, the rest of them keep going. I realize I could just check each enemy but that's a WHOLE LOT OF WORK! I'm sure there's a much simpler way. Could someone explain from top to bottom. Note: "Using SDL"

Share this post


Link to post
Share on other sites
I've reviewed that and it doesn't help much. I don't want to keep adding the enemies off screen. I want them to have there own coordinates like Super Mario for example.

Share this post


Link to post
Share on other sites
"that's a WHOLE LOT OF WORK" - Not really.

Reading 'masters of Doom', it surprised me to learn that John Carmack would often try the most obvious solution first, and then realize a better way to do it later.

Also, the neat thing about software, once it works like you want, you dont have to deal with it anymore. In other words, the 'whoole lotta work' only needs done once by you.

And finally, I use an array of objects in a game im working on, and it isnt an extreme amount of work to get each to play along nicely.

There are more elegant solutions, and ironically, using a computer to find them is the wrong way (IMHO) to go about it. Try a piece of paper and a pencil instead.

Hope this helps :)

-Jason

Share this post


Link to post
Share on other sites
im not 100% sure im reading from the same page as you, but i'll say something based on what i think your talking about.

couldnt you make an 'enemy' structure, with the coordinates etc within it, and make an array of the enemy structures? Checking each enemy wouldnt be a whole lot of work since all you would need is a simple for loop.

for(i=0; i<MAX_ENEMIES; i++;)
{
if(enemyarray[i].right <= wall.left)
{
enemyarray[i].walk = false;
}
}

or something similar using your code and variables. I may have got completely the wrong idea about what your asking, if so, just let me know.

Share this post


Link to post
Share on other sites
Quote:
Original post by AntiGuy
For example if I have 5 enemies walking forward and one bumps into the wall, the rest of them keep going. I realize I could just check each enemy but that's a WHOLE LOT OF WORK! I'm sure there's a much simpler way. Could someone explain from top to bottom.


that's pretty much how you do it:


void Engine::Update( float dt )
{
for (int i = 0; i < numEnemies; ++i)
{
myEnemies[i].Update(dt);
}
}



update each enemy every frame. update includes: locomotion updates, collision detection, AI, etc. some things, like AI can be timesliced so that it's not updated every single frame, but your physics and collision detection should be updated every frame. you'd be surprised at the amount of stuff a computer can do each frame...

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by AntiGuy
For example if I have 5 enemies walking forward and one bumps into the wall, the rest of them keep going. I realize I could just check each enemy but that's a WHOLE LOT OF WORK! I'm sure there's a much simpler way. Could someone explain from top to bottom.


nope, that's pretty much how you do it:


void Engine::Update( float dt )
{
for (int i = 0; i < numEnemies; ++i)
{
myEnemies[i].Update(dt);
}
}




update each enemy every frame. update includes: locomotion updates, collision detection, AI, etc. some things, like AI can be timesliced so that it's not updated every single frame, but your physics and collision detection should be updated every frame. you'd be surprised at the amount of stuff a computer can do each frame...

-me

Share this post


Link to post
Share on other sites
Ok, one way would be to make a struct or class (personally I use classes) and assuming the class is called enemy do somthing like:


class cEnemy
{
int x;
int y;
int velocity;
};


cEnemy ObjectName[10];



And then you have 10 enemies that are completely seperate from each other and can have individual locations and speed.

If this isn't what you are talking about let me know, I'll try again ;)

Share this post


Link to post
Share on other sites
just make sure you try and encapsulate the code as good as possible. what i mean is, let all your object's only care about themselves, and not about outside world. at the very least make the data variables private. for example, have your Enemy class have functions like this:

Update()
Render()
Do_Collision()

etc. i would personally try to keep Update() the only interface the world has to the object, IE, call Render() and Do_Collision() from inside of Update(). then you just call Update() each frame like the way Palidine showed.

Share this post


Link to post
Share on other sites
Well the method definitly worked if I'm performing it correctly, but things seem to move a bit slower. With an array of 5 enemies on a 1.7ghz pentium 4 processor (384MB), should there be any slowdown? If not there may be something wrong with how I did it.

I stored all (well most) of the checks into 1 for loop inside of a function that I call on each frame. The checks were not in a function form. I just put them right there. Everything pans out, but the only way to get the program to move at normal speed is changing the enemy number to 1 or 2. Is this normal?

I'd also like to ask, is there a method for blitting the object (out of a bunch of objects) with the highest y value first?

Share this post


Link to post
Share on other sites
Quote:
Original post by AntiGuy
Well the method definitly worked if I'm performing it correctly, but things seem to move a bit slower. With an array of 5 enemies on a 1.7ghz pentium 4 processor (384MB), should there be any slowdown? If not there may be something wrong with how I did it.


no, there really shouldnt be. describe better exactly what your doing, and exactly what your trying to accomplish. post *some* code, too.

Quote:

I stored all (well most) of the checks into 1 for loop inside of a function that I call on each frame. The checks were not in a function form. I just put them right there. Everything pans out, but the only way to get the program to move at normal speed is changing the enemy number to 1 or 2. Is this normal?


what kind of checks are you performing exactly, and on what?

Quote:

I'd also like to ask, is there a method for blitting the object (out of a bunch of objects) with the highest y value first?


well, im guessing you want your objects to be sorted properly, right? in which case, you have it backwards. things with a lower Y value should be drawn first. there are about a million ways you can do this. i could explain how i do mine, if you'd like, but you would have to be semi-familiar with the STL, which im guessing since your using arrays that your not.

Share this post


Link to post
Share on other sites
This is the main checker. It checks for positions, collisions from the bottom, and the source of the 1 BMP file for animation.It also includes controls for test purposes (I know they all move at once). The variables are in other files but this should give you the picture.The z is a variable I created to represent the depth of the picture. This way, when the character jumps, he doesn't appear behind the enemy. I think that about covers it.



void CheckEnemies()
{

for(int i=0;i<enemies;++i)
{

//position
enemypos[i].x = enemy[i].x - camera.x;
enemypos[i].y = enemy[i].y - camera.y ;
//animation frame
enemy[i].Animation.x = enemy[i].column * 100;
enemy[i].Animation.y = enemy[i].frame * 110;
enemy[i].Animation.w = 100;
enemy[i].Animation.h = 110;
//Up collision detection
if((player.x + player.Animation.w/2 >= enemy[i].x &&
player.x <= enemy[i].x + enemy[i].Animation.w /2) &&
((player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h )||
(player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h+1 )||
(player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h+2)))

//Results
{player.y +=player.ScrollSpeedy; player.z += player.ScrollSpeedy;}


//Right
if(keys[SDLK_KP6]==1)
{if(enemy[i].x < map.w){enemy[i].x +=enemy[i].ScrollSpeedx;}}

//Left
if(keys[SDLK_KP4]==1)
{if(enemy[i].x > map.x - enemy[i].Animation.w){enemy[i].x -=enemy[i].ScrollSpeedx;}}

//Up
if(keys[SDLK_KP8]==1)
{if((enemy[i].y > map.y - enemy[i].Animation.h + TopPath)|| ((enemy[i].State =! 6)&&(enemy[i].y > map.y - enemy[i].Animation.h))){enemy[i].y-=enemy[i].ScrollSpeedy; enemy[i].z -=enemy[i].ScrollSpeedy;}}


//Down
if(keys[SDLK_KP5]==1)
{if(enemy[i].y < map.h - enemy[i].Animation.h){enemy[i].y+=enemy[i].ScrollSpeedy;enemy[i].z +=enemy[i].ScrollSpeedy;}}

//*******************ERROR FIX***************************
if(keys[SDLK_KP6]==1)
{enemy[i].Direction = 0;}
if(keys[SDLK_KP4]==1)
{enemy[i].Direction = 1;}
if((keys[SDLK_KP4]||keys[SDLK_KP5]||keys[SDLK_KP8]||keys[SDLK_KP6]) ==1)
{enemy[i].State = 1;}else enemy[i].State = 0;
if((keys[SDLK_KP4] && keys[SDLK_KP6])||((keys[SDLK_KP8] && keys[SDLK_KP5]))==1)
{enemy[i].State = 0;}
if(((keys[SDLK_KP4] && keys[SDLK_KP6])==1)&&((keys[SDLK_KP8] || keys[SDLK_KP5])==1))
{enemy[i].State = 1;}

if(((keys[SDLK_KP4] || keys[SDLK_KP6])==1) && ((keys[SDLK_KP8] && keys[SDLK_KP5])==1))
{enemy[i].State = 1;}
//****enemy[i] *run set up**********
if(enemy[i].State != 6)
{if(keys[SDLK_KP_PLUS]== 1){enemy[i].ScrollSpeedx = 10;}else{enemy[i].ScrollSpeedx = 3;}
}



}
}

Note: Sources don't seem to be working

Share this post


Link to post
Share on other sites
what exactly isnt working? Does it not do what you intended or does it have errors? if it has errors which ones are you getting?


if((player.x + player.Animation.w/2 >= enemy[i].x &&
player.x <= enemy[i].x + enemy[i].Animation.w /2) &&
((player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h )||
(player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h+1 )||
(player.z + player.Animation.h == enemy[i].z + enemy[i].Animation.h+2)))




thats a huge collision detection 'if' statement. i dont know if its causing the problems you have right now but i think you may find some in the future with it. I think you should be checking with the 'y' position rather than the 'z' position that you invented for the jumping problem.

also:


enemy[i].Animation.w = 100;
enemy[i].Animation.h = 110;




surely these only need to be set once in the constructor for the class? maybe they change at some point but im pretty sure its not necessary (and also inneficient) to set them like this every cycle, for every enemy.

i have no idea what your trying to achieve with all the input stuff. its kinda messy. try going through your code on paper and see the changes that it makes.

Quote:

The z is a variable I created to represent the depth of the picture. This way, when the character jumps, he doesn't appear behind the enemy.


why not just make sure that the character is blitted after all the enemies? that way it will always be drawn on top?

Share this post


Link to post
Share on other sites
You know, when going about doing enemies and the like i found it is better to use a linked list. Its a bit harder to implement, but once you have the basic concept down everything else becomes pie. They make it so you dont have to worry about doing a ton of checking to eliminate the object from the array and stuff..

Here is the article i learned from.

Clicky.

Share this post


Link to post
Share on other sites
No no no the code works just fine. I meant sources don't seem to work for Gamedev.net at that moment, that's why I posted it like that. The real question is if there should be slow down on a 1.7ghz processor (384MB). Secondly, I can't have the player blitted last because he has to appear behind enemies at times. Enemies have to appear behind of and in front of enemies also. I want the object with the lowest z position to be drawn first.


Big Note: I forgot to add that I'm using a 640x480 resolution!

[Edited by - AntiGuy on September 14, 2004 11:11:48 AM]

Share this post


Link to post
Share on other sites
I think I've found the problem! I thought it was the use of for loops but when I changed the canvas size of the 1 BMP I was using, performance increased although, (as expected)the objects would disappear as result of my setup. I think I've got this covered. Thanks for the help!

Share this post


Link to post
Share on other sites
if your using SDL, you will most likely see a pretty nice increase in speed if the color depth of your images match up to the depth of the screen surface.

basically, if you create a window with 32 bpp as the parameter for the screen, then all surfaces that you render should also have 32 bpp. if not, SDL will convert them on the fly, each time they are blitted (VERY slow!).

theres an easy way around this. instead of making sure all your image files match up to the bit depth of the screen, you can convert it using an SDL function. the function you need is SDL DisplayFormat(). this function receives a surface and returns a new surface. the one you send it should be the surface you want to convert, and the return is the newly created surface. its been a while since ive used SDL for blitting, but im pretty sure it creates an ew surface. that means you have to delete the old one.

Share this post


Link to post
Share on other sites

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this