3
\$\begingroup\$

I've been trying to make a pong game with C++ and allegro5, I found moving the ball around easy with SFML, but in allegro5 I don't know what I can do to move it around, right now, it moves but only when one of the paddles is moving, could you please help me?

Here is the code I have now:

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;
  al_init_image_addon();
  ALLEGRO_BITMAP *Player1;
  ALLEGRO_BITMAP *Player2;
  ALLEGRO_BITMAP *ball;
  ALLEGRO_DISPLAY *display = NULL;
  ALLEGRO_EVENT ev;
  ALLEGRO_EVENT_QUEUE *eventqueue = NULL;
  bool playing = true;
  al_init();
  al_init_primitives_addon();
  display = al_create_display(800, 600);
  al_install_keyboard();
  eventqueue = al_create_event_queue();
  al_register_event_source(eventqueue, al_get_keyboard_event_source());
  al_register_event_source(eventqueue, al_get_display_event_source(display));
  Player1 = al_load_bitmap("rectt.png");
  Player2 = al_load_bitmap("rectt.png");
  ball = al_load_bitmap("ball.png");

  while (playing){
    ballx = ballx + 5;
    bally = bally + 5;

    al_clear_to_color(al_map_rgb(255, 255, 0));
    al_wait_for_event(eventqueue, &ev);
    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);
}

EDIT:- I'm now trying to use timers, but for some reason it isn't working, the ball isn't moving at all, could you please help? This is the new code:-

 #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>

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;
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");
ball = al_load_bitmap("ball.png");

while (playing){


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

        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);
}

EDIT: I've solved the problem by actually starting the timer. Here is the code for anybody who needs help with their code. It's definitely not perfect, but I hope it can help who needs it.

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;
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");
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 + 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);
}

Thanks everyone for the help, I really appreciate it :)

\$\endgroup\$
  • \$\begingroup\$ Just a guess, since I am not very familiar with Allegro, but have you tried getting the events off of the event queue with a different function than _italic_al_wait_for_event ? (It states that that function will "Wait until the event queue specified is non-empty", so without looking at implementation, that might cause the whole loop to wait for your input) Perhaps try it out with al_get_next_event instead e.g. and test for null before processing the result further. \$\endgroup\$ – Throzen Apr 2 '16 at 14:14
  • 1
    \$\begingroup\$ The timer did not work because you forgot to use al_start_timer() \$\endgroup\$ – rlam12 Aug 31 '16 at 13:40
4
\$\begingroup\$

If you use al_wait_for_event, then you need to use a ALLEGRO_TIMER as well to generate pulses (every 1/60th of a second for example) and you update your movement every pulse. That way there is always an event happening on Allegro.

If you still don't want to use a timer, you can use al_wait_for_event_until and then specify till when you wait for an event for then to continue with your program.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

One way to do this is to only run physics and render code when the event queue is empty:

ALLEGRO_EVENT_QUEUE* e = al_create_event_queue();
al_register_event_source(e, al_get_keyboard_event_source());
al_register_event_source(e, al_get_mouse_event_source());
al_register_event_source(e, al_get_joystick_event_source());
al_register_event_source(e, al_get_display_event_source(&display));

al_clear_to_color(al_map_rgb(0, 0, 0));
al_flip_display();

auto start_time = std::chrono::high_resolution_clock::now();
auto end_time = std::chrono::high_resolution_clock::now();
auto accumulator_start = std::chrono::high_resolution_clock::now();

bool _isQuitting = false;

while(!_isQuitting) {
    _deltaTime = end_time - start_time;
    start_time = std::chrono::high_resolution_clock::now();

    ALLEGRO_EVENT ev;
    while(al_peek_next_event(e, &ev)) {
        //...Handle Events Here...
        al_drop_next_event(e);
    }

    while((std::chrono::high_resolution_clock::now() - accumulator_start).count() >= 16666666 /* 1/60 second in nanoseconds */ ) {
        if(!_IsQuitting) {
            //...Run Physics Code here...
        }
        accumulator_start = std::chrono::high_resolution_clock::now();
    }

    if(!_IsQuitting) {
        //...Run Render Code Here...
    }

    end_time = std::chrono::high_resolution_clock::now();
}

al_unregister_event_source(e, al_get_keyboard_event_source());
al_unregister_event_source(e, al_get_mouse_event_source());
al_unregister_event_source(e, al_get_joystick_event_source());
al_unregister_event_source(e, al_get_display_event_source(&display));

I did notice that you are not cleaning up your bitmaps. It is a good idea to clean up the memory used in your application.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.