Allegro pong collision problems

285 views Asked by At

I have just recently started working with allegro 5 and decided to start with a basic pong game. I found one and decided to add some extras to it. After adding two more paddles and the needed variables and controls, I copied and pasted the collision code from the original two and added the needed variables. However, if I move the new paddles from the originals, they no longer bounce off the ball. The code is huge I know, but I have no idea whats causing the problem. `

    #include <stdio.h>
    #include <cstdlib>
    #include <sstream>
    #include <allegro5/allegro.h>
    #include <allegro5/allegro_primitives.h>
    #include <allegro5/allegro_color.h>
    #include <allegro5/allegro_font.h>
    #include <allegro5/allegro_ttf.h>

    /* constants and definitions */

    const int SCREEN_W = 960;
    const int SCREEN_H = 720;
    const float FPS = 60;
    const int paddle_height = 96;
    const int paddle_width = 16;
    const int bouncer_size = 16;

    enum MYKEYS{
    KEY_UP,KEY_DOWN,KEY_W,KEY_S,KEY_E,KEY_D,KEY_O,KEY_L
    };



    /* functions */


    void draw_paddle(float x,float y){
        // fill
        al_draw_filled_rounded_rectangle(x,y,x+paddle_width,y+paddle_height,3,3,al_color_html("729fcf"));
        // outline
        al_draw_rounded_rectangle(x,y,x+paddle_width,y+paddle_height,3,3,al_color_html("b5edff"),1.0);
        // shine
        al_draw_filled_rounded_rectangle(x,y,x+paddle_width/2,y+paddle_height-10,3,3,al_color_html("8abbef"));
    }

    void draw_ball(float x,float y){
        // fill
        al_draw_filled_circle(x,y,bouncer_size,al_color_html("6be97d"));
        // shadow
        al_draw_filled_circle(x+bouncer_size/4,y+bouncer_size/4,bouncer_size/3*2,al_color_html("59ce76"));
        // shine
        al_draw_filled_circle(x-bouncer_size/3,y-bouncer_size/3,bouncer_size/4,al_color_html("9bffaa"));
    }

    void draw_score(int l,int r){
        std::ostringstream ostr;
        ostr << l;
        std::ostringstream ostr1;
        ostr1 << r;
        ALLEGRO_FONT *font = al_load_font("arial.ttf",72,0);
        al_draw_filled_rectangle(SCREEN_W/2-5,SCREEN_H,SCREEN_W/2+5,-SCREEN_H,al_color_html("ffffff"));
        al_draw_text(font,al_color_html("ffffff"),SCREEN_W/2-50,0,ALLEGRO_ALIGN_CENTRE,ostr.str().c_str());
        al_draw_text(font,al_color_html("ffffff"),SCREEN_W/2+50,0,ALLEGRO_ALIGN_CENTER,ostr1.str().c_str());
        al_destroy_font(font);
    }


    int main(){
        ALLEGRO_DISPLAY *display = NULL;
        ALLEGRO_EVENT_QUEUE *event_queue = NULL;
        ALLEGRO_TIMER *timer = NULL;
        ALLEGRO_BITMAP *right_paddle = NULL;
        ALLEGRO_BITMAP *left_paddle = NULL;
        ALLEGRO_BITMAP *right_sub_paddle = NULL;
        ALLEGRO_BITMAP *left_sub_paddle = NULL;
        ALLEGRO_BITMAP *bouncer = NULL;
        float right_paddle_x =(SCREEN_W*4/5)-(paddle_width/2.0);
        float right_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
        float left_paddle_x =(SCREEN_W*1/5)-(paddle_width/2.0); 
        float left_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
        float right_sub_paddle_x = (SCREEN_W*4/5)-(paddle_width/2.0)-100;
        float right_sub_paddle_y =(SCREEN_H/2.0)-(paddle_height/2.0);
        float left_sub_paddle_x = (SCREEN_W*1/5)-(paddle_width/2.0)+100;
        float left_sub_paddle_y = (SCREEN_H/2.0)-(paddle_height/2.0);
        float bouncer_x = SCREEN_W/2.0-bouncer_size/2.0;
        float bouncer_y = SCREEN_H/2.0-bouncer_size/2.0;
        float bouncer_dx = 8.0,bouncer_dy = -8.0;
        float paddle_speed = 8.0;
        bool key[8] = {false,false,false,false,false,false,false,false};
        bool redraw = true;
        bool doexit = false;
        bool pause = false;
        int left_score = 0;
        int right_score = 0;
        if(!al_init()){
            fprintf(stderr,"failed to initialized allegro\n");
            return -1;
        }
        if(!al_install_keyboard()){
            fprintf(stderr,"failed to install keyboard\n");
            return -1;
        }
        al_init_primitives_addon();
        al_init_font_addon();
        al_init_ttf_addon();
        al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS,1,ALLEGRO_SUGGEST);
        al_set_new_display_option(ALLEGRO_SAMPLES,4,ALLEGRO_SUGGEST);  

        //initialize display(w,h)
        display = al_create_display(SCREEN_W,SCREEN_H);
        if(!display){
            fprintf(stderr,"failed to create display\n");
            return -1;
        }
        timer = al_create_timer(1.0/FPS);
        if(!timer){
            fprintf(stderr,"failed to create timer\n");
            return -1;
        }
        right_paddle = al_create_bitmap(paddle_width,paddle_height);
        if(!right_paddle){
            fprintf(stderr,"failed to create right paddle bitmap\n");
            return -1;
        }
        left_paddle = al_create_bitmap(paddle_width,paddle_height);
        if(!left_paddle){
            fprintf(stderr,"failed to create left paddle bitmap\n");
            return -1;
        }
        right_sub_paddle = al_create_bitmap(paddle_width,paddle_height);
        if(!right_sub_paddle){
            fprintf(stderr,"failed to create right sub paddle bitmap\n");
            return -1;
        }
        left_sub_paddle = al_create_bitmap(paddle_width,paddle_height);
        if(!left_sub_paddle){
            fprintf(stderr,"failed to create left sub paddle bitmap\n");
            return -1;
        }
        bouncer = al_create_bitmap(bouncer_size,bouncer_size);
        if(!bouncer){
            fprintf(stderr,"failed to create bouncer bitmap\n");
            return -1;
        }
        al_set_target_bitmap(left_paddle);
        al_clear_to_color(al_map_rgb(0,255,0));
        al_set_target_bitmap(right_paddle);
        al_clear_to_color(al_map_rgb(0,255,0));
        al_set_target_bitmap(left_sub_paddle);
        al_clear_to_color(al_map_rgb(0,255,0));
        al_set_target_bitmap(right_sub_paddle);
        al_clear_to_color(al_map_rgb(0,255,0));
        al_set_target_bitmap(bouncer);
        al_clear_to_color(al_map_rgb(0,0,255));
        al_set_target_bitmap(al_get_backbuffer(display));
        event_queue = al_create_event_queue();
        if(!event_queue){
            fprintf(stderr,"failed to create event queue\n");
            return -1;
        }
        al_register_event_source(event_queue,al_get_display_event_source(display));
        al_register_event_source(event_queue,al_get_timer_event_source(timer));
        al_register_event_source(event_queue,al_get_keyboard_event_source());
        al_clear_to_color(al_map_rgb(0,0,0));
        al_flip_display();
        al_start_timer(timer);
        while(!doexit){
            ALLEGRO_EVENT ev;
            al_wait_for_event(event_queue,&ev);
            if(ev.type == ALLEGRO_EVENT_TIMER && !pause){
                //logic for moving the paddles on input
                if(key[KEY_UP] && right_paddle_y >= 4.0){
                    right_paddle_y -= paddle_speed;
                }
                if(key[KEY_DOWN] && right_paddle_y <= SCREEN_H-paddle_height-4.0){
                    right_paddle_y += paddle_speed;
                }
                if(key[KEY_W] && left_paddle_y >= 4.0){
                    left_paddle_y -= paddle_speed;
                }
                if(key[KEY_S] && left_paddle_y <= SCREEN_H-paddle_height-4.0){
                    left_paddle_y += paddle_speed;
                }
                if(key[KEY_E] && left_sub_paddle_y >= 4.0){
                    left_sub_paddle_y -= paddle_speed;
                }
                if(key[KEY_D] && left_sub_paddle_y <= SCREEN_H-paddle_height-4.0){
                    left_sub_paddle_y += paddle_speed;
                }
                if(key[KEY_O] && right_sub_paddle_y >= 4.0){
                    right_sub_paddle_y -= paddle_speed;
                }
                if(key[KEY_L] && right_sub_paddle_y <= SCREEN_H-paddle_height-4.0){
                    right_sub_paddle_y += paddle_speed;
                }
                //logic for the bouncer
                if(bouncer_x < 0 || bouncer_x > SCREEN_W-bouncer_size){
                    if(bouncer_x < 0){
                        left_score += 1;
                    }else if(bouncer_x > SCREEN_W-bouncer_size){
                        right_score += 1;
                    }
                    paddle_speed = 8.0;
                    bouncer_x = SCREEN_W/2.0-bouncer_size/2.0;
                    bouncer_y = SCREEN_H/2.0-bouncer_size/2.0;
                    bouncer_dx = -bouncer_dx;
                    bouncer_dy = -bouncer_dx;
                }
                if(bouncer_y < 0 || bouncer_y > SCREEN_H-bouncer_size){
                    bouncer_dy = -bouncer_dy;
                }
                if(bouncer_x == left_paddle_x+(paddle_width/1.0)){
                    if(bouncer_y >= left_paddle_y+paddle_height || bouncer_y+bouncer_size < left_paddle_y){

                    }else{
                        paddle_speed += 1;
                        bouncer_dx = -bouncer_dx;
                    }
                }
                if(bouncer_x == right_paddle_x-(paddle_width/2.0)){
                    if(bouncer_y >= right_paddle_y+paddle_height || bouncer_y+bouncer_size < right_paddle_y){

                    }else{
                        paddle_speed += 1;
                        bouncer_dx = -bouncer_dx;
                    }
                }
                if(bouncer_x == left_sub_paddle_x+(paddle_width/1.0)){
                    if(bouncer_y >= left_sub_paddle_y+paddle_height || bouncer_y+bouncer_size < left_sub_paddle_y){

                    }else{
                        paddle_speed +=1;
                        bouncer_dx = -bouncer_dx;
                    }
                }
                if(bouncer_x == right_sub_paddle_x+(paddle_width/1.0)){
                    if(bouncer_y >= right_sub_paddle_y+paddle_height || bouncer_y+bouncer_size < right_sub_paddle_y){

                    }else{
                        paddle_speed +=1;
                        bouncer_dx = -bouncer_dx;
                    }
                }
                bouncer_x += bouncer_dx;
                bouncer_y += bouncer_dy;
                redraw = true;
            }else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE){
                break;
            }else if(ev.type == ALLEGRO_EVENT_KEY_DOWN){
                switch(ev.keyboard.keycode){
                    case ALLEGRO_KEY_UP:
                        key[KEY_UP] = true;
                        break;

                    case ALLEGRO_KEY_DOWN:
                        key[KEY_DOWN] = true;
                        break;

                    case ALLEGRO_KEY_W:
                        key[KEY_W] = true;
                        break;

                    case ALLEGRO_KEY_S:
                        key[KEY_S] = true;
                        break;

                    case ALLEGRO_KEY_E:
                        key[KEY_E] = true;
                        break;

                    case ALLEGRO_KEY_D:
                        key[KEY_D] = true;
                        break;

                    case ALLEGRO_KEY_O:
                        key[KEY_O] = true;
                        break;

                    case ALLEGRO_KEY_L:
                        key[KEY_L] = true;
                        break;
                }
            }else if(ev.type == ALLEGRO_EVENT_KEY_UP){
                switch(ev.keyboard.keycode){
                    case ALLEGRO_KEY_UP:
                        key[KEY_UP] = false;
                        break;

                    case ALLEGRO_KEY_DOWN:
                        key[KEY_DOWN] = false;
                        break;

                    case ALLEGRO_KEY_W:
                        key[KEY_W] = false;
                        break;

                    case ALLEGRO_KEY_S:
                        key[KEY_S] = false;
                        break;

                    case ALLEGRO_KEY_E:
                        key[KEY_E] = false;
                        break;

                    case ALLEGRO_KEY_D:
                        key[KEY_D] = false;
                        break;

                    case ALLEGRO_KEY_O:
                        key[KEY_O] = false;
                        break;

                    case ALLEGRO_KEY_L:
                        key[KEY_L] = false;
                        break;

                    case ALLEGRO_KEY_ESCAPE:
                        doexit = true;
                        break;

                    case ALLEGRO_KEY_P:
                        if(pause){
                            pause = false;
                        }else{
                            pause = true;
                        }
                        break;
                }
            }

            if(redraw && al_is_event_queue_empty(event_queue)){
            redraw = false;
            al_clear_to_color(al_map_rgb(0,0,0));
            draw_score(right_score,left_score);

            draw_paddle(right_sub_paddle_x,right_sub_paddle_y);
            draw_paddle(left_sub_paddle_x,left_sub_paddle_y);

            draw_paddle(right_paddle_x,right_paddle_y);
            draw_paddle(left_paddle_x,left_paddle_y);
            draw_ball(bouncer_x,bouncer_y);
            //al_draw_bitmap(right_paddle,right_paddle_x,right_paddle_y,0);
            //al_draw_bitmap(left_paddle,left_paddle_x,left_paddle_y,0);
            //al_draw_bitmap(right_sub_paddle,right_sub_paddle_x,right_sub_paddle_y,0);
            //al_draw_bitmap(left_sub_paddle,left_sub_paddle_x,left_sub_paddle_y,0);
            //al_draw_bitmap(bouncer,bouncer_x,bouncer_y,0);
            al_flip_display();
            }
        }
        al_destroy_bitmap(bouncer);
        al_destroy_bitmap(right_paddle);
        al_destroy_bitmap(left_paddle);
        al_destroy_bitmap(right_sub_paddle);
        al_destroy_bitmap(left_sub_paddle);
        al_destroy_timer(timer);
        al_destroy_display(display);
        al_destroy_event_queue(event_queue);
        return 0;
    }`

Any help is greatly appreciated.

1

There are 1 answers

0
blake On BEST ANSWER

I'm pretty sure this is your problem:

float bouncer_dx = 8.0,bouncer_dy = -8.0;

^ notice it's always moving at 8px per game tick...

Further down in the code, you are checking if bouncer_x (and bouncer_y) is landing on a pixel that is exactly divisible by 8, and while it seems to work for the two original paddles, i'm willing to bet the bouncer_x value never equals the value to trigger this 'if' statement:

if(bouncer_x == left_sub_paddle_x+(paddle_width/1.0)) { ... }

because your new sub paddles have different width and math (divided by 1.0 and not 2.0)

Check it and see... this is just from looking over the code for a minute so i dunno for sure :)

Good luck!