Pong Collision Detection - Allegro Library

This topic is 4399 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I have two questions, sorry for the long code posts but i hope it's relevant. (1)Why won't the ball move, i'm confounded because it worked when i didn't use the class and actually coded it in the main file as "if(ball1.direction == NORTHEAST)" etc.. it moved. (2)Why isn' the ball colliding? This can't be solved I suppose until the first problem is. Again it worked when i coded it in the same manner as above in the main.cpp file, not accessing the CBall Class. Any Help would be very much appreciated. I'm not quite tearing my hair out but i'm certainly stumped! I'm working on it daily. Again thank you in advance for any help in the matter. -Jay Here's the source code to CBall (header file)
#define NORTHEAST 1
#define NORTHWEST 2
#define SOUTHEAST 3
#define SOUTHWEST 4

#define HEIGHT 480
#define WIDTH 640

class CBall {
public:
int x, y, xv, yv, direction, prev_dir;
void set_velocity(int,int);
void set_moving();
void set_direction(int);
void set_position(int, int);
void collide_w();	// checks ball's collision with walls
}ball;

void CBall::set_velocity(int a,int b)
{
xv = a;
yv = b;
}
void CBall::set_position(int a,int b)
{
x = a;
y = b;
}
void CBall::set_moving()
{
if (ball.direction == NORTHEAST)
{
ball.x += ball.xv;
ball.y -= ball.yv;
}
if (ball.direction == SOUTHEAST)
{
ball.x += ball.xv;
ball.y += ball.yv;
}
if (ball.direction == SOUTHWEST)
{
ball.x -= ball.xv;
ball.y += ball.yv;
}
if (ball.direction == NORTHWEST)
{
ball.x -= ball.xv;
ball.y -= ball.yv;
}
}
void CBall::set_direction(int dir)
{
direction = dir;
}
void CBall::collide_w()
{
// check ball boundaries with BOTTOM wall
if (ball.y >= (HEIGHT-10))
{
if (ball.direction == SOUTHEAST)
{
ball.direction = NORTHEAST;
}
if (ball.direction == SOUTHWEST)
{
ball.direction = NORTHWEST;
}
}
// check ball boundaries with TOP wall
if (ball.y <= 0)
{
if (ball.direction == NORTHWEST)
{
ball.direction = SOUTHWEST;
}
if (ball.direction == NORTHEAST)
{
ball.direction = SOUTHEAST;
}
}
// check ball boundaries with LEFT wall
if (ball.x <= 0)
{
if (ball.direction == SOUTHWEST)
{
ball.direction = SOUTHEAST;
}
if (ball.direction == NORTHWEST)
{
ball.direction = NORTHEAST;
}
}
// check ball boundaires with RIGHT wall
if (ball.x >= (WIDTH-10))
{
if (ball.direction == SOUTHEAST)
{
ball.direction = SOUTHWEST;
}
if (ball.direction == NORTHEAST)
{
ball.direction = NORTHWEST;
}
}
}


Here's the relevant code in the main.cpp file
CBall ball1;
ball1.set_velocity(2,2);
ball1.set_position(120,240);
ball1.set_direction(NORTHEAST);

// main game loop
while (done != true)
{

// while loop for logic
while (speed_counter > 0)
{
if(key[KEY_ESC])
{
done = true;
}
if(key[KEY_ENTER])
{
allegro_message("Paused");
}

{
// collision with left wall
}
{
// collision with right wall
}

// set ball into motion
ball1.set_moving();
//check collisions for ball1
ball1.collide_w();

speed_counter--;
//frame_counter++;
}



Share on other sites
If thats your exact code then the problem is this:

// set ball into motion
ball1.set_moving;

It should be
ball1.set_moving();

Without the () the function will not be called

Share on other sites
Hi, Yes, i just caught that mistake myself, and recompiled. Unfortunatly it wasn't the fix. Thank you though.

Share on other sites
Alright well the next question I have is where are you actually drawing the ball during the main loop?

Share on other sites
I seem to have lost my mind. This game is a breakout clone. Not pong. I suppose my questions are still apply regardless. Hope this clears up some potential confusion with the code.

The game logic and drawing code are separate. The main file looks as follows.
#include <allegro.h> // You must include the Allegro Header file#include <time.h>#include <iostream.h>#include <fstream.h>#include <string.h>#include <stdio.h>#include "ball class.h"#define WIDTH 640#define HEIGHT 480#define TILE_W 40#define TILE_H 10volatile long speed_counter = 0; // A long integer which will store the value of the                                             // speed counter. void increment_speed_counter() // A function to increment the speed counter{  speed_counter++; // This will just increment the speed counter by one. :)}END_OF_FUNCTION(increment_speed_counter);int main(int argc, char *argv[]){	//int frame_counter = 0; // A counter for understanding fps			bool done = false;	bool ball_waiting = true;	// ball is waiting for deployment on paddle	bool ball_in_play = false;	// ball is currently moving	char map[16][48]; // 192 tile map	short unsigned int map_x, map_y;	short unsigned int paddle_x, paddle_y;	short unsigned int ball_tile_x, ball_tile_y;	int color;	// tests for color of brick	unsigned short int i,j;		map_x = 0;	map_y = 0;	paddle_x = (WIDTH/2);	paddle_y = (HEIGHT-20);	ball_tile_x = 0;	ball_tile_y = 0;	ifstream map_file_read;	// level to be read	srand (time(NULL));	// seed the random number generator			allegro_init();        // Initialize Allegro	install_keyboard(); // Initialize keyboard routines	install_timer();	// initialize the timer routine	install_mouse();	// initialize the mouse routines		enable_hardware_cursor();	// Set normal arrow pointer	select_mouse_cursor(MOUSE_CURSOR_ARROW);	LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's	LOCK_FUNCTION(increment_speed_counter);//speed.	install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));//Set our BPS	set_color_depth(16); // Set the color depth	set_gfx_mode(GFX_AUTODETECT_WINDOWED, WIDTH, HEIGHT, 0, 0);	set_window_title("Bumper Blocks");	BITMAP *buffer = create_bitmap(WIDTH,HEIGHT);		BITMAP *a = load_bitmap("a.bmp", NULL);	BITMAP *b = load_bitmap("b.bmp", NULL);	BITMAP *c = load_bitmap("c.bmp", NULL);	BITMAP *d = load_bitmap("d.bmp", NULL);	BITMAP *e = load_bitmap("e.bmp", NULL);	BITMAP *f = load_bitmap("f.bmp", NULL);	BITMAP *paddle = load_bitmap("paddle.bmp", NULL);	BITMAP *ball = load_bitmap("ball.bmp", NULL);	map_file_read.open("map_file.txt");			for (map_y=0; map_y<48; map_y++)	{		for (map_x=0; map_x<16; map_x++)		{			// read map info here			map[map_x][map_y] = map_file_read.get();		}	}	map_file_read.close();	//show_mouse(buffer);	CBall ball1;	ball1.set_velocity(2,2);	ball1.set_position(120,240);	ball1.set_direction(NORTHEAST);	// main game loop	while (done != true)	{				// while loop for logic		while (speed_counter > 0)		{			if(key[KEY_ESC])			{				done = true;			}			if(key[KEY_ENTER])			{				allegro_message("Paused");			}			paddle_x = mouse_x;			// paddle collision detection			if (paddle_x <= 0)			{				// collision with left wall				paddle_x = 0;			}			if (paddle_x >= 560)			{				// collision with right wall				paddle_x = 560;			}						// set ball into motion			ball1.set_moving();			//check collisions for ball1			ball1.collide_w();												speed_counter--;			//frame_counter++;		}		// end of logic while loop				//draw tile map		for (short unsigned int i=0; i<16; i++)		{			for (short unsigned int j=0; j<48; j++)			{								if (map[j] == 'a')				{					draw_sprite(buffer, a, i*TILE_W, j*TILE_H);				}				if (map[j] == 'b')				{					draw_sprite(buffer, b, i*TILE_W, j*TILE_H);				}				if (map[j] == 'c')				{					draw_sprite(buffer, c, i*TILE_W, j*TILE_H);				}				if (map[j] == 'd')				{					draw_sprite(buffer, d, i*TILE_W, j*TILE_H);				}				if (map[j] == 'e')				{					draw_sprite(buffer, e, i*TILE_W, j*TILE_H);				}				if (map[j] == 'f')				{					draw_sprite(buffer, f, i*TILE_W, j*TILE_H);				}						}		}		draw_sprite(buffer, paddle, paddle_x, paddle_y);// draw paddle		draw_sprite(buffer, ball, ball1.x, ball1.y);	// draw ball1		textprintf_ex(buffer, font, 2, (HEIGHT-20), makecol(255,255,255), -1, "mouse_x = %d", mouse_x);		textprintf_ex(buffer, font, 2, (HEIGHT-10), makecol(255,255,255), -1, "mouse_y = %d", mouse_y);		textprintf_ex(buffer, font, 2, (HEIGHT-30), makecol(255,255,255), -1, "paddle_x = %d", paddle_x);		textprintf_ex(buffer, font, 2, (HEIGHT-40), makecol(255,255,255), -1, "ball1.y = %d", ball1.y);		textprintf_ex(buffer, font, 2, (HEIGHT-50), makecol(255,255,255), -1, "ball1.x = %d", ball1.x);		textprintf_ex(buffer, font, 2, (HEIGHT-60), makecol(255,255,255), -1, "ball_tile_x = %d", ball_tile_x);		textprintf_ex(buffer, font, 2, (HEIGHT-70), makecol(255,255,255), -1, "ball_tile_y = %d", ball_tile_y);		textprintf_ex(buffer, font, 2, (HEIGHT-80), makecol(255,255,255), -1, "ball1.direction = %d", ball1.direction);		textprintf_ex(buffer, font, 2, (HEIGHT-90), makecol(255,255,255), -1, "ball1.xv = %d", ball1.xv);		textprintf_ex(buffer, font, 2, (HEIGHT-100), makecol(255,255,255), -1, "ball1.yv = %d", ball1.yv);				// draw the buffer to the screen		blit(buffer, screen, 0,0,0,0,WIDTH,HEIGHT); 		clear_bitmap(buffer);	}	//destroy_bitmap(tile_grid);	destroy_bitmap(buffer);	destroy_bitmap(a);	destroy_bitmap(b);	destroy_bitmap(c);	destroy_bitmap(d);	destroy_bitmap(e);	destroy_bitmap(f);	destroy_bitmap(paddle);	destroy_bitmap(ball);			return 0; // Exit with no errors}END_OF_MAIN() // This must be called right after the closing bracket of your MAIN function.                      // It is Allegro specific.

Share on other sites
Have you run in debug to make sure that your speedcounter is not always 0? Also I dont really understand the api that you are using but dont really know why its volatile either??

Share on other sites
Yes i have. Everything "seems" to be working properly. Again i assert that when i pretended like the CBall class didn't exist and typed out the code "manually" it worked. ex. defining the variables and setting them, doing collision detection in the main.cpp. I have never come accross this problem ever. It's a new one for me!

Thank you for trying though, i do appreciate it.

Share on other sites
void CBall::set_moving()
{
if (ball.direction == NORTHEAST)
{
ball.x += ball.xv;
ball.y -= ball.yv;
}
}

All throughout your CBall functions you have ball.x or ball.something

Really you should just use the x or this->x, i have never seen anyone use the class name to access it and it may not be wrong but it sure looks wrong to me.

Share on other sites
When you declare your CBall class, you are also declaring an instance of it called ball, like so:

class CBall
{
...
} ball;

Then, in your implementations, you are referring not to the current instance of the ball but actually the CBall object you created. Instead of referring to ball, refer to this: this->x, etc. That should solve your problem.

Also: seperate your class into a header file (.h) and a class file (.cpp). The header file gets the prototypes and the the inlines and the class gets the implementations. Then, whenever you need to use the class, put #include "headerfile.h" at the top of your code file.

You should also use "include gaurds":

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass
{
};

#endif

The # statements prevent the class from being defined more often than it needs to, thus preventing linkage errors.

Share on other sites
Thank yout for all of the replies. I'm currently unable to test the last poster's response. But I will definitely try when it when i am able. Thanks again.

1. 1
Rutin
45
2. 2
3. 3
4. 4
5. 5

• 11
• 9
• 12
• 10
• 13
• Forum Statistics

• Total Topics
632985
• Total Posts
3009724
• Who's Online (See full list)

There are no registered users currently online

×