diff --git a/README.md b/README.md index 56b6a97..73cd15b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ A bootleg "game engine" in c++, using SDL2 for rendering and input handling. ## Dependencies - SDL2 - SDL2_ttf +- SDL2_mixer ## Building ```bash diff --git a/example_assets/crystal_zone.mp3 b/example_assets/crystal_zone.mp3 new file mode 100644 index 0000000..2dca5b0 Binary files /dev/null and b/example_assets/crystal_zone.mp3 differ diff --git a/include/engine.h b/include/engine.h index 9cb3ac7..6edf820 100644 --- a/include/engine.h +++ b/include/engine.h @@ -5,12 +5,14 @@ #include #include #include +#include "sound.h" class Engine { private: const char* ctitle; int frameStart = 0; + bool soundInitialized = false; public: Input input; @@ -19,6 +21,7 @@ class Engine SDL_Renderer *renderer; Engine(std::string title, int width, int height); + void initSound(); void clear(SDL_Color color); void startFrame(); void render(); 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 index 990303e..11d9051 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -21,6 +21,7 @@ class Sprite void draw(SDL_Renderer* renderer, std::string frame, bool autoRect = true, bool flip = false); 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(); diff --git a/makefile b/makefile index 6e145e8..c270f46 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ CXX = g++ -LDFLAGS = `sdl2-config --libs` -l SDL2_ttf +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))) diff --git a/src/engine.cpp b/src/engine.cpp index 60737d3..4fbb0df 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -14,6 +14,13 @@ Engine::Engine(std::string title, int width, int height) 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 @@ -52,6 +59,12 @@ Engine::~Engine() 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/example-game.cpp b/src/example-game.cpp index 760507e..b934570 100644 --- a/src/example-game.cpp +++ b/src/example-game.cpp @@ -3,6 +3,7 @@ // Variables SDL_Surface* assets; +Music* music; Engine *engine; // Functions @@ -20,11 +21,13 @@ void quit() int main(int argc, char* argv[]) { engine = new Engine("Game", 800, 600); + engine->initSound(); engine->targetFrameRate = 60; // Load assets assets = SDL_LoadBMP("example_assets/sprites.bmp"); - + music = new Music("example_assets/crystal_zone.mp3"); + // frame map std::map idle = { { "idle", { 76, 456, 68, 128 } }, @@ -58,6 +61,9 @@ int main(int argc, char* argv[]) animations->addAnimation("walk_front", front, 10, false, true, true, true); animations->setAnimation("idle"); + // Play music + music->play(); + // Main loop while (true) { @@ -68,32 +74,30 @@ int main(int argc, char* argv[]) engine->update(); // Exit if window is closed - if (engine->input.exit) + if (engine->input.exit || engine->input.activeKeys[SDLK_ESCAPE]) { quit(); } if (engine->input.activeKeys[SDLK_d]) { - sprite->dstrect.x += 1; animations->setAnimation("walk_right"); + sprite->move({ 1, 0 }); } if (engine->input.activeKeys[SDLK_a]) { - sprite->dstrect.x -= 1; animations->setAnimation("walk_left"); - + sprite->move({ -1, 0 }); } if (engine->input.activeKeys[SDLK_w]) { - sprite->dstrect.y -= 1; animations->setAnimation("walk_back"); + sprite->move({ 0, -1 }); } if (engine->input.activeKeys[SDLK_s]) { - sprite->dstrect.y += 1; animations->setAnimation("walk_front"); - + sprite->move({ 0, 1 }); } if (!engine->input.activeKeys[SDLK_d] && !engine->input.activeKeys[SDLK_a] && !engine->input.activeKeys[SDLK_w] && !engine->input.activeKeys[SDLK_s]) { 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 index c309f4f..d68b61f 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -33,9 +33,16 @@ 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 = { position.x, position.y, dstrect.w, dstrect.h }; + dstrect.x += position.x; + dstrect.y += position.y; } int_vec2 Sprite::getSize(std::string frame)