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\$
2
  • \$\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
    Commented Apr 2, 2016 at 14:14
  • 1
    \$\begingroup\$ The timer did not work because you forgot to use al_start_timer() \$\endgroup\$
    – rlam12
    Commented Aug 31, 2016 at 13:40

2 Answers 2

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.

\$\endgroup\$
0
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.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .