Laboratorium Komputerowe Progmar
Marcin Załęczny
Na stronie używamy cookies. Korzystając z witryny wyrażasz zgodę na ich wykorzystywanie.
Zamknij
Oferta
Kontakt
0004_Movement.cpp
#define SDL_MAIN_USE_CALLBACKS 1 #include
#include
#include
#include
SDL_Window* Window{}; SDL_Renderer* Renderer{}; TTF_Font* Font{}; class TSprite { public: TSprite(); ~TSprite(); void Draw(); void Move(float DeltaTime); SDL_Texture* Texture; SDL_FRect Position; float dx; float dy; float v; }; TSprite::TSprite() { Texture = nullptr; dx = 10.0f; dy = 0.0f; v = 10.0f; std::string Path = std::string(SDL_GetBasePath()) + "sdl.bmp"; SDL_Surface* Surface = SDL_LoadBMP(Path.c_str()); if (Surface == nullptr) { SDL_Log("Could not load bitmap [%s]: %s", Path.c_str(), SDL_GetError()); return; } Texture = SDL_CreateTextureFromSurface(Renderer, Surface); SDL_DestroySurface(Surface); if (!Texture) { SDL_Log("Could not create texture: %s", SDL_GetError()); return; } Position.x = 0.0f; Position.y = 0.0f; Position.w = Texture->w; Position.h = Texture->h; } TSprite::~TSprite() { if (Texture) { SDL_DestroyTexture(Texture); } } void TSprite::Draw() { //SDL_Log(SDL_LOG_CATEGORY_APPLICATION, "Sprite Position %f, %f, %f, %f", Position.x, Position.y, Position.w, Position.h); SDL_RenderTexture(Renderer, Texture, nullptr, &Position); } void TSprite::Move(float DeltaTime) { int WindowWidth = 0; int WindowHeight = 0; SDL_GetWindowSize(Window, &WindowWidth, &WindowHeight); float MoveX = DeltaTime * dx * v; if (dx > 0.0f) { if (Position.x + Position.w + MoveX >= WindowWidth) { dx = -dx; } Position.x += MoveX; } else if (dx < 0.0f) { if (Position.x + MoveX <= 0) { dx = -dx; } Position.x += MoveX; } } struct FGameObject { double t{}; float DeltaTime; long long int FrameCounter{ -1 }; std::string Text{ std::string(255, '\0') }; TSprite* Sprites[3]; } GameObject; void DrawString(SDL_Renderer* Renderer, const char* String, float x, float y); void Update(float DeltaTime); SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { SDL_SetAppMetadata("Basic SDL3 App", "1.0", "com.example.MyGame"); 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_LogError(SDL_LOG_CATEGORY_APPLICATION, "TTF_Init failed (%s)", SDL_GetError()); return SDL_APP_FAILURE; } if (!SDL_CreateWindowAndRenderer("examples/MyGame", 640, 480, 0, &Window, &Renderer)) { SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); return SDL_APP_FAILURE; } std::string FontPath = std::string(SDL_GetBasePath()) + "allerrg.ttf"; Font = TTF_OpenFont(FontPath.c_str(), 26.0f); if (!Font) { SDL_Log("Couldn't open font [%s]: %s", FontPath.c_str(), SDL_GetError()); return SDL_APP_FAILURE; } for (int i = 0; i < 3; ++i) { GameObject.Sprites[i] = nullptr; } for (int i = 0; i < 3; ++i) { GameObject.Sprites[i] = new TSprite(); if (!GameObject.Sprites[i]) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create sprite (%d)", i); return SDL_APP_FAILURE; } GameObject.Sprites[i]->Position.y = i * (GameObject.Sprites[i]->Position.h + GameObject.Sprites[i]->Position.h/2) + GameObject.Sprites[i]->Position.h / 2 + 100.0f; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "TextureSize %f, HalfTextureSize: %f, SpritePositionY: %f", GameObject.Sprites[i]->Position.h, GameObject.Sprites[i]->Position.h / 2, GameObject.Sprites[i]->Position.y); } 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(float DeltaTime) { GameObject.Sprites[0]->Move(DeltaTime); if (GameObject.FrameCounter % 2 == 0) { GameObject.Sprites[1]->Move(2*DeltaTime); } if (GameObject.FrameCounter % 3 == 0) { GameObject.Sprites[2]->Move(3*DeltaTime); } } SDL_AppResult SDL_AppIterate(void* appstate) { double t = ((double)SDL_GetTicks()) / 1000.0; GameObject.DeltaTime = t - GameObject.t; GameObject.t = t; GameObject.FrameCounter += 1; Update(GameObject.DeltaTime); SDL_SetRenderDrawColorFloat(Renderer, 0.0f, 0.0f, 0.0f, SDL_ALPHA_OPAQUE_FLOAT); SDL_RenderClear(Renderer); SDL_snprintf(GameObject.Text.data(), 254, "Aktualny czas: %.3f. Ten dopisany tekst spowoduje zcrashowanie apki.", GameObject.t); DrawString(Renderer, GameObject.Text.c_str(), 10.0f, 10.0f); for (int i = 0; i < 3; ++i) { //SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Draw sprite %d", i); GameObject.Sprites[i]->Draw(); } SDL_RenderPresent(Renderer); return SDL_APP_CONTINUE; } void SDL_AppQuit(void* appstate, SDL_AppResult result) { for (int i = 0; i < 3; ++i) { if (GameObject.Sprites[i]) { delete GameObject.Sprites[i]; } } 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 = { 255, 255, 0, 255 }; SDL_Surface* TextSurface = TTF_RenderText_Blended(Font, String, 0, Color); if (TextSurface) { SDL_Texture* TextTexture = SDL_CreateTextureFromSurface(Renderer, TextSurface); if (TextTexture) { SDL_FRect DestRect; DestRect.x = x; DestRect.y = y; DestRect.w = TextTexture->w; DestRect.h = TextTexture->h; SDL_RenderTexture(Renderer, TextTexture, nullptr, &DestRect); SDL_DestroyTexture(TextTexture); } SDL_DestroySurface(TextSurface); } }