Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

brunogmd

Collisions --> Allegro --> Pong

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

Hi..im making a pong game with allegro.But Im having problems with collision detection (Im using bounding box). The problem is that when the ball hits one of the corners of the pad1 or pad2 it falls through the pad (with no collision at all). I would like to know what I am doing wrong.

while (!key[KEY_ESC])

	{

		while (Counter > 0)

		{

			Ball.PosY +=Ball.Speed*Ball.vy;
	        Ball.PosX +=Ball.Speed*Ball.vx;

			ComputePlayers ();

            // Player 1 //////////////////////////////////////////////////////////////////////

			if ( ((Ball.PosX >= Player1.PosX) && (Ball.PosX <= Player1.PosX+Player1.map->w)) &&
				 ((Ball.PosY >= Player1.PosY ) && (Ball.PosY <= Player1.PosY+Player1.map->h)) )

			{

				Ball.vx = -Ball.vx;

			}

			if ( (Ball.PosX >= Player1.PosX) &&
				 (Ball.PosX <= (Player1.PosX + Player1.map->w)) &&
				 (Ball.PosY <= (Player1.PosY + Player1.map->h)) &&
				 (Ball.PosY >= Player1.PosY) )

			{

				Ball.vy = -Ball.vy;

			}




			///////////////////////////////////////////////////////////////////////////////////

			if ( (((Ball.PosX+Ball.map->w) >= Player2.PosX) && ((Ball.PosX+Ball.map->w) <= Player2.PosX+Player2.map->w)) &&
				 ((Ball.PosY >= Player2.PosY ) && (Ball.PosY <= Player2.PosY+Player2.map->h)) )

			{

				Ball.vx = -Ball.vx;

			}

			// We test for player 1 coordinates
			if (key[KEY_W])
			Player1.PosY-=4;

			if (key[KEY_S])
			Player1.PosY+=4;

			// We test for player 2 coordinates
			if (key[KEY_8_PAD])
				Player2.PosY-=4;

			if (key[KEY_5_PAD])
				Player2.PosY+=4;

			


			Counter--;

		}

		vsync ();
		masked_blit (Player1.map,Buffer,0,0,Player1.PosX,Player1.PosY,23,63);
		masked_blit (Player2.map,Buffer,0,0,Player2.PosX,Player2.PosY,23,63);
		masked_blit (Ball.map,Buffer,0,0,Ball.PosX,Ball.PosY,32,32);
		textprintf (Buffer,font,8,8,makecol (255,255,255),"Player 1 Score: %d",Player1Score);
		textprintf (Buffer,font,174,8,makecol (255,255,255),"Player 2 Score: %d",Player2Score);
		blit (Buffer,screen,0,0,0,0,320,200);
		clear(Buffer);
		

	}

 
Thanks

Share this post


Link to post
Share on other sites
Advertisement
well what is your player position, is it the center of the paddle, the top or bottom of a paddle? that will change how you do the detection with your algorithm, for example playerY + map height might detect wrongly if your playerY isnt the bottom coord for your bounding box. id suggest making a rectangle structure like this one:

struct Rect
{
int x,y,x2,y2;
bool collision(const Rect &obj)
{
return( (Rect.x >= this.x)&&
(Rect.y <= this.y)&&
(Rect.x2 >= this.x2)&&
(Rect.y2 <= this.y2) )
}
};

then give each object that needs detection a Rect member and maintain proper coordinate maintaince ( ie making sure the bound box''s X and Y are the same X and Y of the bitmap your rendering)

Share this post


Link to post
Share on other sites
I wish you posted something that actually compiled. I starte filling in the missing pieces, then I started changing your code, and in the end I ended up with something completely different and I never figured out what was wrong with your code.

Anyway, this is what I ended up with:

#include <allegro.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

struct entity
{
float PosX, PosY, vx, vy;
BITMAP *map;
};

void Update(struct entity *e, int friction)
{
e->PosX += e->vx;
e->PosY += e->vy;

if(friction)
{
e->vx *= 0.99;
e->vy *= 0.99;

if(e->PosY < 0)
e->vy = fabs(e->vy)*0.7;
else if(e->PosY + e->map->h > SCREEN_H)
e->vy = -fabs(e->vy)*0.7;
}
else
{
if(e->PosY < 0)
e->vy = fabs(e->vy);
else if(e->PosY + e->map->h > SCREEN_H)
e->vy = -fabs(e->vy);
}
}

void ResetBall(struct entity *b)
{
b->PosX = SCREEN_W/2-b->map->w/2;
b->PosY = SCREEN_H/2-b->map->h/2;
b->vx = ((rand()%2)?1:-1)*(rand()/(float)RAND_MAX+1.3);
b->vy = rand()/(float)RAND_MAX*2.0-1.0;
}

int main(int argc, char *argv[])
{
srand(time(0));
allegro_init();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);
install_keyboard();

struct entity Ball, Player1, Player2;
int Player1Score = 0, Player2Score = 0;

Ball.map = create_bitmap(17, 17);
clear_to_color(Ball.map, MASK_COLOR_32);
circlefill(Ball.map, 8, 8, 8, makecol(255, 255, 255));
ResetBall(&Ball);

Player1.map = create_bitmap(16, 64);
clear_to_color(Player1.map, makecol(255, 0, 0));
rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);
Player1.PosX = 0;
Player1.PosY = SCREEN_H/2-16;
Player1.vx = Player1.vy = 0;

Player2.map = create_bitmap(16, 64);
clear_to_color(Player2.map, makecol(0, 0, 255));
rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);
Player2.PosX = SCREEN_W-16;
Player2.PosY = SCREEN_H/2-16;
Player2.vx = Player2.vy = 0;

while(!key[KEY_ESC])
{
Update(&Ball, 0);
Update(&Player1, 1);
Update(&Player2, 1);

// Player 1

if(Ball.vx < 0 && Ball.PosX < Player1.PosX+Player1.map->w)
{
if(Ball.PosY >= Player1.PosY - Ball.map->h && Ball.PosY <= Player1.PosY + Player1.map->h)
{
Ball.vx *= -1;
Ball.vy += Player1.vy;
}
else
{
ResetBall(&Ball);
++Player2Score;
}
}

// Player 2

if(Ball.vx > 0 && Ball.PosX + Ball.map->w > Player2.PosX)
{
if(Ball.PosY >= Player2.PosY - Ball.map->h && Ball.PosY <= Player2.PosY + Player2.map->h)
{
Ball.vx *= -1;
Ball.vy += Player2.vy;
}
else
{
ResetBall(&Ball);
++Player1Score;
}
}

if(key[KEY_W])
Player1.vy -= 0.1;

if(key[KEY_S])
Player1.vy += 0.1;

if(key[KEY_8_PAD])
Player2.vy -= 0.1;

if(key[KEY_5_PAD])
Player2.vy += 0.1;

vsync();
clear(Buffer);
masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);
masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);
masked_blit(Ball.map, Buffer, 0, 0, Ball.PosX, Ball.PosY, Ball.map->w, Ball.map->h);
textprintf(Buffer, font, 8, 8, makecol(255,255,255), "Player 1 Score: %d", Player1Score);
textprintf(Buffer, font, 174, 8, makecol(255,255,255), "Player 2 Score: %d", Player2Score);
blit(Buffer,screen,0,0,0,0,SCREEN_W, SCREEN_H);
}

allegro_exit();
} END_OF_MAIN();


[edited by - smart_idiot on June 4, 2004 6:47:00 AM]

Share this post


Link to post
Share on other sites
Oh, and just for fun, try adding ''e->vy += 0.05;'' to the start of the Update function. Gravity makes things a little harder, don''t you think?

Share this post


Link to post
Share on other sites
Still playing around. Look, multiple balls!




#include <allegro.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

#define BALLS 5

struct entity
{
float PosX, PosY, vx, vy;
BITMAP *map;
};

void Update(struct entity *e, int friction)
{
e->PosX += e->vx;
e->PosY += e->vy;

if(friction)
{
e->vx *= 0.99;
e->vy *= 0.99;

if(e->PosY < 0)
e->vy = fabs(e->vy)*0.7;
else if(e->PosY + e->map->h > SCREEN_H)
e->vy = -fabs(e->vy)*0.7;
}
else
{
if(e->PosY < 0)
e->vy = fabs(e->vy);
else if(e->PosY + e->map->h > SCREEN_H)
e->vy = -fabs(e->vy);
}
}

void ResetBall(struct entity *b)
{
b->PosX = SCREEN_W/2-b->map->w/2;
b->PosY = SCREEN_H/2-b->map->h/2;
b->vx = ((rand()%2)?1:-1)*(rand()/(float)RAND_MAX+1.3);
b->vy = rand()/(float)RAND_MAX*2.0-1.0;
}

int main(int argc, char *argv[])
{
srand(time(0));
allegro_init();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);
install_keyboard();

struct entity Ball[BALLS], Player1, Player2;
int Player1Score = 0, Player2Score = 0;

int i;

for(i = 0; i < BALLS; ++i)
{
Ball[i].map = create_bitmap(17, 17);
clear_to_color(Ball[i].map, MASK_COLOR_32);
circlefill(Ball[i].map, 8, 8, 8, makecol(128+rand()%127, 128+rand()%127, 128+rand()%127));
ResetBall(Ball+i);
}

Player1.map = create_bitmap(16, 64);
clear_to_color(Player1.map, makecol(255, 0, 0));
rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);
Player1.PosX = 0;
Player1.PosY = SCREEN_H/2-16;
Player1.vx = Player1.vy = 0;

Player2.map = create_bitmap(16, 64);
clear_to_color(Player2.map, makecol(0, 0, 255));
rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);
Player2.PosX = SCREEN_W-16;
Player2.PosY = SCREEN_H/2-16;
Player2.vx = Player2.vy = 0;

while(!key[KEY_ESC])
{
Update(&Player1, 1);
Update(&Player2, 1);

for(i = 0; i < BALLS; ++i)
{
Update(Ball+i, 0);

if(Ball[i].vx < 0 && Ball[i].PosX < Player1.PosX+Player1.map->w)
{
if(Ball[i].PosY >= Player1.PosY - Ball[i].map->h && Ball[i].PosY <= Player1.PosY + Player1.map->h)
{
Ball[i].vx *= -1;
Ball[i].vy += Player2.vy;
}
else
{
ResetBall(Ball+i);
++Player2Score;
}
}

// Player 2

if(Ball[i].vx > 0 && Ball[i].PosX + Ball[i].map->w > Player2.PosX)
{
if(Ball[i].PosY >= Player2.PosY - Ball[i].map->h && Ball[i].PosY <= Player2.PosY + Player2.map->h)
{
Ball[i].vx *= -1;
Ball[i].vy += Player2.vy;
}
else
{
ResetBall(Ball+i);
++Player1Score;
}
}
}

if(key[KEY_W])
Player1.vy -= 0.17;

if(key[KEY_S])
Player1.vy += 0.17;

if(key[KEY_8_PAD])
Player2.vy -= 0.17;

if(key[KEY_5_PAD])
Player2.vy += 0.17;

vsync();
clear(Buffer);
masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);
masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);

for(i = 0; i < BALLS; ++i)
masked_blit(Ball[i].map, Buffer, 0, 0, Ball[i].PosX, Ball[i].PosY, Ball[i].map->w, Ball[i].map->h);

textprintf(Buffer, font, 8, 8, makecol(255,255,255), "Player 1 Score: %d", Player1Score);
textprintf(Buffer, font, 174, 8, makecol(255,255,255), "Player 2 Score: %d", Player2Score);
blit(Buffer,screen,0,0,0,0,SCREEN_W, SCREEN_H);
}

allegro_exit();
} END_OF_MAIN();

Share this post


Link to post
Share on other sites
I added AI just for no apparent reason.


#include <allegro.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

struct entity
{
float PosX, PosY, vx, vy;
BITMAP *map;
};

void Update(struct entity *e, int friction)
{
if(friction)
{
if(e->PosY < 0)
e->vy = fabs(e->vy)*0.7;
else if(e->PosY + e->map->h >= SCREEN_H)
e->vy = -fabs(e->vy)*0.7;

e->PosX += (e->vx *= 0.99);
e->PosY += (e->vy *= 0.99);
}
else
{
if(e->PosY < 0)
e->vy = fabs(e->vy);
else if(e->PosY + e->map->h >= SCREEN_H)
e->vy = -fabs(e->vy);

e->PosX += e->vx;
e->PosY += e->vy;
}
}

void ResetBall(struct entity *b)
{
if(rand()%2)
{
b->vx = rand()/(float)RAND_MAX+4.3;
b->PosX = 0;
}
else
{
b->vx = -rand()/(float)RAND_MAX-4.3;
b->PosX = SCREEN_W-b->map->w;
}

b->vy = rand()/(float)RAND_MAX*4.0-2.0;
b->PosY = SCREEN_H/2-b->map->h/2;
}

int main(int argc, char *argv[])
{
srand(time(0));
allegro_init();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT, 320, 240, 0, 0);
BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);
install_keyboard();

struct entity Ball, Player1, Player2;
int Player1Score = 0, Player2Score = 0;
int Player1Computer = 1, Player2Computer = 1;

Ball.map = create_bitmap(9, 9);
clear_to_color(Ball.map, MASK_COLOR_32);
circlefill(Ball.map, 4, 4, 4, makecol(255, 255, 255));
ResetBall(&Ball);

Player1.map = create_bitmap(16, 64);
clear_to_color(Player1.map, makecol(255, 0, 0));
rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);
Player1.PosX = 0;
Player1.PosY = SCREEN_H/2-16;
Player1.vx = Player1.vy = 0;

Player2.map = create_bitmap(16, 64);
clear_to_color(Player2.map, makecol(0, 0, 255));
rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);
Player2.PosX = SCREEN_W-16;
Player2.PosY = SCREEN_H/2-16;
Player2.vx = Player2.vy = 0;

while(!key[KEY_ESC])
{
Update(&Ball, 0);
Update(&Player1, 1);
Update(&Player2, 1);

if(Ball.vx < 0 && Ball.PosX < Player1.PosX+Player1.map->w)
{
if(Ball.PosY >= Player1.PosY - Ball.map->h && Ball.PosY <= Player1.PosY + Player1.map->h)
{
Ball.vx *= -1;
Ball.vy += Player1.vy;
}
else
{
ResetBall(&Ball);
++Player2Score;
}
}

if(Ball.vx > 0 && Ball.PosX + Ball.map->w > Player2.PosX)
{
if(Ball.PosY >= Player2.PosY - Ball.map->h && Ball.PosY <= Player2.PosY + Player2.map->h)
{
Ball.vx *= -1;
Ball.vy += Player2.vy;
}
else
{
ResetBall(&Ball);
++Player1Score;
}
}

if(key[KEY_W])
{
Player1.vy -= 0.17;
Player1Computer = 0;
}

if(key[KEY_S])
{
Player1.vy += 0.17;
Player1Computer = 0;
}

if(key[KEY_8_PAD])
{
Player2.vy -= 0.17;
Player2Computer = 0;
}

if(key[KEY_5_PAD])
{
Player2.vy += 0.17;
Player2Computer = 0;
}

if(Ball.vx > 0)
{
if(Player2Computer)
{
float predicted_time = (SCREEN_W-Player2.map->w-Ball.map->w-Ball.PosX)/Ball.vx, predicted_y = Ball.PosY + Ball.vy*predicted_time;

while(predicted_y < 0 || predicted_y > SCREEN_H-Ball.map->h)
if(predicted_y < 0)
predicted_y = 1-predicted_y;
else
predicted_y = 2*(SCREEN_H-Ball.map->h)-predicted_y;

if(Player2.PosY + Player2.vy * predicted_time - Ball.map->h/2 + Player2.map->h/2 > predicted_y)
Player2.vy -= 0.17;
else
Player2.vy += 0.17;
}

if(Player1Computer)
{
if(Player1.vy < 1 && Player1.PosY < (SCREEN_H-Player1.map->h)/3)
Player1.vy += 0.17;
else if(Player1.vy > -1 && Player1.PosY > (SCREEN_H-Player1.map->h)*2/3)
Player1.vy -= 0.17;
}
}
else
{
if(Player1Computer)
{
float predicted_time = (Ball.PosX-Player2.map->w)/-Ball.vx, predicted_y = Ball.PosY + Ball.vy*predicted_time;

while(predicted_y < 0 || predicted_y > SCREEN_H-Ball.map->h)
if(predicted_y < 0)
predicted_y = 1-predicted_y;
else
predicted_y = 2*(SCREEN_H-Ball.map->h)-predicted_y;


if(Player1.PosY + Player1.vy * predicted_time - Ball.map->h/2 + Player1.map->h/2 > predicted_y)
Player1.vy -= 0.17;
else
Player1.vy += 0.17;
}

if(Player2Computer)
{
if(Player2.vy < 1 && Player2.PosY < (SCREEN_H-Player2.map->h)/3)
Player2.vy += 0.17;
else if(Player2.vy > -1 && Player2.PosY > (SCREEN_H-Player2.map->h)*2/3)
Player2.vy -= 0.17;
}
}


masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);
masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);
masked_blit(Ball.map, Buffer, 0, 0, Ball.PosX, Ball.PosY, Ball.map->w, Ball.map->h);
textprintf(Buffer, font, 0, 0, makecol(255,255,255), "%s: %d", Player1Computer?"Computer":"Human", Player1Score);
textprintf_right(Buffer, font, SCREEN_W-1, 0, makecol(255,255,255), "%s: %d", Player2Computer?"Computer":"Human", Player2Score);
vsync();
blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
clear(Buffer);
}

allegro_exit();
} END_OF_MAIN();

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!