# bouncing bullets

• 09-13-2003
dydoko
bouncing bullets
IŽm developing a tilebased game and i have written some code to make bullets bounce, but it cant get i to work 100%. Do anyone f you guys have any experince of this kind of code? HereŽs the code and a picture that hopefully explains how i check when the bullet should bounce, i also included the game if you want to see how the bullet behaves.

Code:

```void CBullets::Update() {         float tempX, tempY, factor;         int tx, ty, lo, lo2;         int xx[4], yy[4], type[4];         bool deleted, left, right, upp, ner;         bool bouncedX, bouncedY;         // Loop through all bullets         for (lo = bullets.size()-1; lo >= 0; lo--) {                 deleted = left = right = up = down = bouncedX = bouncedY = false;                 type[0] = type[1] = type[2] = type[3] = -1;                                 // Save bullet position before moving it                 tempX = bullets[lo].x;                 tempY = bullets[lo].y;                 // Move bullet                 bullets[lo].x += cos_360[ bullets[lo].direction ] * bulletProperties[ bullets[lo].typ ].speed * time;                 bullets[lo].y -= sin_360[ bullets[lo].direction ] * bulletProperties[ bullets[lo].typ ].speed * time;                                 // Did it move to the left or to the right                 if ( bullets[lo].x < tempX ) {                         left = true;                         factor = -1.0;                 } else if ( bullets[lo].x > tempX ) {                         right = true;                         factor = 1.0;                 }                 // If it moved to the left or to the right caluclate control points                 if (left || right) {                         // Tile in the upper left/right corner, control point 1 (see picture)                         xx[0] = (bullets[lo].x + bulletProperties[ bullets[lo].type ].halfWidth * factor) / tilemap->TileWidth();                         yy[0] = (tempY - kulBesk[ bullets[lo].typ ].halfHeight) / tilemap->TileHeight();                         type[0] = tilemap->pTileArray()[ yy[0] ][ xx[0] ].tile;                                                 // Tile in the lower left/right corner, control point 2 (see picture)                         xx[1] = (bullets[lo].x + bulletProperties[ bullets[lo].type ].halfWidth * factor) / tilemap->TileWidth();                         yy[1] = (tempY + kulBesk[ bullets[lo].typ ].halfHeight) / tilemap->TileHeight();                         type[1] = tilemap->pTileArray()[ yy[1] ][ xx[1] ].tile;                        }                 // Did it move up or down                 if (bullets[lo].y < tempY) {                         up = true;                         factor = -1.0;                 } else if (bullets[lo].y > tempY) {                         down = true;                         factor = 1.0;                 }                 if (up || down) {                         // Tile in the left upper/lower corner, control point 3 (see picture)                         xx[2] = (tempX - bulletProperties[ bullets[lo].typ ].halfWidth) / tilemap->TileWidth();                         yy[2] = (bullets[lo].y + bulletProperties[ bullets[lo].typ ].halfHeight * factor) / tilemap->TileHeight();                         type[2] = tilemap->pTileArray()[ yy[2] ][ xx[2] ].tile;                                                 // Tile in the right upper/lower corner, control point 4 (see picture)                         xx[3] = (tempX + bulletProperties[ bullets[lo].typ ].halfWidth) / tilemap->TileWidth();                         yy[3] = (bullets[lo].y + bulletProperties[ bullets[lo].typ ].halfHeight * factor) / tilemap->TileHeight();                         type[3] = tilemap->pTileArray()[ yy[3] ][ xx[3] ].tile;                        }                 // Step through the tiles that the bullets collides/passes                 for ( lo2 = 0; lo2 < 3; lo2++ ) {                         if ( type[lo2] > -1 ) {                                 // Obstacle, remove or bounce                                 if ( tilemap->pTileProperties()[ type[lo2] ].obstacle ) {                                                                                 // The bullet doesnt bounce, delete it and exit loop                                         if ( !bulletProperties[ bullets[lo].type ].bouncing ) {                                                 deleted = true;                                                 bullets.erase( &bullets.at(lo) );                                                 break;                                                                                 // A bouncing bullet                                         } else {                                                 // Tiles before the bullet was moved                                                 tx = tempX / tilemap->TileWidth();                                                 ty = tempY / tilemap->TileHeight();                                                                                                 // Y                                                 if ( ty != yy[lo2] ) {                                                         bullets[lo].direction = 359 - bullets[lo].direction;                                                         ++bullets[lo].bounces;                                                                                                 // X                                                 } else if ( tx != xx[lo2] ) {                                                         bullets[lo].direction = 180 - bullets[lo].direction;                                                         if ( bullets[lo].direction < 0 ) bullets[lo].direction += 360;                                                         ++bullets[lo].bounces;                                                 }                                                                                                                                                 // "Reset" position so that i doesnt get stuck in the wall                                                 bullets[lo].x = tempX;                                                 bullets[lo].y = tempY;                                                 break;                                         }                                 }                         }                 }                 // The bullet has bounced maximum nr of times, delete it                 if ( bullets[lo].bounces > bulletProperties[ bullets[lo].typ ].maxBounces ) {                         deleted = true;                         bullets.erase( &bullets.at(lo) );                 // Draw bullet if it wans deleted                 } else if ( !deleted ) {                         ....draw bullet...                 }         } }```
http://student.itn.liu.se/~mikgu166/temp/bullet.gif
tegame.zip (346k)
• 09-13-2003
confuted
Hmmm... I didn't read all the code, and the diagram was a bit confusing. Are you trying to have a bullet "bounce" like a ball would off the wall in a Pong game, or are you trying to do something more "kid-ish" where the bullet will bounce off in some sort of smooth curve?
• 09-13-2003
dydoko
The balls are bouncing as a ball in a pong-game, but when the ball hits a wall to its left/right it "sometimes" doesnt bounce, try the game and youŽll see what i mean
• 09-13-2003
confuted
Quote:

Originally posted by pheer
The balls are bouncing as a ball in a pong-game, but when the ball hits a wall to its left/right it "sometimes" doesnt bounce, try the game and youŽll see what i mean
Can you post a link to the game? :p

Until then... is the problem in the collision detection (it doesn't detect a collision with the wall), or is the problem in the math to make it bounce?
• 09-13-2003
dydoko
the link is up therem, under the link to the confusing diagram :p
its the colission detection that doesnt work, i think its only when the middle of the ball (y) hits where one tile meets another
• 09-17-2003
VirtualAce
Bouncing can be done easily by:

if (ball.x<=left) ball.xvel=-ball.xvel;
if (ball.x>=right) ball.xvel=-ball.xvel;
if (ball.y<=top) ball.yvel=-ball.yvel;
if (ball.y>=bottom) ball.yvel=-ball.yvel;

This does not take into account angles and will not always produce the desired results. But its a lot less code and produces decent results.

For angles, create a triangle out of the ball bouncing. The base of the tri is the distance the ball traveled in X, and the height of the tri is the distance in Y. Unfortunately the hypotenuse requires the use of the oh so slow sqrt(), but you can get around this using a Taylor-series expansion - which may or may not be faster in certain cases. You must store the initial x,y of your ball and the final x,y of your ball to create each tri. When the ball bounces - store the initial again and wait for the ball to hit another side to get the final.
• 09-17-2003
dydoko
I know how to bounce a ball on the screen, but bouncing it in a "tiled environment" is a little more complex than that, atleast i think so
• 09-17-2003
VirtualAce
Why would that be harder??

I'm lost.
• 09-18-2003
frenchfry164
The logic for projectiles should be exactly identical for all 2D games. If you make the projectiles work only within tiles, it won't be that flexible.

Actually, it could be a little simpler in a tiled environment for the collision detection, if you don't care about getting everything precisely accurate.