c++ - Allegro pong 碰撞问题

标签 c++ allegro allegro5

我最近才开始使用 allegro 5,并决定从一个基本的乒乓球游戏开始。我找到了一个,并决定给它添加一些额外的东西。添加两个桨和所需的变量和控件后,我复制并粘贴了原来两个的碰撞代码并添加了所需的变量。但是,如果我将新 Racket 从原来的 Racket 上移开,它们就不会再从球上弹开。我知道代码很大,但我不知道是什么导致了问题。 `

    #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;
    }`

非常感谢任何帮助。

最佳答案

我很确定这是你的问题:

float bouncer_dx = 8.0,bouncer_dy = -8.0;

^ 注意它总是以每个游戏刻度 8 像素的速度移动...

在代码的更下方,您正在检查 bouncer_x(和 bouncer_y)是否落在可以被 8 整除的像素上,虽然它似乎适用于两个原始桨,但我愿意打赌 bouncer_x值永远不会等于触发此“if”语句的值:

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

因为你的新子桨有不同的宽度和数学(除以 1.0 而不是 2.0)

检查一下...这只是查看代码一分钟,所以我不确定 :)

祝你好运!

关于c++ - Allegro pong 碰撞问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20391225/

相关文章:

c++ - 在 C++ 中转义外部代码块

2d - 检测 Sprite 之间碰撞的最佳方法?

c++ - C++中的变量如何命名为函数调用?

c++ - Visual C++ 和 Allegro5 : cannot recognize objects from abstract class from header file

c++ - 检查 Eigen::Matrix 的任何元素是否不为零

c++ - dup2( ) 导致子进程提前终止

c++ - 为什么我重载的 << 运算符没有输出最后一行?

c++ - 在 OSX 上运行 Allegro 5 时找不到主要功能

c++ - Allegro 5 一次播放多个样本