Page 1 of 2

(Allegro Collision Problem) Now my first 2d Game!

Posted: Mon Mar 08, 2010 5:37 pm
by mv2112
I cant figure out what is wrong. I am making a pong clone using allegro. I can bounce the ball of the player's racket but not the computer's.
Here is the code:

Code: Select all


#define USE_CONSOLE
#include <allegro.h>
#include <mvTIMER_a.h>
#include <stdio.h>
#include <stdlib.h>

const static int screen_x=1440;
const static int screen_y=900;

class ball
{
public:
	void physics(int x, int y1, int y2, int test);
	void draw();
	void move();
	ball(int rad);
	bool gameon;

	int x; //x coordinate
	int y; //y coordinate
	int r; //radius
	int oldx;
	int oldy;
	int dirx; //x's direction
	int diry; //y's direction
};

ball::ball(int rad)
{
	r=rad;
	x=700;
	y=500;
	dirx=-1;
	gameon=true;
	diry=(rand()%1);
	if(dirx==0)
	{
		dirx=-1;
	}
	if(diry==0)
	{
		diry=-1;
	}
}

void ball::move()
{
	oldx=x;
	oldy=y;
	x+=r*dirx;
	y+=r*diry;
}

void ball::physics(int px, int y1, int y2, int test)
{

	if(test==1&&x-(r)==px&&(y<=y2+r&&y>=y1-r))
	{
		dirx=1;
	}

	
	if(test==2&&x-(r)==px&&(y<=y2+r&&y>=y1-r)) //this should check the collision for the computer player. This also might be whats wrong.
	{
		dirx=-1;
	}

	if(x>=screen_x-r)
	{
		dirx=-1;
	}

	if(x<=0+r)
	{
		dirx=1;
	}

	if(y>=screen_y-r)
	{
		diry=-1;
	}

	if(y<=0+r)
	{
		diry=1;
	}
}


void ball::draw()
{
	circlefill(screen,oldx,oldy,r,makecol(0,0,0));
	circlefill(screen,x,y,r,makecol(255,255,255));

}

int main()
{
	allegro_init();
	install_keyboard();
	set_gfx_mode(GFX_AUTODETECT,screen_x,screen_y,0,0);
//AI
	int aix=1240;
	int aiy=100;
	int aixx=aix-25;
	int aiyy=aiy-150;
//Player
	int x=200;
	int y=100;
	int xx=x-25;
	int yy=y-150;
	ball b(25);

	acquire_screen();

	while(!key[KEY_ESC])
	{
		if(b.y>aiy)
		{
			rectfill(screen,aix,aiy,aixx,aiyy,makecol(0,0,0));
			aiy+=25;
			aiyy=aiy-150;
			rectfill(screen,aix,aiy,aixx,aiyy,makecol(255,255,255));
		}

		if(b.y<aiy)
		{
			rectfill(screen,aix,aiy,aixx,aiyy,makecol(0,0,0));
			aiy-=25;
			aiyy=aiy-150;
			rectfill(screen,aix,aiy,aixx,aiyy,makecol(255,255,255));
		}

		if(key[KEY_DOWN])
		{
			rectfill(screen,x,y,xx,yy,makecol(0,0,0));
			y+=30;
			yy=y-150;
			rectfill(screen,x,y,xx,yy,makecol(255,255,255));
		}

		if(key[KEY_UP])
		{
			rectfill(screen,x,y,xx,yy,makecol(0,0,0));
			y-=30;
			yy=y-150;
			rectfill(screen,x,y,xx,yy,makecol(255,255,255));
		}
		b.move();
		b.physics(x,yy,y,1); //check for collision against player
		b.physics(aix,aiy,aiyy,2); //check for collision agains opponent. I have no idea why this isnt working.
		rectfill(screen,x,y,xx,yy,makecol(255,255,255));
		b.draw();

		if(b.gameon==false)
		{
			return 0;
		}
		timer(30);

	}

}
END_OF_MAIN();
I cant figure out what is actually wrong with the code. Im guessing that i am checking wrong in the 2nd if statement in the ball::physics function.
Oh, if you plan on running this on your computer, you should probably change the:

Code: Select all


const static int screen_x=1440; //to your screen res
const static int screen_y=900;

int aix=1240; // and make this lower


Re: Allegro Collision Problem

Posted: Tue Mar 09, 2010 3:05 am
by krilik

Code: Select all

b.physics(aix,aiy,aiyy,2);
You have your y values mixed up when you call the function. Should be:

Code: Select all

b.physics(aix,aiyy,aiy,2);
Edit: Also just fyi, during the check for the AI collision

Code: Select all

if(test==2&&x-(r)==px&&(y<=y2+r&&y>=y1-r)) //this should check the collision for the computer player. This also might be whats wrong.
   {
      dirx=-1;
   }
You should add the radius of the ball to the ball x position instead of subtract otherwise the ball will pass through the computer's paddle.

Re: Allegro Collision Problem

Posted: Tue Mar 09, 2010 6:57 pm
by mv2112
Ugh, my code is too sloppy, i lost track of variables. I think im going to re-write what code i have much neater lol. Then i will see about my collision issues. ALSO, im not using rectangles any more im using bitmaps, so how would i detect collision with bitmaps or sprites?

Re: Allegro Collision Problem

Posted: Tue Mar 09, 2010 8:27 pm
by krilik
Your bounding box collision that you have should be fine for a Pong game even if you're using sprites. You would just want to keep track of the sprites position and its width/height and use those values as your rectangles coordinates instead.

Re: Allegro Collision Problem

Posted: Tue Mar 09, 2010 8:35 pm
by mv2112
I successfully re-created pong! It took me a while to get the collision right lol. My problem before was i got all the variables mixed because the code was messy. Now it works! The physics arn't perfect but this is my first 2D game! 8-)
There are 4 files, 1 main.cpp and 3 headers.

main.cpp:

Code: Select all


#define USE_CONSOLE
#include <allegro.h>
#include "ball.h"

int main()
{
	mvALLEGRO init; //takes care of Allegro setup
	init.setup(1024,768,false,8); //sets the screen w and h, sets fullscreen to true or false and defines color bit, forgot what its called

	BITMAP * buffer=create_bitmap(init.x,init.y); //creates buffer
	BITMAP * p=load_bitmap("pong.bmp",NULL); //loads pong paddle
	BITMAP * b=load_bitmap("ball.bmp",NULL); //load ball

	char p1[10]; //for score
	char p2[10];

	ball ball(init.x/2,init.y/2,b,2); //creates ball
	Player player(200,380,p,1); //creates player 1 . Change x and y depending on screen res 
	Player player2(init.x-220,380,p,2); //and 2.Change x and y depending on screen res

	clear_to_color(buffer,makecol(0,0,0)); //makes BG black

	while(!key[KEY_ESC]) //GAME LOOP!!!!
	{
		clear_bitmap(buffer); //clear the buffer for game

		ball.move(); //move the ball
		itoa(ball.p1,p1,10); //get the score
		itoa(ball.p2,p2,10);
		rectfill(buffer,init.x/2-5,0,init.x/2+5,init.y,makecol(255,255,255)); //setup field
		textout_ex(buffer,font,p1,init.x/2-27,10,makecol(255,255,255),makecol(0,0,255)); //display score
		textout_ex(buffer,font,p2,init.x/2+20,10,makecol(255,255,255),makecol(0,0,255));
		ball.physics(&init); //collision and score check against walls
		ball.collision(&player); //check against player collision
		ball.collision(&player2);
		player2.move(&init); //player 2 move
		player.move(&init); //player 1 move
		player.draw(buffer); //draw players
		player2.draw(buffer);
		ball.draw(buffer); //draw ball
		init.render(buffer); //draw buffer to screen
	}

	

	destroy_bitmap(buffer); //DESTROY ALL!!!
	destroy_bitmap(p);
	destroy_bitmap(b);

	return 0;
}
END_OF_MAIN();


pomg.h:

Code: Select all


#include <ctime>
#include <time.h>


void timer(int time) //homemade timer
{
	clock_t timer=time+clock();
	while(timer>clock()){
          if(key[KEY_ESC]){
            return;
          }
	}
}

class mvALLEGRO
{
public:
	void setup(int x, int y, bool fscreen, int cd); //sets up screen for use
	void render(BITMAP* buffer); //renders the buffer
	int x; //width of screen
	int y; //height of screen
};

void mvALLEGRO::setup(int xx, int yy, bool fscreen,int cd)
{
	x=xx;
	y=yy;
	allegro_init();
	install_keyboard();
	install_mouse();
	if(fscreen==true)
	{
		set_gfx_mode(GFX_AUTODETECT,x,y,0,0);
	}
	else if(fscreen==false)
	{
		set_gfx_mode(GFX_AUTODETECT_WINDOWED,x,y,0,0);
	}
	set_color_depth(cd);
	clear_to_color(screen,makecol(0,0,0));
}

void mvALLEGRO::render(BITMAP* buffer)
{
	blit(buffer,screen,0,0,0,0,x,y);
}

player.h:

Code: Select all


#include "pomg.h"
class Player
{
public:
	Player(int x, int y, BITMAP*p, int i); //setup player
	void move(mvALLEGRO* init); //changes y coordinates depending on key press
	void draw(BITMAP* buffer); //draws pong paddle to buffer using current x and y data
public:
	int x;
	int y;
	int id;
	BITMAP * me;
};

Player::Player(int xx, int yy, BITMAP *p,int i)
{
	id=i;
	x=xx;
	y=yy;
	me=p;
}

void Player::draw(BITMAP* buffer)
{
	draw_sprite(buffer,me,x,y);
}

void Player::move(mvALLEGRO* init)
{
	if(y+118>=(*init).y) //*stops movement so it doesnt go off screen
	{
		y-=1;
		return;
	}

	if(y<=0) //*
	{
		y+=1;
		return;
	}

	if(id==2)
	{
	if(key[KEY_UP])
		{
			y-=10;
		}

	if(key[KEY_DOWN])
		{
			y+=10;
		}
	}
	if(id==1)
	{
		if(key[KEY_W])
		{
			y-=10;
		}

	if(key[KEY_S])
		{
			y+=10;
		}
	}
}

and ball.h:

Code: Select all


#include "player.h"
class ball
{
public:
	ball(int x, int y, BITMAP*b,int s); //sets up ball
	void move(); //moves ball
	void draw(BITMAP* buffer); //draws ball to buffer
	void physics(mvALLEGRO * init); //checks for wall collision and score
	void collision(Player* play); //checks for collision against players
	int p1; //player 1 score
	int p2; //player 2 score
private:
	int x;
	int y;
	int dy;
	int dx;
	int speed;
	BITMAP* bll;
};

ball::ball(int bx, int by, BITMAP* b,int s)
{
	bll=b;
	x=bx;
	y=by;
	dy=-1;
	dx=-1;
	speed=s;
	p1=0;
	p2=0;
}

void ball::move()
{
	if(dy==-1)
	{
		y-=speed;
	}
	else if(dy==1)
	{
		y+=speed;
	}
	if(dx==-1)
	{
		x-=speed;
	}
	else if(dx==1)
	{
		x+=speed;
	}
}

void ball::draw(BITMAP* buffer)
{
	draw_sprite(buffer,bll,x,y);
}

void ball::physics(mvALLEGRO* init)
{
	if(x>=(*init).x-25)
	{
		p1+=1;
		x=(*init).x/2;
		dx=-1;
	}
	if(x<=0)
	{
		p2+=1;
		x=(*init).x/2;
		dx=1;
	}
	if(y>=(*init).y-25)
	{
		dy=-1;
	}
	if(y<=0)
	{
		dy=1;
	}
}

void ball::collision(Player* play)
{
	if((*play).id==1)
	{
		if(x-10==(*play).x&&(y>=(*play).y-25&&y<=(*play).y+120))
		{
			dx=1;
		}
	}

		if((*play).id==2)
	{
		if(x+20==(*play).x&&(y>=(*play).y-25&&y<=(*play).y+120))
		{
			dx=-1;
		}
	}
}

Need less to say, I am very proud of myself :) .
So how does my code look? Are there any improvements that could be made? Any criticism is appreciated!

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 4:44 am
by RyanPridgeon
Make a video! :)

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 9:12 am
by K-Bal
Player scores in the ball class. Dude, do I have to elaborate on this? :)

Video +1

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 9:19 am
by GroundUpEngine
Damn that was fast! ;)

Moar Video :P

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 2:22 pm
by mv2112
K-Bal wrote:Player scores in the ball class. Dude, do I have to elaborate on this? :)

Video +1

Lol,
it was easier to have it in the ball class because the collision with the walls and goals was in there too. Less code.
What type of videos?

EDIT:
I slightly modified the collision with players because if you made the ball's speed higher than 2, it would pass right through the players. Here is the ball.h file:

Code: Select all


#include "player.h"
class ball
{
public:
	ball(int x, int y, BITMAP*b,int s); //sets up ball
	void move(); //moves ball
	void draw(BITMAP* buffer); //draws ball to buffer
	void physics(mvALLEGRO * init); //checks for wall collision and score
	void collision(Player* play); //checks for collision against players
	int p1; //player 1 score
	int p2; //player 2 score
private:
	int x;
	int y;
	int dy;
	int dx;
	int speed;
	BITMAP* bll;
};

ball::ball(int bx, int by, BITMAP* b,int s)
{
	bll=b;
	x=bx;
	y=by;
	dy=-1;
	dx=-1;
	speed=s;
	p1=0;
	p2=0;
}

void ball::move()
{
	if(dy==-1)
	{
		y-=speed;
	}
	else if(dy==1)
	{
		y+=speed;
	}
	if(dx==-1)
	{
		x-=speed;
	}
	else if(dx==1)
	{
		x+=speed;
	}
}

void ball::draw(BITMAP* buffer)
{
	draw_sprite(buffer,bll,x,y);
}

void ball::physics(mvALLEGRO* init)
{
	if(x>=(*init).x-25)
	{
		p1+=1;
		x=(*init).x/2;
		dx=-1;
	}
	if(x<=0)
	{
		p2+=1;
		x=(*init).x/2;
		dx=1;
	}
	if(y>=(*init).y-25)
	{
		dy=-1;
	}
	if(y<=0)
	{
		dy=1;
	}
}

void ball::collision(Player* play)
{
	if((*play).id==1)
	{
		if((x-10<=(*play).x&&x-10>=(*play).x-18)&&(y>=(*play).y-25&&y<=(*play).y+120)) //i changed the x parts of the if statements
		{
			dx=1;
		}
	}

		if((*play).id==2)
	{
		if((x+8<=(*play).x&&x+8>=(*play).x-18)&&(y>=(*play).y-25&&y<=(*play).y+120))
		{
			dx=-1;
		}
	}
}


Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 3:03 pm
by hurstshifter
mv2112 wrote:
Lol,
it was easier to have it in the ball class because the collision with the walls and goals was in there too. Less code.
What type of videos?
Maybe you should consider having the Player object hold a pointer to a ball that way you can store the score in the Player class. If you got advanced and started throwing in multi-balls like in arkanoid this would help.

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 3:37 pm
by K-Bal
hurstshifter wrote:
mv2112 wrote:
Lol,
it was easier to have it in the ball class because the collision with the walls and goals was in there too. Less code.
What type of videos?
Maybe you should consider having the Player object hold a pointer to a ball that way you can store the score in the Player class. If you got advanced and started throwing in multi-balls like in arkanoid this would help.
Or a manager class that holds the instances of balls and paddles.

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 5:43 pm
by mv2112
RyanPridgeon wrote:Make a video! :)
What type of video? I'v never made any before :shock2:

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 6:44 pm
by XianForce
mv2112 wrote:
RyanPridgeon wrote:Make a video! :)
What type of video? I'v never made any before :shock2:
Download a screen recorder (Hypercam, Fraps, Camstudio, etc) and record a small video of your game. If you have a mic, record your voice too... Makes the video a whole lot more enjoyable imo. But if nothing else, put some background music in it at least.

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 7:58 pm
by mv2112
XianForce wrote:
mv2112 wrote:
RyanPridgeon wrote:Make a video! :)
What type of video? I'v never made any before :shock2:
Download a screen recorder (Hypercam, Fraps, Camstudio, etc) and record a small video of your game. If you have a mic, record your voice too... Makes the video a whole lot more enjoyable imo. But if nothing else, put some background music in it at least.
Ok, now i need a program to put all the vids together, windows movie maker sucks.

Re: (Allegro Collision Problem) Now my first 2d Game!

Posted: Wed Mar 10, 2010 10:23 pm
by XianForce
mv2112 wrote:
XianForce wrote:
mv2112 wrote:
RyanPridgeon wrote:Make a video! :)
What type of video? I'v never made any before :shock2:
Download a screen recorder (Hypercam, Fraps, Camstudio, etc) and record a small video of your game. If you have a mic, record your voice too... Makes the video a whole lot more enjoyable imo. But if nothing else, put some background music in it at least.
Ok, now i need a program to put all the vids together, windows movie maker sucks.
Well... Good luck finding a free one... Personally I use Video Studio (it has a 30 day free trial, but you have to pay after that)