Jump to content
  • Advertisement
Sign in to follow this  
ravinDavin

Cant get obstacle collision to work. PLEASE HELP

This topic is 2592 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

I have spent more hours than I care to admit on this. It has gotten to the point that I am confused as to what the hell I am doing. I have an Obstacle class in my game, which first checks if it is on screen, then it checks if it is in the same sector as the player, then it does a rectangle test, and then a pixel perfect test.

I am using projected rectangles to for the rectangle and pixel tests. If pixels collide then I set a player.COLLIDED = true;

It works, as in it stops the player from moving. But it gets him stuck there! You can't move away from the collision being true. I thought when I was doing the projected rectangles, it would work like: if the player WILL collide, then dont let him move. But now that I think about it, it will just do the same thing as a normal bounds check. Unless you push the player back or something.

Also, When I jump on top of it, it gets stuck aswell, I have to keep jumping to get over it. I am 100% sure I am missing something simple. Here is the 2 update methods from the Obstacle and Player class:

PLAYER CLASS:
public override void Update(GameTime gameTime)
{


float elapsed = gameTime.ElapsedGameTime.Milliseconds;
this.totalElapsed += elapsed;
bMoving = false;
direction = Vector2.Zero;
if (!GLOBALS.bGAMEOVER)
{
if (health < 0)
isDead = true;


#region DEATH LOGIC
if (isDead)
{
bAnimate = true;
if (!FxPlayed)
{
deathEffect.Play();
FxPlayed = true;
}
timeDead += elapsed;
sprite.setAnimation(2, false);
sprite.sprColor = Color.White;

if (sprite.animHandle.ANIM_FINISHED && timeDead > 2000 && lives > 0)
{

isDead = false;
resetPlayer();
timeDead = 0;
}
else if (lives == 0)
{
GLOBALS.bGAMEOVER = true;
isDead = false;
// noLives.Play();
}






}
#endregion
else
{







UpdateMovement(gameTime);
sprite.setAnimFrame(1);
UpdateMouseActions(elapsed);




projectedBounds = new Rectangle((int)((position.X - translatedOriginX)+direction.X),
(int)((position.Y - translatedOriginY) + direction.Y), Width, Height);

//DIDN'T WORK EITHER
/* foreach (Entity ent in entManager.ENTLIST)
{
Entity temp;
if (ent.GetType().Equals(typeof(Obstacle)))
{
temp = (Obstacle)ent;
if (Collision.IntersectsBSP(temp.sprite, sprite))
{
if (temp.projectedBounds.Intersects(projectedBounds))
{

if (Collision.IntersectsAA(temp.sprite.getTextureColorData(), sprite.getTextureColorData(), temp.projectedBounds, player.projectedBounds))
{
bCollision = true;

}
}
}
}
}*/

if (game.keyboardManager.NEWSTATE.IsKeyDown(Keys.D) && !bCollision && position.X + sprite.Width == GLOBALS.SCREENWIDTH/2)
{

bMoving = true;
GLOBALS.camera.X += (int)GLOBALS.SCROLLSPEED;
}

else if (!bCollision && !bMoving)
POSITION += direction * speed * gameTime.ElapsedGameTime.Milliseconds * 0.125f;




UpdateJump(gameTime);
//reset each loop so it flashes(for low health effect)
sprite.sprColor = Color.White;

//Low health effect
#region LOW HEALTH
heartBeat += elapsed;
if ((health < 30) && (health > 15))
{
sprite.sprColor = Color.White;
if (heartBeat > 700)
{
Resources.Characters.Sounds.lowHealthFX.Play();
sprite.sprColor = Color.Red;
heartBeat = 0;
}
}
else if (health <= 15)
{
sprite.sprColor = Color.White;
if (heartBeat > 400)
{
Resources.Characters.Sounds.lowHealthFX.Play();
sprite.sprColor = Color.Red;
heartBeat = 0;
}

}
#endregion

}
}
else
{

if (totalElapsed > 4000)
{
GLOBALS.bPAUSED = true;

}

}


bCollision = false;

game.mouseManager.setOldState();
game.keyboardManager.setOldState();

base.Update(gameTime);
}


Obstacle Class:
public override void Update(GameTime gameTime)
{

projectedBounds = new Rectangle((int)((position.X - translatedOriginX) - (GLOBALS.SCROLLSPEED)),
(int)(position.Y - translatedOriginY), Width, Height);


if (Collision.IntersectsBSP(this.projectedBounds, player.projectedBounds))
{

if (Collision.Intersects(this.projectedBounds, player.projectedBounds))
{
if (Collision.IntersectsAA(sprite.getTextureColorData(), player.sprite.getTextureColorData(), this.projectedBounds, player.projectedBounds))
{
player.COLLIDED = true;

}
}
}

base.Update(gameTime);
}

Share this post


Link to post
Share on other sites
Advertisement
Whats happening is exactly what you said it is. You get inside the rectangle and since you will always stop the movement you can't get out. You can fix this just like you said by either pushing your guy outside the box. (Shouldn't be that hard if you use Force Vectors originating from the rectangle). Or you could check for the collision before the movement actually takes place.

Also good luck!

Share this post


Link to post
Share on other sites
I did try to do the collision test before the movement took place, that was the bit in the player class where I commented out "DIDN't WORK EITHER". But since the collision was always true I couldnt move anyway. I guess thats the thing that is confusing me now.

Maybe I should say, my player only actually physically moves up until the centre of the screen, after that, if you hold "D", everything else will move towards the player. Will this be somehow messing up the projected bounds?

Share this post


Link to post
Share on other sites
Are you checking collision with the current frame of the players sprite or do you use a non-changing image. If the image you use for collision detection changes than this could be causing the problem. An example.

I walk to the right until I collide with the wall. I let go of the arrow key, I am not colliding with the wall but am just right up against it. I go to the left, the image changes but to an image that is overlapping with the wall now. Because of the overlap I cannot move.

Looking through what you have posted I don't see the collision detection problem.

Share this post


Link to post
Share on other sites
A solution that is simple to implement and suitable for small games is to simply store the last position of the player that was not colliding with anything, and when collision is detected move the player back to that position.


L. Spiro

Share this post


Link to post
Share on other sites
You've explained what you have working. My question is, what do you expect the result of a collision to be? You have the difficult part down, it seems, finding when a collision happens. But the program is not going to do anything that you don't tell it to do. Do you want collisions to bounce the player, or just block his movement? Should he be able to slide along the wall if you push him into the wall at an angle? I'll admit I haven't looked closely at the code, so I'm not sure if you've limited the direction that a player can move in in any way. But I think you should first describe in detail what you actually expect as a result, and the way to do it will be that much clearer.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!