Collision problem with pong ALLEGRO5

I have a problem with making a pong game, when the ball intersects with the second player, nothing happens, the ball just passes right through it, but that's only when it's up, when it's down, collision is detected and it bounces normally, why is that? Here is the code:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <stdio.h>
#include <allegro5/allegro.h>
#include "allegro5/allegro.h"
#include "allegro5/allegro_image.h"
#include <allegro5/allegro_native_dialog.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/color.h>
#include <allegro5/allegro_color.h>
#include <allegro5/allegro5.h>
#include <allegro5/color.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <iostream>

ALLEGRO_EVENT ev;
int main(){
	int d = 200;
	int f = 200;
	int x = 700;
	int y = 100;
	int a = 100;
	int b = 100;
	int ballx = 200;
	int bally = 200;
	int ballXSpeed = 5;
	int ballYSpeed = 3;
	bool ballmoving = true;
	al_init_image_addon();
	ALLEGRO_BITMAP *Player1;
	ALLEGRO_BITMAP *Player2;
	ALLEGRO_BITMAP *ball;
	ALLEGRO_DISPLAY *display = NULL;
	
	ALLEGRO_EVENT_QUEUE *eventqueue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	
	bool playing = true;
	al_init();
	al_init_primitives_addon();
	display = al_create_display(800, 600);
	al_install_keyboard();
	eventqueue = al_create_event_queue();
	timer = al_create_timer(1.0 / 60.0);
	al_register_event_source(eventqueue, al_get_keyboard_event_source());
	al_register_event_source(eventqueue, al_get_display_event_source(display));
	al_register_event_source(eventqueue, al_get_timer_event_source(timer));
	Player1 = al_load_bitmap("rectt.png");
	Player2 = al_load_bitmap("rectt.png");
	int P1W = al_get_bitmap_width(Player1);
	int P1H = al_get_bitmap_height(Player1);
	int P2W = al_get_bitmap_width(Player2);
	int P2H = al_get_bitmap_height(Player2);
	ball = al_load_bitmap("ball.png");
	
	while (playing){


		al_clear_to_color(al_map_rgb(255, 255, 0));
		al_wait_for_event(eventqueue, &ev);
		al_start_timer(timer);
		if (ev.type == ALLEGRO_EVENT_TIMER){

			ballx = ballx + ballXSpeed;
			bally = bally + ballYSpeed;
			if (ballx < x+P1W && ballx>x-P1W &&bally<y+P1H && bally>y){
				ballXSpeed = ballXSpeed * -1;
				ballYSpeed = ballYSpeed*-1;
			}
			if (ballx > a + P2W && ballx < a+P2W+10 && bally <b + P2H &&bally>b){
				ballXSpeed = ballXSpeed*-1;
				ballYSpeed = ballYSpeed*-1;
			}
			if (ballx > 800 || bally > 600){
				ballx = 400;
				bally = 400;
				std::cout << "2 wins!" << std::endl;
			}
			if (ballx<-1 || bally<-1){
				ballx = 400;
				bally = 400;
				std::cout << "1 wins!" << std::endl;
			}
		}
			if (ev.type = ALLEGRO_EVENT_KEY_DOWN){
				switch (ev.keyboard.keycode){
				case ALLEGRO_KEY_UP:
					y -= 20;
					break;
				case ALLEGRO_KEY_DOWN:
					y += 20;
					break;
				case ALLEGRO_KEY_W:
					b -= 20;
					break;
				case ALLEGRO_KEY_S:
					b += 20;
					break;


				}
			}

			al_draw_bitmap(Player1, x, y, 0);
			al_draw_bitmap(Player2, a, b, 0);
			al_draw_bitmap(ball, ballx, bally, 0);
			al_flip_display();
		}
	
	al_flip_display();
	al_rest(5);
}		
Last edited on
You are not handling the collision detection the same way for both players.

1
2
if (ballx < x + P1W && ballx > x - P1W      && bally < y + P1H && bally > y){
if (ballx > a + P2W && ballx < a + P2W + 10 && bally < b + P2H && bally > b){


It's easy to make mistakes with repeated code. To avoid mistakes you could create function so that you don't have to repeat the collision detection code for both players.
Last edited on
I've tried making it the same first, but it still didn't work :/
So what was the thought behind the changes you made?
Last edited on
That the ball would be to the left of the paddle in the case of player1, but in the case of player 2, it would be to the right of the paddle, so in the first case, the ball's x coordinates have to be less than the coordinates of the paddle + its width, but in the second one they have to be more than the a coordinates + the width, but less than the coordinates+ the width+10
Hmm, to make sure I follow I'm going to start with the code for player 1, because I'm not even sure that one is correct.


 
ballx < x + P1W
This checks if the left side of the ball is less than the right side of the paddle.
 ballx    <    x + P1W 
 :             :
 : ____      __:
 :/    \    |  |
 |      |   |  |
  \____/    |  |
            |__|
OK this one looks fine, I guess. It simply checks if the ball has not yet passed the paddle on the right hand side.


 
ballx > x - P1W
This one I have a bit harder time understanding.
 ballx > x - P1W 
 :       :     
 : ____  :.. __
 :/    \    |  |
 |      |   |  |
  \____/    |  |
            |__|
x - P1W doesn't make much sense to me. If you want to check against the left side of the paddle you should simply have used x by itself. I also don't think you want to check the left side of the paddle against the left side of the ball. If you want the right side of the ball you need add the width of the ball to ballx. This gives you something like ballx + ballw > x.
        ballx + ballw
        :   >
        :   x     
   ____ :   :__
  /    \:   |  |
 |      |   |  |
  \____/    |  |
            |__|


Together ballx < x + P1W && ballx + ballw > x checks if the paddle and the ball is overlapping on the x-axis. Now it shouldn't be hard to do the same for the y-axis, just use the exact same code but replace the x coordinates with y coordinates and the widths with heights.

And when you have it working for player 1 you should only need to substitute the coordinates and size of the paddles to have it working for player 2. If this doesn't work you should suspect that the code for player 1 is also not working correctly.
Last edited on
Thank you so so much! It's now working :)
Topic archived. No new replies allowed.