Laboratorium Komputerowe Progmar
Marcin Załęczny
Na stronie używamy cookies. Korzystając z witryny wyrażasz zgodę na ich wykorzystywanie.
Zamknij
Oferta
Kontakt
0006_MovingSpriteWithDeltaTime.cpp
Do pobrania:
Font
Aller_Rg.ttf
Textura
sdl.bmp
#define SDL_MAIN_USE_CALLBACKS 1 #include
#include
#include
#include
struct FSprite { SDL_Texture* Texture{}; SDL_FRect Position{}; float dx{}; float dy{}; }; struct FGameObject { double t{}; float red{}; float green{}; float blue{}; std::string Text{ '\0', 255 }; FSprite Sprite; int WindowWidth; int WindowHeight; float DeltaTime{}; std::string Texts[4]; } GameObject; SDL_Window* Window{}; SDL_Renderer* Renderer{}; TTF_Font* Font{}; void DrawString(SDL_Renderer* Renderer, const char* String, float x, float y); void Update(); void Tick(float DeltaTime); SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { SDL_SetAppMetadata("Basic SDL3 App", "1.0", "com.example.001_BasicSDL3App"); if (!SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed (%s)", SDL_GetError()); return SDL_APP_FAILURE; } if (!TTF_Init()) { SDL_Log("Couldn't initialize TTF: %s", SDL_GetError()); return SDL_APP_FAILURE; } if (!SDL_CreateWindowAndRenderer("examples/001_BasicOldFashionedApp", 640, 480, 0, &Window, &Renderer)) { SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); return SDL_APP_FAILURE; } std::string Path = std::string(SDL_GetBasePath()) + "Aller_Rg.ttf"; Font = TTF_OpenFont(Path.c_str(), 70.0); if (!Font) { SDL_Log("Couldn't open Font [%s]: %s", Path.c_str(), SDL_GetError()); return SDL_APP_FAILURE; } Path = std::string(SDL_GetBasePath()) + "sdl.bmp"; SDL_Surface* surface = SDL_LoadBMP(Path.c_str()); if (!surface) { SDL_Log("Couldn't load bitmap [%s]: %s", Path.c_str(), SDL_GetError()); return SDL_APP_FAILURE; } GameObject.Sprite.Texture = SDL_CreateTextureFromSurface(Renderer, surface); if (!GameObject.Sprite.Texture) { SDL_DestroySurface(surface); SDL_Log("Couldn't create static texture: %s", SDL_GetError()); return SDL_APP_FAILURE; } GameObject.Sprite.Position = { 0.0f, 0.0f, static_cast
(GameObject.Sprite.Texture->w), static_cast
(GameObject.Sprite.Texture->h) }; SDL_GetWindowSize(Window, &GameObject.WindowWidth, &GameObject.WindowHeight); GameObject.Sprite.Position.y = (GameObject.WindowHeight - GameObject.Sprite.Texture->h) / 2.0f; GameObject.Sprite.dx = 250.0f; // per second SDL_DestroySurface(surface); return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { switch (event->type) { case SDL_EVENT_QUIT: case SDL_EVENT_FINGER_UP: SDL_Log("0003_BasicAnimation: Exit requested by user"); return SDL_APP_SUCCESS; } return SDL_APP_CONTINUE; } void Update() { double t = ((double)SDL_GetTicks()) / 1000.0; // in seconds GameObject.DeltaTime = t - GameObject.t; GameObject.t = t; const double PerSeconds = 3.0; const double v = 2 * SDL_PI_D / PerSeconds; GameObject.red = (float)(0.5 + 0.5 * SDL_sin(v * GameObject.t + SDL_PI_D / 2)); GameObject.green = (float)(0.5 + 0.5 * SDL_sin(v * GameObject.t - SDL_PI_D)); GameObject.blue = (float)(0.5 + 0.5 * SDL_sin(v * GameObject.t + SDL_PI_D)); } void Tick(float DeltaTime) { GameObject.Sprite.Position.x += DeltaTime * GameObject.Sprite.dx; if (GameObject.Sprite.dx > 0.0f) { if (GameObject.Sprite.Position.x >= 3 * 500) { GameObject.Sprite.dx = -GameObject.Sprite.dx; for (int i = 0; i < 4; ++i) { GameObject.Texts[i] = ""; } } } else if (GameObject.Sprite.dx < 0.0f) { if (GameObject.Sprite.Position.x <= 0.0f) { GameObject.Sprite.dx = -GameObject.Sprite.dx; for (int i = 0; i < 4; ++i) { GameObject.Texts[i] = ""; } } } SDL_RenderTexture(Renderer, GameObject.Sprite.Texture, nullptr, &GameObject.Sprite.Position); for (int i = 0; i < 4; ++i) { SDL_FRect Position = GameObject.Sprite.Position; Position.x = i * 500.0f; Position.y -= 1.5 * Position.h; SDL_RenderTexture(Renderer, GameObject.Sprite.Texture, nullptr, &Position); if (GameObject.Sprite.dx > 0) { if (GameObject.Texts[i].empty() && GameObject.Sprite.Position.x > Position.x) { std::string Text{ '\0', 255 }; SDL_snprintf(Text.data(), 254, "%.3f", GameObject.t); GameObject.Texts[i] = Text; } } else if (GameObject.Sprite.dx < 0) { if (GameObject.Texts[i].empty() && GameObject.Sprite.Position.x < Position.x) { std::string Text{ '\0', 255 }; SDL_snprintf(Text.data(), 254, "%.3f", GameObject.t); GameObject.Texts[i] = Text; } } if (!GameObject.Texts[i].empty()) { DrawString(Renderer, GameObject.Texts[i].c_str(), Position.x, Position.y); } } DrawString(Renderer, GameObject.Text.c_str(), 10.0f, 10.0f); } SDL_AppResult SDL_AppIterate(void* appstate) { Update(); SDL_SetRenderDrawColorFloat(Renderer, GameObject.red, GameObject.green, GameObject.blue, SDL_ALPHA_OPAQUE_FLOAT); SDL_RenderClear(Renderer); SDL_snprintf(GameObject.Text.data(), 254, "Aktualny czas: %.3f", GameObject.t); Tick(GameObject.DeltaTime); SDL_RenderPresent(Renderer); return SDL_APP_CONTINUE; } void SDL_AppQuit(void* appstate, SDL_AppResult result) { if (GameObject.Sprite.Texture) { SDL_DestroyTexture(GameObject.Sprite.Texture); } if (Font) { TTF_CloseFont(Font); } if (Window) { SDL_DestroyWindow(Window); } if (Renderer) { SDL_DestroyRenderer(Renderer); } TTF_Quit(); SDL_Quit(); } void DrawString(SDL_Renderer* Renderer, const char* String, float x, float y) { SDL_Color Color = { 0xff, 0xff, 0x00, 0xff }; SDL_Surface* TextSurface = TTF_RenderText_Blended(Font, String, 0, Color); //SDL_Surface* TextSurface = TTF_RenderText_Solid(m_Font, String, 0, m_Color); // TTF_RenderText_Blended(m_Font, String, 0, m_Color); if (TextSurface) { SDL_Texture* TextTexture = SDL_CreateTextureFromSurface(Renderer, TextSurface); if (TextTexture != nullptr) { SDL_FRect destRect; destRect.x = x; destRect.y = y; destRect.w = static_cast
(TextSurface->w); destRect.h = static_cast
(TextSurface->h); SDL_RenderTexture(Renderer, TextTexture, nullptr, &destRect); SDL_DestroyTexture(TextTexture); } SDL_DestroySurface(TextSurface); } } [[CODE HERE]]