P
P
Pavel Matveev2019-08-03 20:30:20
C++ / C#
Pavel Matveev, 2019-08-03 20:30:20

When drawing, the picture "blinks". What to do?

I am learning C/C++ game development with Allegro. I'm trying to use sprite sheets and make the little man move on keypresses. For some reason, when moving, the picture blinks (it's kind of called "does not have time to render"). The code:

#include <allegro5\allegro.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_primitives.h>

enum KEYS {LEFT, RIGHT, SLEFT, SRIGHT};
bool keys[4] = {false, false, false, true};

int main(void)
{
  int FPS = 60;
  int width = 640;
  int height = 480;
  bool done = false;

  const int maxFrame = 10;
  int curFrame = 0;
  int frameCount = 0;
  int frameDelay = 5;
  int frameWidth = 46;
  int frameHeight = 84;

  int speed = 4;
  int x = width / 2 - frameWidth / 2;
  int y = height / 2 - frameHeight / 2;

  ALLEGRO_DISPLAY* display = NULL;
  ALLEGRO_EVENT_QUEUE* event_queue = NULL;
  ALLEGRO_TIMER* timer;
  ALLEGRO_BITMAP* image;

  if (!al_init())										
    return -1;

  display = al_create_display(width, height);			

  if (!display)									
    return -1;

  al_install_keyboard();
  al_init_image_addon();
  al_init_primitives_addon();

  image = al_load_bitmap("sprite_sheet_x2.png");
  al_convert_mask_to_alpha(image, al_map_rgb(255,255,255));

  event_queue = al_create_event_queue();
  timer = al_create_timer(1.0 / FPS);

  al_register_event_source(event_queue, al_get_timer_event_source(timer));
  al_register_event_source(event_queue, al_get_keyboard_event_source());

  al_start_timer(timer);

  while (!done)
  {
    ALLEGRO_EVENT ev;
    al_wait_for_event(event_queue, &ev);

    if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
    {
      switch (ev.keyboard.keycode)
      {
      case ALLEGRO_KEY_ESCAPE:
        done = true;
        break;
      case ALLEGRO_KEY_LEFT:
      case ALLEGRO_KEY_A:
        keys[LEFT] = true;
        keys[SRIGHT] = false;
        break;
      case ALLEGRO_KEY_RIGHT:
      case ALLEGRO_KEY_D:
        keys[RIGHT] = true;
        keys[SLEFT] = false;
        break;
      case ALLEGRO_KEY_UP:
      case ALLEGRO_KEY_W:
        break;
      case ALLEGRO_KEY_DOWN:
      case ALLEGRO_KEY_S:
        break;
      }
    }
    else if (ev.type == ALLEGRO_EVENT_KEY_UP)
    {
      switch (ev.keyboard.keycode)
      {
      case ALLEGRO_KEY_ESCAPE:
        done = true;
        break;
      case ALLEGRO_KEY_LEFT:
      case ALLEGRO_KEY_A:
        keys[LEFT] = false;
        keys[SLEFT] = true;
        break;
      case ALLEGRO_KEY_RIGHT:
      case ALLEGRO_KEY_D:
        keys[RIGHT] = false;
        keys[SRIGHT] = true;
        break;
      case ALLEGRO_KEY_UP:
      case ALLEGRO_KEY_W:
        break;
      case ALLEGRO_KEY_DOWN:
      case ALLEGRO_KEY_S:
        break;
      }
    }
    else if (ev.type == ALLEGRO_EVENT_TIMER)
    {
      if(keys[RIGHT])
      {
        if (++frameCount >= frameDelay)
        {
          if (++curFrame >= maxFrame)
            curFrame = 0;

          frameCount = 0;
        }
  
        x += speed;
      
        if (x >= width + frameWidth)
          x = -frameWidth;

        al_draw_bitmap_region(image, curFrame* frameWidth, 0, frameWidth, frameHeight, x, y, 0);
      }
      else if (keys[LEFT])
      {
        if (++frameCount >= frameDelay)
        {
          if (--curFrame <= 0)
            curFrame = maxFrame;

          frameCount = 0;
        }

        x -= speed;

        if (x <= -frameWidth)
        {
          x = width + frameWidth;
        }

        al_draw_bitmap_region(image, curFrame * frameWidth, frameHeight, frameWidth, frameHeight, x, y, 0);
      }
      else if (keys[SRIGHT])
      {
        al_draw_bitmap_region(image, 0, 0, frameWidth, frameHeight, x, y, 0);
      }
      else if (keys[SLEFT])
      {
        al_draw_bitmap_region(image, (maxFrame-1)*frameWidth, frameHeight, frameWidth, frameHeight, x, y, 0);
      }
    }
    al_flip_display();
    al_clear_to_color(al_map_rgb(117, 187, 253));
    al_draw_filled_rectangle(0, height / 2 + frameHeight / 2, width, height, al_map_rgb(96, 70, 63));
  }


  al_destroy_event_queue(event_queue);
  al_destroy_display(display);			
  al_destroy_bitmap(image);
  al_destroy_timer(timer);

  return 0;
}

5d45c421c73d1219732663.png
Link to the program:
https://yadi.sk/d/x0npCX54Ou-gxA
In the version where there is no response to keystrokes, i.e. the little man just moves in a certain direction, this does not happen.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Developer, 2019-08-03
@axe_lankaster13

Use double buffering

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question