commit e2e27c3677c6ecff03b84a0ea26adebedb19de32 Author: Alfie King Date: Tue May 6 15:08:30 2025 +0100 game diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a8bc10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +build \ No newline at end of file diff --git a/assets/fonts/C64.ttf b/assets/fonts/C64.ttf new file mode 100644 index 0000000..02ff5fc Binary files /dev/null and b/assets/fonts/C64.ttf differ diff --git a/assets/sounds/die.wav b/assets/sounds/die.wav new file mode 100644 index 0000000..9b79fbd Binary files /dev/null and b/assets/sounds/die.wav differ diff --git a/assets/sounds/hit.wav b/assets/sounds/hit.wav new file mode 100644 index 0000000..9d9b77c Binary files /dev/null and b/assets/sounds/hit.wav differ diff --git a/assets/sounds/point.wav b/assets/sounds/point.wav new file mode 100644 index 0000000..9cf19fe Binary files /dev/null and b/assets/sounds/point.wav differ diff --git a/assets/sounds/wing.wav b/assets/sounds/wing.wav new file mode 100644 index 0000000..9ae2c67 Binary files /dev/null and b/assets/sounds/wing.wav differ diff --git a/assets/sprites/background.bmp b/assets/sprites/background.bmp new file mode 100644 index 0000000..84a487d Binary files /dev/null and b/assets/sprites/background.bmp differ diff --git a/assets/sprites/bird.bmp b/assets/sprites/bird.bmp new file mode 100644 index 0000000..5888383 Binary files /dev/null and b/assets/sprites/bird.bmp differ diff --git a/assets/sprites/ground.bmp b/assets/sprites/ground.bmp new file mode 100644 index 0000000..7fc3bd9 Binary files /dev/null and b/assets/sprites/ground.bmp differ diff --git a/assets/sprites/pipe.bmp b/assets/sprites/pipe.bmp new file mode 100644 index 0000000..667da04 Binary files /dev/null and b/assets/sprites/pipe.bmp differ diff --git a/include/engine.h b/include/engine.h new file mode 100644 index 0000000..6edf820 --- /dev/null +++ b/include/engine.h @@ -0,0 +1,30 @@ +#include "input.h" +#include "text.h" +#include "sprite.h" +#include "vector.h" +#include +#include +#include +#include "sound.h" + +class Engine +{ + private: + const char* ctitle; + int frameStart = 0; + bool soundInitialized = false; + + public: + Input input; + int targetFrameRate = 60; + SDL_Window *window; + SDL_Renderer *renderer; + + Engine(std::string title, int width, int height); + void initSound(); + void clear(SDL_Color color); + void startFrame(); + void render(); + void update(); + ~Engine(); +}; \ No newline at end of file diff --git a/include/input.h b/include/input.h new file mode 100644 index 0000000..7858f0c --- /dev/null +++ b/include/input.h @@ -0,0 +1,39 @@ +#include +#include +#include + +struct Controller +{ + SDL_GameController* controller; + std::string name; + std::map buttons; + Sint16 leftStickX = 0; + Sint16 leftStickY = 0; + Sint16 rightStickX = 0; + Sint16 rightStickY = 0; + Sint16 leftTrigger = 0; + Sint16 rightTrigger = 0; +}; + +struct Mouse +{ + int x; + int y; + int wheel; + std::map buttons; +}; + +class Input +{ + private: + SDL_Event event; + + public: + bool exit; + std::map controllers; + std::map activeKeys; + Mouse mouse; + + Input(); + void update(); +}; \ No newline at end of file diff --git a/include/sound.h b/include/sound.h new file mode 100644 index 0000000..05e8cf7 --- /dev/null +++ b/include/sound.h @@ -0,0 +1,26 @@ +#include + +class Music +{ + private: + Mix_Music* music; + public: + Music(const char* path); + void play(int loops = -1); + void pause(); + void stop(); + void resume(); + void setVolume(int volume); + ~Music(); +}; + +class Effect +{ + private: + Mix_Chunk* effect; + public: + Effect(const char* path); + void setVolume(int volume); + void play(int loops = 0, int channel = -1); + ~Effect(); +}; \ No newline at end of file diff --git a/include/sprite.h b/include/sprite.h new file mode 100644 index 0000000..7d57365 --- /dev/null +++ b/include/sprite.h @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include "vector.h" +#pragma once + +class Sprite +{ + private: + std::map frames; + SDL_Surface* surface; + SDL_Texture* Texture; + int_vec2 size; + + public: + SDL_Rect dstrect; + int_vec2 scale = { 1, 1 }; + double angle = 0; + Sprite(SDL_Renderer* renderer, SDL_Surface* surface); + void draw(SDL_Renderer* renderer, std::string frame, bool autoRect = true, SDL_RendererFlip flip = SDL_FLIP_NONE); + void addFrame(std::string name, SDL_Rect rect); + void move(int_vec2 position); + void setPos(int_vec2 position); + int_vec2 getSize(std::string frame); + void autorect(std::string frame); + ~Sprite(); +}; + +class Animation +{ + private: + std::vector frames; + Sprite* sprite; + int currentFrame = 0; + int frameDuration = 0; + int frameCounter = 0; + std::string currentFrameName; + int frameIndex = 0; + int frameDirection = 1; + + public: + bool loop = true; + bool pingpong = false; + Animation(std::map frames, Sprite* sprite, int frameDuration); + void update(); + void reset(bool ifFinish = false); + void draw(SDL_Renderer* renderer, bool autoRect = true, bool flip = false); +}; + +class AnimationManager +{ + private: + std::map animations; + std::map flip; + std::map autoRect; + std::string currentAnimation; + Sprite* sprite; + + public: + AnimationManager(Sprite* sprite); + void addAnimation(std::string name, std::map animation, int frameDuration = 10, bool flip = false, bool autoRect = true, bool loop = true, bool pingpong = false); + void setAnimation(std::string name); + void update(); + void play(std::string name); + void draw(SDL_Renderer* renderer); +}; \ No newline at end of file diff --git a/include/text.h b/include/text.h new file mode 100644 index 0000000..bc014e9 --- /dev/null +++ b/include/text.h @@ -0,0 +1,19 @@ +#include +#include +#include + +class Text +{ +private: + SDL_Surface* surface; + SDL_Texture* texture; + TTF_Font* font; + SDL_Color color; + SDL_Rect* rect; + +public: + Text(std::string font, int size, SDL_Color color); + ~Text(); + void update(std::string text, SDL_Renderer* renderer); + void draw(SDL_Renderer* renderer, int x, int y); +}; \ No newline at end of file diff --git a/include/vector.h b/include/vector.h new file mode 100644 index 0000000..76c938d --- /dev/null +++ b/include/vector.h @@ -0,0 +1,58 @@ +// prevent multiple inclusion +#pragma once + +// class for 2D float vector +class float_vec2 +{ + // public members + public: + // x and y coordinates + float x, y; + // operator functions + float_vec2 operator+(float_vec2 vec) + { + return { x + vec.x, y + vec.y }; + } + float_vec2 operator*(float v) + { + return { x * v, y * v }; + } + float_vec2 operator*(float_vec2 vec) + { + return { x * vec.x, y * vec.y }; + } + float_vec2 operator-(float_vec2 vec) + { + return { x - vec.x, y - vec.y }; + } + float_vec2 operator-(float v) + { + return { x - v, y - v }; + } +}; + +// class for 2D integer vector +class int_vec2 +{ + // public members + public: + // x and y coordinates + int x, y; + // operator functions + int_vec2 operator+(int_vec2 vec) + { + return { x + vec.x, y + vec.y }; + } + int_vec2 operator*(int v) + { + return { x * v, y * v }; + } + int_vec2 operator*(int_vec2 vec) + { + return { x * vec.x, y * vec.y }; + } + int_vec2 operator-(int_vec2 vec) + { + return { x - vec.x, y - vec.y }; + } +}; \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..6ab71d4 --- /dev/null +++ b/makefile @@ -0,0 +1,20 @@ +CXX = g++ +LDFLAGS = `sdl2-config --libs` -l SDL2_ttf -l SDL2_mixer +CXXFLAGS = `sdl2-config --cflags` -pedantic -O2 -std=c++17 -lX11 -lstdc++fs -I include +SRC = $(wildcard src/*.cpp) +OBJ = $(addprefix build/, $(notdir $(SRC:.cpp=.o))) +TARGET = build/x86_64/main.x86_64 + +all: clean dirs $(TARGET) + +dirs: + @mkdir -p build/x86_64 + +$(TARGET): $(OBJ) + $(CXX) -o $@ $^ $(LDFLAGS) + +build/%.o: src/%.cpp + $(CXX) -c -o $@ $< $(CXXFLAGS) + +clean: + @rm -f $(OBJ) $(TARGET) \ No newline at end of file diff --git a/src/engine.cpp b/src/engine.cpp new file mode 100644 index 0000000..4fbb0df --- /dev/null +++ b/src/engine.cpp @@ -0,0 +1,71 @@ +#include "engine.h" + +Engine::Engine(std::string title, int width, int height) +{ + // convert title to char* + ctitle = title.c_str(); + + // Initialize SDL and TFF; + TTF_Init(); + SDL_Init(SDL_INIT_EVERYTHING); + + // Create window and renderer + window = SDL_CreateWindow(ctitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); +} + +void Engine::initSound() +{ + // Initialize sound + Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048); + soundInitialized = true; +} + +void Engine::clear(SDL_Color color) +{ + // Set color + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); + + // Clear screen + SDL_RenderClear(renderer); +} + +void Engine::startFrame() +{ + // Start frame + frameStart = SDL_GetTicks(); +} + +void Engine::render() +{ + // Render screen + SDL_RenderPresent(renderer); + + if (1000 / targetFrameRate > SDL_GetTicks() - frameStart) + { + SDL_Delay(1000 / targetFrameRate - (SDL_GetTicks() - frameStart)); + } +} + +void Engine::update() +{ + // Update input + input.update(); +} + +Engine::~Engine() +{ + // Free renderer and window + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + // If sound is initialized, quit Mix + if (soundInitialized) + { + Mix_Quit(); + } + + // Quit SDL and TTF + SDL_Quit(); + TTF_Quit(); +} diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..3bab838 --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,56 @@ +#include "input.h" + +Input::Input() +{ + SDL_Init(SDL_INIT_JOYSTICK); + exit = false; +} + +void Input::update() +{ + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_CONTROLLERBUTTONDOWN: + controllers[event.cbutton.which].buttons[event.cbutton.button] = true; + break; + case SDL_CONTROLLERBUTTONUP: + controllers[event.cbutton.which].buttons[event.cbutton.button] = false; + break; + case SDL_MOUSEBUTTONDOWN: + mouse.buttons[event.button.button] = true; + break; + case SDL_MOUSEBUTTONUP: + mouse.buttons[event.button.button] = false; + break; + case SDL_KEYDOWN: + activeKeys[event.key.keysym.sym] = true; + break; + case SDL_KEYUP: + activeKeys.erase(event.key.keysym.sym); + break; + case SDL_CONTROLLERDEVICEADDED: + controllers[SDL_NumJoysticks() - 1] = { + SDL_GameControllerOpen(SDL_NumJoysticks() - 1), + SDL_GameControllerName(SDL_GameControllerOpen(SDL_NumJoysticks() - 1)) + }; + printf("Controller added: %s\n", controllers[SDL_NumJoysticks() - 1].name.c_str()); + break; + case SDL_QUIT: + exit = true; + break; + } + for (auto& controller : controllers) + { + controller.second.leftStickX = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_LEFTX); + controller.second.leftStickY = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_LEFTY); + controller.second.rightStickX = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_RIGHTX); + controller.second.rightStickY = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_RIGHTY); + controller.second.leftTrigger = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT); + controller.second.rightTrigger = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); + } + SDL_GetMouseState(&mouse.x, &mouse.y); + mouse.wheel = event.wheel.y; + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..1114ba8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,225 @@ +#include "engine.h" +#include + +SDL_Surface* background; +SDL_Surface* pipe; +SDL_Surface* ground; +SDL_Surface* bird; +Effect* flapSound; +Effect* hitSound; +Effect* pointSound; +Effect* dieSound; +Engine *engine; + +int random(int min, int max) +{ + return rand() % (max - min + 1) + min; +} + +void quit() +{ + delete engine; + SDL_FreeSurface(background); + SDL_FreeSurface(pipe); + SDL_FreeSurface(ground); + SDL_FreeSurface(bird); + return; +} + +int main(int argc, char* argv[]) +{ + srand(time(NULL)); + engine = new Engine("Flappy Bird", 288, 512); + engine->initSound(); + engine->targetFrameRate = 60; + + background = SDL_LoadBMP("assets/sprites/background.bmp"); + pipe = SDL_LoadBMP("assets/sprites/pipe.bmp"); + ground = SDL_LoadBMP("assets/sprites/ground.bmp"); + bird = SDL_LoadBMP("assets/sprites/bird.bmp"); + + Text* scoreText = new Text("assets/fonts/C64.ttf", 24, { 255, 255, 255, 255 }); + + flapSound = new Effect("assets/sounds/wing.wav"); + hitSound = new Effect("assets/sounds/hit.wav"); + pointSound = new Effect("assets/sounds/point.wav"); + dieSound = new Effect("assets/sounds/die.wav"); + flapSound->setVolume(50); + hitSound->setVolume(50); + pointSound->setVolume(50); + dieSound->setVolume(50); + Sprite* backgroundSprite = new Sprite(engine->renderer, background); + backgroundSprite->addFrame("background", { 0, 0, 288, 512 }); + + Sprite* groundSprite = new Sprite(engine->renderer, ground); + groundSprite->addFrame("ground", { 0, 0, 336, 112 }); + groundSprite->setPos({ 0, 400 }); + + Sprite* pipeSprite = new Sprite(engine->renderer, pipe); + pipeSprite->addFrame("pipe", { 0, 0, 52, 320 }); + + int groundSpeed = 1; + int groundPosx[2] = { 0, 336 }; + + int pipeSpeed = 1; + int pipeGap = 125; + int pipeSet1[2] = { 288, random(0, 320 - pipeGap) }; + int pipeSet2[2] = { 288 + 144 + 26, random(0, 320 - pipeGap) }; + + + Sprite* birdSprite = new Sprite(engine->renderer, bird); + AnimationManager* birdAnimations = new AnimationManager(birdSprite); + std::map flap = { + { "up", { 34*2, 0, 34, 24 } }, + { "mid", { 0, 0, 34, 24 } }, + { "down", { 34*1, 0, 34, 24 } }, + }; + std::map idle = { + { "mid", { 0, 0, 34, 24 } }, + }; + birdAnimations->addAnimation("flap", flap, 15, false, true, true, true); + birdAnimations->setAnimation("flap"); + + float birdAngle = 0; + float birdGravity = 0.2; + float birdVelocity = 0; + float birdJump = -3.5; + float birdY = 200; + bool dead = false; + int score = 0; + int jumpDelay = 0; + bool deathSoundPlayed = false; + int scoreCooldown = 0; + + scoreText->update("0", engine->renderer); + + while (true) + { + + engine->startFrame(); + + engine->update(); + + if (engine->input.exit || engine->input.activeKeys[SDLK_ESCAPE]) + { + quit(); + } + + birdVelocity += birdGravity; + + if (engine->input.activeKeys[SDLK_SPACE] && !dead && jumpDelay == 0) + { + birdVelocity = birdJump; + flapSound->play(); + jumpDelay = 10; + } + + if (jumpDelay > 0) + { + jumpDelay--; + } + + birdY += birdVelocity; + birdAngle = birdVelocity * 3; + + engine->clear({ 0, 0, 0, 255 }); + backgroundSprite->draw(engine->renderer, "background"); + + pipeSprite->setPos({ pipeSet1[0], pipeSet1[1] - 320 }); + pipeSprite->draw(engine->renderer, "pipe", true, SDL_FLIP_VERTICAL); + pipeSprite->setPos({ pipeSet1[0], pipeSet1[1] + pipeGap }); + pipeSprite->draw(engine->renderer, "pipe"); + + pipeSprite->setPos({ pipeSet2[0], pipeSet2[1] - 320 }); + pipeSprite->draw(engine->renderer, "pipe", true, SDL_FLIP_VERTICAL); + pipeSprite->setPos({ pipeSet2[0], pipeSet2[1] + pipeGap }); + pipeSprite->draw(engine->renderer, "pipe"); + + pipeSet1[0] -= pipeSpeed; + pipeSet2[0] -= pipeSpeed; + + if (birdY >= 400 || birdY <= 0) + { + dead = true; + } + + if (birdSprite->dstrect.x + birdSprite->dstrect.w >= pipeSet1[0] && birdSprite->dstrect.x <= pipeSet1[0] + 52) + { + if (birdSprite->dstrect.y <= pipeSet1[1] || birdSprite->dstrect.y + birdSprite->dstrect.h >= pipeSet1[1] + pipeGap) + { + dead = true; + } + } + + if (birdSprite->dstrect.x + birdSprite->dstrect.w >= pipeSet2[0] && birdSprite->dstrect.x <= pipeSet2[0] + 52) + { + if (birdSprite->dstrect.y <= pipeSet2[1] || birdSprite->dstrect.y + birdSprite->dstrect.h >= pipeSet2[1] + pipeGap) + { + dead = true; + } + } + + if (birdSprite->dstrect.x >= pipeSet1[0] + 26 - 24 && birdSprite->dstrect.x <= pipeSet1[0] + 26 - 24 + pipeSpeed && !dead && scoreCooldown == 0) + { + score++; + scoreCooldown = 5; + pointSound->play(); + scoreText->update(std::to_string(score), engine->renderer); + } + + if (birdSprite->dstrect.x >= pipeSet2[0] + 26 - 24 && birdSprite->dstrect.x <= pipeSet2[0] + 26 - 24 + pipeSpeed && !dead && scoreCooldown == 0) + { + score++; + scoreCooldown = 5; + pointSound->play(); + scoreText->update(std::to_string(score), engine->renderer); + } + + if (scoreCooldown > 0) + { + scoreCooldown--; + } + + if (dead && !deathSoundPlayed) + { + pipeSpeed = 0; + groundSpeed = 0; + hitSound->play(); + dieSound->play(); + deathSoundPlayed = true; + } + + if (pipeSet1[0] <= -52) + { + pipeSet1[0] = 288; + pipeSet1[1] = random(120, 320 - pipeGap); + } + + if (pipeSet2[0] <= -52) + { + pipeSet2[0] = 288; + pipeSet2[1] = random(120, 320 - pipeGap); + } + + birdSprite->angle = birdAngle; + birdSprite->setPos({ 50, (int)birdY }); + birdAnimations->update(); + birdAnimations->draw(engine->renderer); + + for (int i = 0; i < 2; i++) + { + groundSprite->setPos({ groundPosx[i], 400 }); + groundSprite->draw(engine->renderer, "ground"); + groundPosx[i] -= groundSpeed; + if (groundPosx[i] <= -336) + { + groundPosx[i] = 336; + } + } + + scoreText->draw(engine->renderer, 144, 50); + engine->render(); + } + quit(); + return 0; +} \ No newline at end of file diff --git a/src/sound.cpp b/src/sound.cpp new file mode 100644 index 0000000..6232c1c --- /dev/null +++ b/src/sound.cpp @@ -0,0 +1,56 @@ +#include "sound.h" + +Music::Music(const char* path) +{ + music = Mix_LoadMUS(path); +} + +void Music::play(int loops) +{ + Mix_PlayMusic(music, loops); +} + +void Music::pause() +{ + Mix_PauseMusic(); +} + +void Music::stop() +{ + Mix_HaltMusic(); +} + +void Music::resume() +{ + Mix_ResumeMusic(); +} + +void Music::setVolume(int volume) +{ + Mix_VolumeMusic(volume); +} + +Music::~Music() +{ + Mix_FreeMusic(music); +} + +Effect::Effect(const char* path) +{ + effect = Mix_LoadWAV(path); +} + +void Effect::play(int loops, int channel) +{ + Mix_PlayChannel(channel, effect, loops); +} + +void Effect::setVolume(int volume) +{ + Mix_VolumeChunk(effect, volume); +} + +Effect::~Effect() +{ + Mix_FreeChunk(effect); +} \ No newline at end of file diff --git a/src/sprite.cpp b/src/sprite.cpp new file mode 100644 index 0000000..70fce1c --- /dev/null +++ b/src/sprite.cpp @@ -0,0 +1,164 @@ +#include "sprite.h" + +Sprite::Sprite(SDL_Renderer *renderer, SDL_Surface *surface) +{ + Texture = SDL_CreateTextureFromSurface(renderer, surface); + dstrect = { 0, 0, surface->w, surface->h }; +} + +Sprite::~Sprite() +{ + SDL_DestroyTexture(Texture); +} + +void Sprite::draw(SDL_Renderer* renderer, std::string frame, bool autoRect, SDL_RendererFlip flip) + { + if (frames.find(frame) == frames.end()) + { + printf("Frame not found\n"); + return; + } + if (autoRect) + { + dstrect = { dstrect.x, dstrect.y, frames[frame].w, frames[frame].h }; + } + SDL_SetTextureAlphaMod(Texture, 255); + dstrect.w *= scale.x; + dstrect.h *= scale.y; + SDL_RenderCopyEx(renderer, Texture, &frames[frame], &dstrect, angle, NULL, flip); +} + +void Sprite::addFrame(std::string name, SDL_Rect rect) +{ + frames[name] = rect; +} + +void Sprite::setPos(int_vec2 position) +{ + dstrect.x = position.x; + dstrect.y = position.y; +} + +void Sprite::move(int_vec2 position) +{ + dstrect.x += position.x; + dstrect.y += position.y; +} + +int_vec2 Sprite::getSize(std::string frame) +{ + size = { frames[frame].w, frames[frame].h }; + return size; +} + +void Sprite::autorect(std::string frame) +{ + dstrect = { dstrect.x, dstrect.y, frames[frame].w, frames[frame].h }; +} + + +Animation::Animation(std::map frames, Sprite* sprite, int frameDuration) +{ + this->sprite = sprite; + this->frameDuration = frameDuration; + + for (auto const& x : frames) + { + this->frames.push_back(x.first); + this->sprite->addFrame(x.first, x.second); + } + currentFrameName = this->frames[0]; +} + +void Animation::update() +{ + frameCounter++; + if (frameCounter >= frameDuration) + { + frameCounter = 0; + if (pingpong) + { + frameIndex += frameDirection; + if (frameIndex >= frames.size() - 1 || frameIndex <= 0) + { + if (!loop) + { + frameDirection = 0; + } else { + frameDirection *= -1; + } + } + } + else + { + frameIndex++; + if (frameIndex >= frames.size()) + { + if (!loop) + { + frameIndex = frames.size() - 1; + } else { + frameIndex = 0; + } + } + } + + + currentFrameName = frames[frameIndex]; + } +} + +void Animation::reset(bool ifFinish) +{ + if (ifFinish) + { + if (frameIndex == frames.size() - 1) + { + frameIndex = 0; + currentFrameName = frames[0]; + } + } else { + frameIndex = 0; + currentFrameName = frames[0]; + } +} + +void Animation::draw(SDL_Renderer* renderer, bool autoRect, bool flip) +{ + sprite->draw(renderer, currentFrameName, autoRect, flip ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE); +} + +AnimationManager::AnimationManager(Sprite* sprite) +{ + this->sprite = sprite; +} + +void AnimationManager::addAnimation(std::string name, std::map frames, int frameDuration, bool flip, bool autoRect, bool loop, bool pingpong) +{ + animations[name] = new Animation(frames, sprite, frameDuration); + this->flip[name] = flip; + this->autoRect[name] = autoRect; + animations[name]->loop = loop; + animations[name]->pingpong = pingpong; +} + void autorect(std::string frame); +void AnimationManager::setAnimation(std::string name) +{ + currentAnimation = name; +} + +void AnimationManager::update() +{ + animations[currentAnimation]->update(); +} + +void AnimationManager::draw(SDL_Renderer* renderer) +{ + animations[currentAnimation]->draw(renderer, autoRect[currentAnimation], flip[currentAnimation]); +} + +void AnimationManager::play(std::string name) +{ + setAnimation(name); + animations[currentAnimation]->reset(true); +} \ No newline at end of file diff --git a/src/text.cpp b/src/text.cpp new file mode 100644 index 0000000..60720ad --- /dev/null +++ b/src/text.cpp @@ -0,0 +1,30 @@ +#include "text.h" + +Text::Text(std::string font, int size, SDL_Color color) +{ + this->font = TTF_OpenFont(font.c_str(), size); + this->color = color; + rect = new SDL_Rect(); +} + +Text::~Text() +{ + SDL_FreeSurface(surface); + SDL_DestroyTexture(texture); + TTF_CloseFont(font); +} + +void Text::update(std::string text, SDL_Renderer* renderer) +{ + surface = TTF_RenderText_Solid(font, text.c_str(), color); + texture = SDL_CreateTextureFromSurface(renderer, surface); + rect->w = surface->w; + rect->h = surface->h; +} + +void Text::draw(SDL_Renderer* renderer, int x, int y) +{ + rect->x = x - rect->w / 2; + rect->y = y - rect->h / 2; + SDL_RenderCopy(renderer, texture, NULL, rect); +} \ No newline at end of file