Collision isn't working in pong

I've posted about another pong problem a while ago, but now I'm having another problem with the ball collision with the paddle , when the ball collides, it doesn't bounce back, why is that? Here is a snippet of the code:-

if (ev.type == ALLEGRO_EVENT_TIMER){

ballx = ballx + 10;
bally = bally + 10;
if (ballx ==x+(P1W/1.0)){
if (bally == y + (P1H / 1.0)){
ballx = ballx - 10;
bally = bally - 10;
}
}
}


Here is the whole code:-

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 = 10;
int bally = 10;
bool ballmoving = true;
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();
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));
int P1W = al_get_bitmap_width(Player1);
int P1H = al_get_bitmap_height(Player1);

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 + 10;
bally = bally + 10;
if (ballx ==x+(P1W/1.0)){
if (bally == y + (P1H / 1.0)){
ballx = ballx - 10;
bally = bally - 10;
}
}
}
if (ev.type = ALLEGRO_EVENT_KEY_DOWN){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
y -= 5;
break;
case ALLEGRO_KEY_DOWN:
y += 5;
break;
case ALLEGRO_KEY_W:
b -= 5;
break;
case ALLEGRO_KEY_S:
b += 5;
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);
}


UPDATE:-

  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 = 10;
int bally = 10;
int ballXSpeed = 5;
int ballYSpeed = 3;
bool ballmoving = true;
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();
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));
int P1W = al_get_bitmap_width(Player1);
int P1H = al_get_bitmap_height(Player1);

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 / 1.0)){
ballXSpeed = ballXSpeed * -1;
}
if (bally == y + (P1H / 1.0)){

ballYSpeed = ballYSpeed*-1;
}

}
if (ev.type = ALLEGRO_EVENT_KEY_DOWN){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
y -= 5;
break;
case ALLEGRO_KEY_DOWN:
y += 5;
break;
case ALLEGRO_KEY_W:
b -= 5;
break;
case ALLEGRO_KEY_S:
b += 5;
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);
}


still not working

Edit

The observed behavior of the ball going through the paddle prompts me to check your collision detection statements, and I believe they are the problem. The condition if (ballx == x + (P1W / 1.0)) will only return true if ballxis exactly equal to a specific point of your paddle. What you want to check is if any part of your ball overlaps any part of your paddle. Let's try an example.

Let's say we have a ball and a wall and let's assume that both are normal rectangles. *note this is sudo code to get the logic across. I'm not familiar enough with c++ or your framework to know what the actual code required would be.

if (// if the ball is not to the left of the wall
(!(ball.position.x + ball.width < wall.position.x))
// and the ball is not to the right of the wall
&&  (!(ball.position.x > wall.position.x + wall.width))
// and the ball is not above the wall
&& (!(ball.position.y + ball.height < wall.position.y))
// and the ball is not below the wall
&& (!(ball.position.y > wall.position.y + wall.height))){
// then the ball collides with the wall!
}


Now that is a big ugly check, and it only check for collision with one wall. There are at least 2 walls and 2 bumpers in PONG so we probably want to make that a method so we can just say

if(ballHitsRect(bumper1) || ballHitsRect(bumper2)){
//handle collision
ballXStep = ballXStep * -1;
}
if(ballHitsRect(topWall) || ballHitsRect(bottomWall)){
//handle collision
ballYStep = ballYStep * -1;
}


*note: the above reflection logic is simplified and will always revers a ball's X direction when it hits a bumper in any way. This causes some odd behavi,or but it is a good starting point. It's up to you how realistic you want your physics to be. You can certainly improve upon this by playing around with your game and seeing how it behaves and what you want to change.

It doesn't look like your properly reversing the direction the ball travels.

if (ev.type == ALLEGRO_EVENT_TIMER){

ballx = ballx + 10;
bally = bally + 10;
if (ballx ==x+(P1W/1.0)){
if (bally == y + (P1H / 1.0)){
ballx = ballx - 10;
bally = bally - 10;
}
}
}


This code will only move the ball -10 for the pass through the loop where the ball hits the bumper.

My suggestion, try storing the ball movement in a variable. Then you can just change the value of the variable to control the direction and speed of the ball.

Also you should probably check for collisions with the walls and the bumper separately.

Here's an example of this

if (ev.type == ALLEGRO_EVENT_TIMER){

ballx = ballx + ballXStep;
bally = bally + ballYStep;
if (ballx ==x+(P1W/1.0)){ // if x movement causes collision
ballXStep = ballXStep * -1; // reverse x movement direction
}
if (bally == y + (P1H / 1.0)){ // if y movement causes collision
ballYStep = ballYStep * -1; // reverse y movement direction
}

}


*note: I'm not that familiar with C++ so there might be a silly error in the conditions.

Just initialize these variables with your other variables.

int ballXStep = 10;
int ballYStep = 10;


Also, one note on your variables. You may want to consider renaming them so they have meaningful names. ballx is a good name. It tells me that is the x coordinate of the ball. d, f, a, and b aren't great names because I don't easily know what b -= 5; means without looking through other code. This isn't a big problem in code as short as yours is, but if you write something more in-depth, then this will become a bigger setback. Good variable names will help you add features and debug much more easily.

• Thank you so much, but it's still not working, I will update with the new code – Luna Apr 6 '16 at 13:52
• It's still not working because you're not properly using variables to step. You're still going ballx = ballx + 5 and then trying ballx = ballx * -1 (the second part of this will move your ball off the screen...). You need a variable that holds how far to move. You need to create the ballXStep variable and ballYStep variable. Check the code in my answer and compare it to your changes. You'll see there are some key differences. – JustWannaFly Apr 6 '16 at 14:27
• The differences I'm meaning are that ballx = ballx + 5 needs to be changed to ballx = ballx + ballXStep and ballx = ballx * -1 needs to be changed to ballXStep = ballXStep * -1. The same needs to be done for the y components. Then you also need to add int ballXStep = 5 and int ballYStep = 3 to the section where you initialize your variables. *note, if you need to adjust the speed of your ball just change the values of ballXStep and ballYStep – JustWannaFly Apr 6 '16 at 14:33
• I added the variables ballXSpeed and ballYSpeed and set their values, also:-'if (ev.type == ALLEGRO_EVENT_TIMER){ ballx = ballx + ballXSpeed; bally = bally + ballYSpeed; if (ballx == x + (P1W / 1.0)){ ballXSpeed = ballXSpeed * -1; } if (bally == y + (P1H / 1.0)){ ballYSpeed = ballYSpeed*-1; } } ' – Luna Apr 6 '16 at 14:48
• @Luna If that is the case, then you don't have your latest code in the updated section. My comments responded to what I can see. If you're still having troubles, please post your updated code. Also if you could describe what behavior you're observing, that would help a lot. – JustWannaFly Apr 6 '16 at 14:54