Bouncing Ball Movement in a 2D Level
Update: The article A Better 2D Bouncing Ball Movement has a vastly improved algorithm for performing the 2D bouncing ball movement detailed in this article. You probably don't want to use the code below anymore (unless you love poor framerates). If you do and you get bad performance, don't say I didn't warn you.
In the game I am currently working on, I found the need to implement a bouncing ball type mechanic for a couple enemies. I essentially wanted some dumb enemies that bounce around the level as fodder for the player.
Searching online, I found tutorials on how to make a ball type object bounce when it leaves the limits of the playing area, but I needed my enemies to bounce whenever they hit into a block onscreen.
Unable to find a suitable tutorial online (and satisfied that if it wasn't in Google, it doesn't exist), I went about creating my own. My game is too big to post everything, so I'm just going to include
some snippets and walk through the logic of how it all
comes together.
First off, I've got a few constant variables (should they really still be called variables if they're constant?) that allow me to easily check things like moving up and down. I have these included in a sprite class
that all objects in my game inherit from.
public const int MOVE_UP = -1;
public const int MOVE_DOWN = 1;
public const int MOVE_LEFT = -1;
public const int MOVE_RIGHT = 1;
Now in my enemy class, I run the update function for each enemy during each game loop.
LevelBlocks is a collection of every block in my level (they're all 16x16 tiles) that is passed into this function and
Collision.checkLevelCollision() is a function that returns true if there is a collision between the levelBlocks and the vector position passed in.
Source is a rectangle that holds the size of the enemy. EnemyDirection is a vector2 that holds the direction of (gasp) the enemy.
public void Update(GameTime theGameTime, List<Block> levelBlocks)
{
Vector2 futurePosition = new Vector2();
if (currentState == enemyState.Active)
{
futurePosition = CurrentPosition;
futurePosition.Y += MOVE_UP * enemySpeed.Y;
if (Collision.checkLevelCollision(levelBlocks, futurePosition, source))
{
enemyDirection.Y = -enemyDirection.Y;
}
futurePosition = CurrentPosition;
futurePosition.Y += MOVE_DOWN * enemySpeed.Y;
if (Collision.checkLevelCollision(levelBlocks, futurePosition, source))
{
enemyDirection.Y = -enemyDirection.Y;
}
futurePosition = CurrentPosition;
futurePosition.X += MOVE_LEFT * enemySpeed.X;
if (Collision.checkLevelCollision(levelBlocks, futurePosition, source))
{
enemyDirection.X = -enemyDirection.X;
}
futurePosition = CurrentPosition;
futurePosition.X += MOVE_RIGHT * enemySpeed.
This article has been view 3833 times.
|