Sign in to follow this  
Chad Smith

Moving my enemies

Recommended Posts

Chad Smith    1344
EDIT: This post right here, is about how I couldn't get my enemies loaded right. That is now fixed, so I changed the topic title to my new problem. Making the enemies move. Go to the bottom of this topic, to see the post on it. Hey, me and my friend are creating a little 2D Sidescroller. I am trying to implent the enemies inside of the game right now. So, I create a enemy class. This is what the drawing function inside my enemy class looks like:
void Enemy::DrawEnemy(int sourcew, int sourceh, int x, int y)
{
     sourcew=enemySource.w;
     sourceh=enemySource.h;
     x=enemyDest.x;
     y=enemyDest.y;
     SDL_BlitSurface(enemy, &enemySource, SDL_GetVideoSurface(), &enemyDest);
}



Next, is when I create the Enemies instace. I do it as follows
Enemy enemy[10];
Next, I Init everyone of the enemies like this:
enemy[0].CreateEnemy(2);
enemy[1].CreateEnemy(2);
enemy[2].CreateEnemy(2);
enemy[3].CreateEnemy(2);
enemy[4].CreateEnemy(2);
enemy[5].CreateEnemy(2);
enemy[6].CreateEnemy(2);
enemy[7].CreateEnemy(2);
enemy[8].CreateEnemy(2);
enemy[9].CreateEnemy(2);



Also, I know it would be better to use a for loop to do that, and I had it like that, but it didn't work how I wanted it to work, so I wanted to see if it was my for loop doing it. Guess not. Anyway, back to the code! lol. Next, I draw all the enemies:
enemy[0].DrawEnemy(128, 128, 200, 300);
enemy[1].DrawEnemy(128, 128, 200, 400);
enemy[3].DrawEnemy(128, 128, 400, 200);
enemy[4].DrawEnemy(128, 128, 700, 400);
enemy[5].DrawEnemy(128, 128, 700, 300);
enemy[6].DrawEnemy(128, 128, 700, 200);
enemy[7].DrawEnemy(128, 128, 900, 300);
enemy[8].DrawEnemy(128, 128, 1000, 200);
enemy[9].DrawEnemy(128, 128, 2000, 500);



Again, I would have used a for loop here, but I wanted to see if my for loop was messed up. Here is the problem. All the enemies get drawn, but they always get drawn in the top left corner of the screen! Why is this happening? Is my logic wrong? Am I taking this a hardway, or what? Any help on enemies on this stuff will be helpfull! Thanks, Chad! [Edited by - Chad Smith on March 15, 2006 6:32:14 PM]

Share this post


Link to post
Share on other sites
Cuzz    122
Your code isn't copying your position information correctly. It should be


void Enemy::DrawEnemy(int sourcew, int sourceh, int x, int y)
{
enemySource.w = sourcew;
enemySource.h = sourceh;
enemyDest.x=x;
enemyDest.y=y;
SDL_BlitSurface(enemy, &enemySource, SDL_GetVideoSurface(), &enemyDest);
}

Share this post


Link to post
Share on other sites
Chad Smith    1344
Alright,
today I worked really hard on some other stuff, but now I need to get the enemies moving. I did what I would usually do on moving stuff, to get the enemies moving. So, this is what I did. First off, I changed my Drawing function for the enemies. It now looks like the following:


DrawEnemy(int sourcew, int sourceh, int x, int y, float XVel);


That way, I can manage each of the enemies x velocity right when I draw them, without each and everysingle enemy having the same velocity. That would get very repetive. Also, inside the DrawEnemy function I do this now.


XVelEnemy=XVel;


Next, I added a function inside my enemyclass that now updates the destination of the enemy. The function looks like this in my enemy.cpp file:


void Enemy::UpdateEnemy()
{
enemyDest.x-=XVelEnemy;
}


So that should update the destination to move towards the main character as far as I am concerned.

Finally, how I call update in my main function. I do it as follows:


for(int i = 0; i<10; i++)
{
enemy[i].UpdateEnemy();
}


So, as far as I am aware this illiterates through the loop 9 times, and each of the enemies should be updated per frame. Am I right, or is my logic plain wrong?

I am sorry for asking for this much help, and I know I shouldn't since I need to learn from my own mistakes. I usually fix my own problems, but this is not making any since to me at all! Also, I am sure there is something that might be missing and I am just dumb enough to miss it, to make the whole thing wrong.

So, thanks to all who help!

Also, I am initing all the velocities to 2.

Chad.

Share this post


Link to post
Share on other sites
Kalazart    148
enemyDest is the point to where it should move, right? If it is, you are doing wrong stuff. You shouldn't change the destination when updating the position. You should change the actual coordinates of the object.

First, you must have 2 components of the velocity. Let's call the Vx and Vy. Then, on the Update function, you add Vx to the x coordinate and Vy to the y coordinate of the enemy. To make sure you won't let the enemy go past enemyDest, you do a verification to see if it passed through -- if it did, place there and zero the velocity, since movement is done.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Umm...maybe you just didn't understand the type of game I am creating. I want it where the velocity dosen't go back to 0. And the destination, is where it starts. It is a SDL_Rect variable. And, that is how I have done all of my motion, and if you want the proof, then I will show you my bullet class, as it uses the exact same thing.

What could be going on?


Chad.

Share this post


Link to post
Share on other sites
Kylotan    10002
The loop iterates 10 times, from 0..9. You shouldn't pass a velocity to DrawEnemy, as the velocity has nothing to do with drawing it. You should pass the velocity to UpdateEnemy. DrawEnemy shouldn't call UpdateEnemy or vice versa - they should be called independently by your game loop. Really every enemy should have its own velocity or you're going to have problems if and when you want them to move at different speeds.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Thank you for that.

So, instead should I make the velocity variable an array? I would use vectors(I don't even know if that would be good here or not)but I don't understand them at this time.

Also, I do call the update function outside of the draw function. In the draw function, I just assigned the velocity variable. I think I understand what is wrong. I will work on this a little bit more.

I am also going over to my friends house, to get some faster development going on, instead of just sending the graphics through AIM. We would use CVS or something to that matter but we don't have the money to spend on a server.

Thanks,
Chad.

Share this post


Link to post
Share on other sites
Drew_Benton    1861
Quote:
Original post by Chad Smith
I am also going over to my friends house, to get some faster development going on, instead of just sending the graphics through AIM. We would use CVS or something to that matter but we don't have the money to spend on a server.


Free + I have two tutorials on using it [smile] Should be straight forward, but I'll be on aim later today when you run into troubles.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Ok,
I have been looking at this, and it is STILL not making any sense at all. This is so weird. I can not make any progress on this at all. It is just so weird how it is basically just like my bullet class and the bullet moves, but the enemy won't move.

This is what I have in the UpdateEnemy function:


void Enemy::UpdateEnemy(float XVel)
{
for(int i = 0; i<9; i++)
{
XVelEnemy[i]=XVel;
enemyDest.x-=XVel;
}
}



Then, I call the function like this in my main game loop:


for(int i = 0; i<10; i++)
{
enemy[i].UpdateEnemy(2);
}



Alright, I know that I shouldn't keep on asking this, and just figure this out on my own, and I usually do figure this stuff out on my own, but for some unknown reason this will just not work, and I am like...99% sure that everything is exactly like it should be.

Any suggestions?

Chad.

PS: Thanks ahead of time for all who help! All of Gamedev.net will be credited in the credits.

Share this post


Link to post
Share on other sites
Kylotan    10002
Why store XVelEnemy[i] if you're not going to do anything with it? That shouldn't cause a problem in this case, but I want to make sure you understand what you're coding.

Note that you call UpdateEnemy once per enemy, which is fine. (You should probably just call it Update if it's a member of the Enemy class.) Then for some reason you loop through all enemies again within it. So you end up modifying enemyDest.x (which again should probably be called dest.x, presuming it's a member of the Enemy class) 100 times, 10 times for each enemy. I don't think that is what you want.

Seeing which variables are in your Enemy class might help narrow down the problem.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Ok, I will just show you all of my enemy class.


This is what it looks like:


class Enemy
{
public:

Enemy();
~Enemy();

//create the Enemy
void CreateEnemy(int type);
//draw the enemy
void DrawEnemy(int sourcew, int sourceh, int x, int y);
//update the enemy
void UpdateEnemy(float XVel);
//delete the enemy
void DeleteEnemy();

//varialbes
SDL_Surface* enemy;
SDL_Rect enemySource;
SDL_Rect enemyDest;
private:
int XVelEnemy[10];
int IenemyDest;
};



Again, thanks to all who help.

Also, I am sure this will be really simple, and something I just forgot. That is how my mistakes usually are.

Thanks,
Chad.

Share this post


Link to post
Share on other sites
Kylotan    10002
Ok, why does each enemy have 10 velocity values? Each enemy should have one position and one velocity (or 1 position rect and an X and a Y velocity if you want to do it that way). And what does IenemyDest do?

I can't see an obvious bug so the problem is either in how you're updating the enemy or in how you're drawing it after the updates. As I said, get rid of the array of velocity values because you don't need 10 per enemy, and make sure you only apply the velocity to an enemy's x position once per update.

How're you calling DrawEnemy in your game loop?

Share this post


Link to post
Share on other sites
Chad Smith    1344
Ok, I will show you what my DrawEnemy function looks like after I get rid of the arrays. This is what it looks like:



void Enemy::DrawEnemy(int sourcew, int sourceh, int x, int y)
{
enemySource.w = sourcew;
enemySource.h = sourceh;
enemyDest.x=x;
enemyDest.y=y;
SDL_BlitSurface(enemy, &enemySource, SDL_GetVideoSurface(), &enemyDest);
}




This is what the update function looks like:


void Enemy::UpdateEnemy(float XVel)
{
XVelEnemy=XVel;
enemyDest.x-=XVel;
}





Then finally this is how I call each of those in my main game loop


for(int i = 0; i<10; i++)
{
enemy[i].UpdateEnemy(2);
}
enemy[0].DrawEnemy(256, 128, 200, 300);
enemy[1].DrawEnemy(128, 128, 200, 400);
enemy[3].DrawEnemy(256, 128, 400, 200);
enemy[4].DrawEnemy(128, 128, 700, 400);
enemy[5].DrawEnemy(256, 128, 700, 300);
enemy[6].DrawEnemy(128, 128, 700, 200);
enemy[7].DrawEnemy(256, 128, 900, 300);
enemy[8].DrawEnemy(128, 128, 1000, 200);
enemy[9].DrawEnemy(256, 128, 2000, 500);



Anything I am doing wrong?

Also, the enemies right now are only going to be moving along the X axis.

Also, the IenemyDest variable is no longer there. I only had it there to test something out, and I meant to take it out of the post when I posted that, but I forgot to.

Thanks so much y'all! Gamedev.net deserves to be in every games credits, as much as y'all help!

Chad.

Share this post


Link to post
Share on other sites
rip-off    10979
You store the velocity of a enemy in your enemy class. why not store its position. It will simplify your code:




class Enemy
{
public:
Enemy( float startx, float starty, float startVelx, float startVely );
void draw();
void update();
/*
additional getFoo() and setBar() methods if you want.
*/

private:
float xposition, yposition;
float xvelocity, yvelocity;
SDL_Surface *image;
};

Enemy::Enemy( float startx, float starty, float startVelx, float startVely )
:xposition(startx),yposition(starty),
xvelocity(startVelx),yvelocity(startVely)
{
}

void Enemy::draw()
{
SDL_Rect destination;
destination.x = (int)startx;
destination.y = (int)starty;
destination.w = image->w;
destination.h = image->h;
SDL_BlitSurface( image, NULL, SDL_GetVideoSurface(), &dest );
}

void Enemy::update()
{
xposition += xvelocity;
yposition += yvelocity;
}





This simplifies your caller to:


for(int i = 0; i<10; i++)
{
enemy[i].update();
enemy[i].draw();
}




You may need to seperate updatiung from drawing for collision detection or whatever.

EDIT:

This method may require you to move the constructor call into a seperate method, like so:

void Enemy::setup( const std::string& imageName, float x, float y, float xvel, float yvel, .../*other values*/ );

This is because you are probably using either a static array or a std::vector for storing you enemies( std::vector I hope ). So the default constructor will be have to be callable ( and you should provide one ).

Share this post


Link to post
Share on other sites
Chad Smith    1344
Hey, I know it has been a while since I have posted here about this, but I am STILL working on getting the enemies to move. This so weird!! I have tried like everything and this is not working at all.

My enemy class looks the same as the last time I posted it. I did what rip-off said, and that didn't work eithier. I can't figure this out at all.

I do believe I have enough knowledge and stuff to make a game like this, but for somereason something simple like moving enemies is killing me. Mostly because it is not making since to me at all!

Anymore things to try? Any help is helpful!

Thanks to all who help.

Chad.

Share this post


Link to post
Share on other sites
evillive2    779
enemy[0].DrawEnemy(128, 128, 200, 300);
enemy[1].DrawEnemy(128, 128, 200, 400);
enemy[3].DrawEnemy(128, 128, 400, 200);
enemy[4].DrawEnemy(128, 128, 700, 400);
enemy[5].DrawEnemy(128, 128, 700, 300);
enemy[6].DrawEnemy(128, 128, 700, 200);
enemy[7].DrawEnemy(128, 128, 900, 300);
enemy[8].DrawEnemy(128, 128, 1000, 200);
enemy[9].DrawEnemy(128, 128, 2000, 500);
void Enemy::DrawEnemy(int sourcew, int sourceh, int x, int y)
{
enemySource.w = sourcew;
enemySource.h = sourceh;
enemyDest.x=x; // the x you pass in is static and changes the update you made
enemyDest.y=y; // same as the x
SDL_BlitSurface(enemy, &enemySource, SDL_GetVideoSurface(), &enemyDest);
}



Using that DrawEnemy function and the static numbers in that first list your enemies will never move.

Your DrawEnemy function is taking parameters it really shouldn't need. For instance your enemy object should know it's source rectangle and dimensions when it is first created and you should never have to tell it again (barring some special effect or something). Also, sending in the x and y variables in this way makes no sense as this will just keep sending in the same static values from the hard coded numbers you showed above. And again, since you update the enemies position and x velocity in the UpdateEnemy function you shouldn't need those parameters at all. Try simplifying your DrawEnemy function to:
void Enemy::DrawEnemy()
{
SDL_BlitSurface(enemy, &enemySource, SDL_GetVideoSurface(), &enemyDest);
}



rip-off's post is pretty accurate but I think you need to change this:
void Enemy::draw()
{
SDL_Rect destination;
// destination.x = (int)startx; - startx and starty aren't valid members
// destination.y = (int)starty;
destination.x = (Sint16)xposition; // I prefer to use SDL's types
destination.y = (Sint16)yposition;
destination.w = image->w;
destination.h = image->h;
SDL_BlitSurface( image, NULL, SDL_GetVideoSurface(), &dest );
}



I hope that helps.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Hey, thanks a lot for that. And OMG I see what you are saying on that. My brain must not have been thinking at all. I will be changing up my DrawEneny function and enemy class to get it as close as I can to that. I have got to work on something else right now, but right after that, back to the game!

Also, I will be posting the game here when it is done. Which I hope will be pretty soon, as I think the rest of the games logic should be in the bag. Only time will tell.


Chad.

Share this post


Link to post
Share on other sites
Chad Smith    1344
Ok, it has been a while, and I actaully just NOW got the time to work on the game again. I go directly to coding the enemies. I look at this post, to compare it to my code, and it is the same really. I go to compile it, it compiles...the ENEMY moves! YEAH!! But, no...that is not a error...I said...ENEMY. Only one enemy is seen on the screen...but it does move! I don't understand it. After further checking my code...it seems like everything is like it should be. Can someone else check my main game code out, to see if it is right?



void PlayGame()
{
Uint8* keysheld;
keysheld=SDL_GetKeyState(0);
character.CreateMain();
bullet.CreateBullet();
enemy[0].CreateEnemy(1);
enemy[1].CreateEnemy(2);
enemy[2].CreateEnemy(1);
enemy[3].CreateEnemy(2);
enemy[4].CreateEnemy(1);
enemy[5].CreateEnemy(2);
enemy[6].CreateEnemy(1);
enemy[7].CreateEnemy(2);
enemy[8].CreateEnemy(1);
enemy[9].CreateEnemy(2);
background=SDL_LoadBMP("Cloudtest1.bmp");
//now set all the enemies up before we enter the game loop
enemy[0].Setup(200, 300, 2, 0);
enemy[1].Setup(200, 500, 1, 0);
enemy[2].Setup(400, 200, 2, 0);
enemy[3].Setup(400, 370, 2, 0);
enemy[4].Setup(400, 500, 2, 0);
enemy[5].Setup(600, 256, 3, 0);
enemy[6].Setup(600, 400, 2, 0);
enemy[7].Setup(600, 100, 1, 0);
enemy[8].Setup(700, 400-128/2, 2, 0);
enemy[9].Setup(900, 400, 2, 0);
while(!done)
{
if(SDL_PollEvent(&event))
{
if(event.type==SDL_QUIT)
{
done = true;
}
character.InputMain(event);
}
if(keysheld[SDLK_ESCAPE])
{
done = true;
}
if(keysheld[SDLK_SPACE])
{
bullet.FireBullet(character.mainDest.x, character.mainDest.y, 8, 0);
}
Background();
bullet.UpdateBullet();
bullet.DrawBullet();
for(int i = 0; i<10; i++)
{
enemy[i].UpdateEnemy();
enemy[1].DrawEnemy();
}
character.DrawMain();
character.CollisionMain();
SDL_Flip(SDL_GetVideoSurface());
}
}



I am getting closer and closer. I keep on looking at my code...but it seems like everything it like it should be. If you need to see my Enemy class now, then tell me, and I will post it. Thanks to all who help/helped! It has greatly helped me in developing this game, and my skills.

Chad.

Share this post


Link to post
Share on other sites
Kylotan    10002
You're only telling it to draw 1 enemy. Look closely at what you typed.

On a different note, you should use while(SDL_PollEvent(&event)), not if(SDL_PollEvent(&event)). You need to process every event that is waiting for you.

Share this post


Link to post
Share on other sites
Chad Smith    1344
yeah, I was coming her to tell everyone that I noticed that. I was really tired last night, because I forgot of the time change...lol. Ok, thanks everyone for the help!!! I was really dumb for not figuring that out on my own. Thanks everyone again!


Also, thanks for telling me it should be while and not if.

Chad

Share this post


Link to post
Share on other sites

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