axe_lankaster13
@axe_lankaster13
C++ разраб с большими планами

При отрисовке картинка «мигает». Что делать?

Учусь геймдеву на С/С++ с 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;
}

5d45c421c73d1219732663.png
Ссылка на прогу:
https://yadi.sk/d/x0npCX54Ou-gxA
В версии, где нет реагирования на нажатия клавиш, т.е. человечек просто двигается в определённую стороны, такого не происходит.
  • Вопрос задан
  • 142 просмотра
Решения вопроса 1
samodum
@samodum
Какой вопрос - такой и ответ
Используй двойную буферизацию
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы