• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Allegro 5 - problem z implementacją delta time i timestep

Object Storage Arubacloud
0 głosów
215 wizyt
pytanie zadane 31 sierpnia 2019 w C i C++ przez niezalogowany

Witam, chcąc zaimplementować delta time i timestep natknąłem się na problem z niestałymi wartościami timestep. Otóż, gdy przytrzymuje jakiś klawisz ruchu, if po Inpucie jest pomijany przez co wartość timestep jest dużo mniejsza, co z kolei wpływa na movement gracza (nie jest on już płynny).

Tak wygląda główna pętla gry.

void Run()
{
	float time;

	while (!gameOver)
	{
		time = (float)al_get_time() * 1000.0;
		timeStep = time - lastFrameTime;
		lastFrameTime = time;

		Input();

		if (draw && al_is_event_queue_empty(eventQueue))
		{
			game->draw = false;

			UpdateSnake(timeStep, direction);
			Logic();
			Draw();

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

A tak wygląda Input()

void Input()
{
	ALLEGRO_EVENT events;
	al_wait_for_eventeventQueue, &events);

	switch (events.type)
	{
		case ALLEGRO_EVENT_TIMER:
		{
			game->draw = true;

			switch (keys)
			{
				case UP:
					direction = (Position) { 0, -1 };
					break;

				case DOWN:
					direction = (Position) { 0, 1 };
					break;

				case LEFT:
					direction = (Position) { -1, 0 };
					break;

				case RIGHT:
					direction = (Position) { 1, 0 };
					break;
				}
			}

			break;
		}

		case ALLEGRO_EVENT_KEY_DOWN:
		{
			if (events.keyboard.keycode == ALLEGRO_KEY_UP || events.keyboard.keycode == ALLEGRO_KEY_W)
				game->keys = UP;
	
			if (events.keyboard.keycode == ALLEGRO_KEY_DOWN || events.keyboard.keycode == ALLEGRO_KEY_S)
				game->keys = DOWN;
					
			if (events.keyboard.keycode == ALLEGRO_KEY_LEFT || events.keyboard.keycode == ALLEGRO_KEY_A)
				game->keys = LEFT;

			if (events.keyboard.keycode == ALLEGRO_KEY_RIGHT || events.keyboard.keycode == ALLEGRO_KEY_D)
				game->keys = RIGHT;

			break;
		}

		case ALLEGRO_EVENT_DISPLAY_CLOSE:
		{
			gameOver = true;
			break;
		}
	}
}

 

1 odpowiedź

0 głosów
odpowiedź 31 sierpnia 2019 przez tangarr Mędrzec (154,780 p.)

Jestem niewyspany (gorąca noc, wyjący wiatrak) i nie piłem jeszcze kawy.
Wydaje mi się, że zmienna lastFrameTime powinna być aktualizowana podczas rysowania.
 

void Run()
{
    float time = (float)al_get_time() * 1000.0;
    lastFrameTime = time;
 
    while (!gameOver)
    {
        time = (float)al_get_time() * 1000.0;
        timeStep = time - lastFrameTime;
 
        Input();
 
        if (draw && al_is_event_queue_empty(eventQueue))
        {
            lastFrameTime = time;
            game->draw = false;
 
            UpdateSnake(timeStep, direction);
            Logic();
            Draw();
 
            al_flip_display();
            al_clear_to_color(al_map_rgb(0, 0, 0));
        }
    }
}
komentarz 31 sierpnia 2019 przez niezalogowany
edycja 31 sierpnia 2019
Niestety to raczej nie w tym rzecz, mam wrażenie że to coś z obsługą eventów w Allegro. Jeśli chcesz możesz zobaczyć jak to wygląda (najlepiej jest przemieścić się do jednej krawędzi i przemieszczając się do drugiej przytrzymać klawisz, i przegrać): https://www.mediafire.com/file/b3mg9cetm54w6zf/Snake.rar/file

Mogę również udostępnić cały kod lub projekt w VS 2017.
komentarz 31 sierpnia 2019 przez tangarr Mędrzec (154,780 p.)

Ewentualnie mógłbyś spróbować obsłużyć wszystkie eventy z kolejki przed rysowaniem.

while (!al_is_event_queue_empty(eventQueue)) {
    Input()
}
if (draw) {
    // rysowanie
}

 

komentarz 31 sierpnia 2019 przez tangarr Mędrzec (154,780 p.)
Jeżeli podzielisz się kodem to spróbuję później zdebugować problem.
komentarz 31 sierpnia 2019 przez niezalogowany
Kod jest kompilowany w C.

Skoro wysyłam już kod to skorzystam z okazji, mógłbyś ocenić czy mój kod się do czegoś nadaje? Nie znam żadnych patternów dla C, więc nie wiem czy tak powinno się pisać. Jakieś rady byłyby mile widziane :)

https://www.mediafire.com/file/ncuvoag2gwkmc2v/Kod-Snake-Allegro5.rar/file
komentarz 31 sierpnia 2019 przez niezalogowany

Dopiero zauważyłem, że wysłałem wersje ze złym main.c, poprawiam.

#include "Game.h"

int main(void)
{
	Game GAME;

	Setup(&GAME);
	Run(&GAME);
	Free(&GAME);

	return EXIT_SUCCESS;
}

 

komentarz 31 sierpnia 2019 przez tangarr Mędrzec (154,780 p.)

Testowałem na Ubuntu.
Liczenie delty w warunku if (draw && ...) naprawiło mi problem z szarpaniem podczas trzymania klawisza. Jednak sterowanie ciągle było "ociężałe". Zastosowałem drugi pomysł który ci zaproponowałem i wszystkie moje problemy znikły.

void Run(Game *game)
{
    float time = (float)al_get_time() * 1000.0;
    lastFrameTime = time;

    while (!game->gameOver)
    {
        while (!al_is_event_queue_empty(game->eventQueue)) 
            Input(game);

        if (game->draw)
        {
            time = (float)al_get_time() * 1000.0;
            timeStep = time - lastFrameTime;
            lastFrameTime = time;

            /* reszta kodu */
        }
    }
} 

Na pierwszy rzut oka kod ładnie się prezentuje. Widzę, że część logiki jeszcze nie jest zaimplementowana. Brakuje mi sprawdzania błędów podczas wczytywania zasobów.
Później poszukam czy nie ma problemów z zarządzaniem zasobami.

komentarz 31 sierpnia 2019 przez niezalogowany

Udało mi się znaleźć na forum Allegro algorytm interpolacji napisany przez jednego z twórców tej biblioteki i w nim była jedna różnica, otóż:

while (al_get_next_event(eventQueue, &events))

Wszystko było w takim while zamiast al_wait_for_event().

Przesyłam zaaktualizowany plik Game.c i folder res: https://www.mediafire.com/file/fw8eiygtt0xlnf7/updated.rar/file

Podobne pytania

0 głosów
1 odpowiedź 1,521 wizyt
pytanie zadane 14 grudnia 2019 w C i C++ przez Szymczak_7 Obywatel (1,860 p.)
0 głosów
1 odpowiedź 143 wizyt
pytanie zadane 27 sierpnia 2019 w C i C++ przez niezalogowany
+1 głos
0 odpowiedzi 501 wizyt
pytanie zadane 12 maja 2019 w Nasze projekty przez niezalogowany

92,551 zapytań

141,399 odpowiedzi

319,531 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...