Page 1 of 1
Enemy movement
Posted: Wed Jul 14, 2010 3:16 am
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
Re: Enemy movement
Posted: Wed Jul 14, 2010 3:25 am
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;
Re: Enemy movement
Posted: Wed Jul 14, 2010 4:04 am
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.
Re: Enemy movement
Posted: Wed Jul 14, 2010 11:11 am
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;
Re: Enemy movement
Posted: Wed Jul 14, 2010 11:33 am
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
Re: Enemy movement
Posted: Wed Jul 14, 2010 12:47 pm
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).
Re: Enemy movement
Posted: Sat Jul 24, 2010 2:21 am
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
Re: Enemy movement
Posted: Sat Jul 24, 2010 4:36 am
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;
}
Re: Enemy movement
Posted: Sat Jul 24, 2010 9:45 am
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;
Re: Enemy movement
Posted: Tue Jul 27, 2010 3:25 am
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
Re: Enemy movement
Posted: Tue Jul 27, 2010 5:00 am
by X Abstract X
Pastebin the entire source if it isn't too big and you still need help.
Re: Enemy movement
Posted: Wed Jul 28, 2010 8:05 am
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
Re: Enemy movement
Posted: Wed Jul 28, 2010 12:17 pm
by dandymcgee
This is what he meant by pastebin:
http://pastebin.com/wC8h421H
Re: Enemy movement
Posted: Wed Jul 28, 2010 12:32 pm
by X Abstract X
You have the line:
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:
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).
Re: Enemy movement
Posted: Wed Jul 28, 2010 7:12 pm
by PaperDuckyFTW