Учусь геймдеву на С/С++ с Allegro. Пытаюсь использовать спрайт-листы и заставлять человечка двигаться по нажатию клавиш. Почему-то при движении картинка мигает (это вроде называется "не успевает рендериться"). Код:
#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;
}
Ссылка на прогу:
https://yadi.sk/d/x0npCX54Ou-gxA
В версии, где нет реагирования на нажатия клавиш, т.е. человечек просто двигается в определённую стороны, такого не происходит.