Enemy movement

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
PaperDuckyFTW
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 76
Joined: Sat Apr 03, 2010 5:08 am
Programming Language of Choice: C++

Enemy movement

Post by PaperDuckyFTW »

Im making a SDl platformer and atm im implimenting enemies.

So far it is in a class and I can spawn one onscreen which im happy about.
I can also make it move and collide with the tiles, which again im happy about.
What im not too happy about is how to make it have 'goomba' movement, as its not working

What I aim to do is have a 'enemy tile map', much like a tile map but instead creates a new enemy for each corresponding or respective number. So far I have it moving to the right, and when it collides with a wall tile what I want it to do is move in the opposite direction but I dont know how to do this.


Ive tried simple things like:

Code: Select all

x++;
if( ( collided_with_wall )&& (xvelocity greater then 0 ) )  //hit wall while moving right
{
     x - xvel;
     x--;
}
else
if ( collided with wall, and xvelocity less then 0 )  //hit wall while moving left
{
     x += xvel;
     x++;
}
Ive even tried just subtracting the velocity utthat didnt work. Does anyone know a solution?

Oh and how do I create the enemies from a enemy tile map? Better asked is how do I create more then one instance of the enemy? Im guessing its
new Enemy( x,y,variable); with the x and y variables being read from the map, btu when I tried it it didnt work. Ill try again but If you know thanks in advance
A Person
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 10
Joined: Mon Jul 12, 2010 3:12 am
Current Project: iPhone 2D Game
Favorite Gaming Platforms: Wii, NDS, iPhone, 360
Programming Language of Choice: Objective-C
Location: Calgary, AB

Re: Enemy movement

Post by A Person »

To switch directions just before you add the velocity to the position invert the velocity like so.

Code: Select all

velocity.x = -velocity.x;
velocity.y = -velocity.y;
X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Enemy movement

Post by X Abstract X »

To add to what was already said, you seem to be modifying 'x' way more than you need to in your code. It does not matter what direction the monster is travelling when he collides, you simply multiply the velocity by -1.

Code: Select all

monster.x += monster.xVelocity;

if (collisionWithWall)
    monster.xVelocity = -monster.xVelocity;
To store your enemies, you might want to consider using some sort of container, like an std::vector.
wearymemory
Chaos Rift Junior
Chaos Rift Junior
Posts: 209
Joined: Thu Feb 12, 2009 8:46 pm

Re: Enemy movement

Post by wearymemory »

X Abstract X wrote:To add to what was already said...
Perhaps it would be wiser in this situation to use absolute values:

Code: Select all

if (/* Colliding with the left wall. */) {
    deltaX = abs(deltaX);
}
if (/* Colliding with the right wall. */) {
    deltaX = -abs(deltaX);
}

...

x += deltaX;
Last edited by wearymemory on Wed Jul 14, 2010 12:54 pm, edited 3 times in total.
A Person
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 10
Joined: Mon Jul 12, 2010 3:12 am
Current Project: iPhone 2D Game
Favorite Gaming Platforms: Wii, NDS, iPhone, 360
Programming Language of Choice: Objective-C
Location: Calgary, AB

Re: Enemy movement

Post by A Person »

Perhaps it would be wiser in this situation to use absolute values:
CODE: SELECT ALL
if (LeftCollides()) {
deltaX = abs(deltaX);
}
if (RightCollides()) {
deltaX = -abs(deltaX);
}

...

x += deltaX;
I'm pretty sure that would be unesscerary and may even cause a problem i would just stick to inverting the velocity :)
wearymemory
Chaos Rift Junior
Chaos Rift Junior
Posts: 209
Joined: Thu Feb 12, 2009 8:46 pm

Re: Enemy movement

Post by wearymemory »

A Person wrote: I'm pretty sure that would be unesscerary and may even cause a problem i would just stick to inverting the velocity :)
I believe it's adjunct, but not unnecessary. How do you suppose it could cause a problem? In effect, it's doing exactly what X Abstract X's code should do, but with the advantage of not getting stuck if the entity's overlapping distance was greater than its delta (or velocity).
PaperDuckyFTW
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 76
Joined: Sat Apr 03, 2010 5:08 am
Programming Language of Choice: C++

Re: Enemy movement

Post by PaperDuckyFTW »

Thanks for all your posts, it might be easier to get help if i post the code which is bothering me

Code: Select all

//if its at edge of screen or collided with the top/bottom of tile
if( ( enemyCol.y < 0 ) || ( enemyCol.y + enemyCol.h > LEVEL_H ) || ( tile_collision( enemyCol ) ) )
	{
		enemyCol.y -= yVel; //stop moving down
		landed = true; 
		xVel = xVel; //make xvel a positive value
	}

//if enemys at left/right edge of screen or collided with left/right of tile
if( ( enemyCol.x < 0 ) || ( enemyCol.x + enemyCol.w > LEVEL_W) || ( tile_collision( enemyCol) ))
                {
		xVel = -xVel; //make xvel negative value
	}

	if( landed == true )
	{
                                //if we've landed, increase xpos by xvel
		enemyCol.x += xVel;
	}
So far it moves to the right and then when it collides with a tile, it moves back a few pixels, then moves right again, then back and forth. Some other methods are very similar to the current one, and all have the same result. Does this help you guys? It would be very appreciated if someone knew what im doing wrong. All i need it it to change direction when it collides with a tile
X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Enemy movement

Post by X Abstract X »

First a few minor things I noticed.

xVel = xVel; //make xvel a positive value
That does nothing, you're just setting the variable equal to itself. If xVel is negative it will remain negative.

You also have:
enemyCol.y -= yVel //stop moving
That will work okay in some cases but could leave gaps in between your objects. Consider a case like this:
Player height = 10
A wall at height = 13
A player yVelocity of 7
Your player will be sitting at a height of 10 after the collision when the wall is at a height of 13.

Also, you don't need to be checking collision if the monster isn't changing position. Depending on how you have other things working, this could be causing a problem. It should be rearranged like this:

Code: Select all

if (landed) {
    enemyCol.x += xVel;

    if ( (enemyCol.x < 0) || (enemyCol.x + enemyCol.w > LEVEL_W) || (tile_collision(enemyCol )
        xVel = -xVel;
}
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Enemy movement

Post by dandymcgee »

X Abstract X wrote:First a few minor things I noticed.

Code: Select all

xVel = xVel; //make xvel a positive value
That does nothing, you're just setting the variable equal to itself. If xVel is negative it will remain negative.
Also:

Code: Select all

xVel = -xVel; //make xvel negative value
This will indeed negate xVel, but will not necessarily make it negative.

To make xVel positive (getting absolute value):

Code: Select all

#include <math.h>
abs(xVel);

//OR

//If xVel is less than zero negate it, otherwise let it be
xVel = (xVel < 0) ? -xVel : xVel;
To make xVel negative:

Code: Select all

//If xVel is greater than zero negate it, otherwise let it be
xVel = (xVel > 0) ? -xVel : xVel;
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
PaperDuckyFTW
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 76
Joined: Sat Apr 03, 2010 5:08 am
Programming Language of Choice: C++

Re: Enemy movement

Post by PaperDuckyFTW »

ive tried all the ways you guys came up with but unfortunately nothing has worked. Im stumpt here as reading your posts made sence as to how it would work
X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Enemy movement

Post by X Abstract X »

Pastebin the entire source if it isn't too big and you still need help.
PaperDuckyFTW
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 76
Joined: Sat Apr 03, 2010 5:08 am
Programming Language of Choice: C++

Re: Enemy movement

Post by PaperDuckyFTW »

Thanks for your patience and help, and I hope this is what you means my post bin ^.^"
These are the relative codes:

Code: Select all

void Enemy::update_enemy()
{
	//set velocities
	yVel = 5;
	xVel = 1;

	//increase the y value (fall)
	enemyCol.y += yVel;

	//test to see if its landed
	bool landed = false;

	
	const int eFACE_LEFT = 0; //
	const int eFACE_RIGHT = 1;// Was testing another method
	int eFacing = eFACE_RIGHT;//

	if( xVel < 0 )
	{
		eFacing = eFACE_LEFT;
	}

	else if( xVel > 0 )
	{
		eFacing = eFACE_RIGHT;
	}

	

	//if collided with edge of screen or wall tile
	if( ( enemyCol.y < 0 ) || ( enemyCol.y + enemyCol.h > LEVEL_H ) || ( tile_collision( enemyCol ) ) )
	{
		//stop falling and allow enemy to move left/right
		enemyCol.y -= yVel;
		landed = true;	
		
	}

	
	//if we can move left/right
	if (landed) {
		//if we collided with wall, change direction
	    if ( (enemyCol.x < 0) || (enemyCol.x + enemyCol.w > LEVEL_W) || (tile_collision(enemyCol ) ) )
		    enemyCol.x = xVel -xVel;

		//move left/right
		enemyCol.x += xVel;
		}			
}

//then I have the enemy drawn after the player
luigi.update_player(); //move player
baddie.update_enemy(); //move enemy
If it would help and not be of too much inconvenience, I can upload the .exe and full source files.
Thanks if you can help and I hope it dont take too much of your time
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Enemy movement

Post by dandymcgee »

This is what he meant by pastebin:
http://pastebin.com/wC8h421H ;)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Enemy movement

Post by X Abstract X »

You have the line:

Code: Select all

enemyCol.x = xVel - xVel;
That is equivalent to setting enemyCol.x to 0. I don't think that's what you want to do, you want to negate xVel instead. That line should be replaced with:

Code: Select all

xVel = -xVel;
You have another problem aswell. Each time you update you reset the velocities to be positive, that's no good. You should set the velocities once in the object's constructor or in an initialize() function that is called only ONCE (not in your game loop).
PaperDuckyFTW
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 76
Joined: Sat Apr 03, 2010 5:08 am
Programming Language of Choice: C++

Re: Enemy movement

Post by PaperDuckyFTW »

:worship: :worship: :worship: :worship: :worship: :worship: :worship:

Thankyou soo soo much. The problem was what you said, I was setting the velocity or position to 0 repetativly in the game loop. I did as you suggested, initialised it in the constructor and so it solved my issue.

Thankyou evryone who helped and I hope it wasnt time consuming lol
Now i learned another thing about game loops, which will help me when Im making a state machine
Post Reply