diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2a3b61c..a4fc976 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,12 +8,21 @@ }, "runArgs": [ "--name=jelly-rescue-dev-cont", - "--net=host" + "--net=host", + "--privileged", + "--volume", "/dev/snd:/dev/snd", + "--volume", "/tmp/.X11-unix:/tmp/.X11-unix", + "--env", "DISPLAY=${localEnv:DISPLAY}" ], "workspaceFolder": "/app", "mounts": [ - "source=./src,target=/app/src,type=bind" + "source=./src,target=/app/src,type=bind", + "source=./scripts,target=/app/scripts,type=bind", + "source=./dist,target=/app/dist,type=bind", + "source=./assets,target=/app/assets,type=bind", + "source=./include,target=/app/include,type=bind" ], + "customizations": { "vscode": { "settings": {}, @@ -24,6 +33,4 @@ ] } }, - // "postCreateCommand": "/app/scripts/emsdk_setup.sh", - //"postStartCommand": "/app/scripts/emsdk_activate.sh" } diff --git a/.gitignore b/.gitignore index 259148f..bfc7430 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ *.exe *.out *.app + +/dist +**/SFML diff --git a/Dockerfile b/Dockerfile index 0628e8f..25c0935 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,6 @@ FROM gcc:latest as base -# RUN apt-get install cmake \ - # && rm -rf /var/cache/apt/* - - FROM base as development -# RUN apt-get update \ -# && apt-get install -y entr \ -# && rm -rf /var/cache/apt/* RUN apt-get update \ && apt-get install -y \ @@ -16,6 +9,7 @@ RUN apt-get update \ libasound2-dev libx11-dev libxrandr-dev libxi-dev libgl1-mesa-dev \ libglu1-mesa-dev libxcursor-dev libxinerama-dev libwayland-dev libxkbcommon-dev \ sudo \ + alsa-utils \ && rm -rf /var/cache/apt/* @@ -28,33 +22,45 @@ RUN chown -R dev:dev /app RUN echo "dev ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/dev && \ chmod 0440 /etc/sudoers.d/dev -COPY scripts ./scripts -RUN chmod +x /app/scripts/*.sh +# COPY scripts ./scripts +# RUN chmod +x /app/scripts/*.sh USER dev SHELL ["/bin/bash", "-c"] RUN g++ --version -RUN git clone https://github.com/emscripten-core/emsdk.git && \ - cd emsdk && \ +RUN git clone https://github.com/emscripten-core/emsdk.git libs/emsdk && \ + cd libs/emsdk && \ ./emsdk install latest && \ ./emsdk activate latest && \ - cd .. + cd ../.. -RUN echo 'source "/app/emsdk/emsdk_env.sh"' >> $HOME/.bash_profile +RUN echo 'source "/app/libs/emsdk/emsdk_env.sh"' >> $HOME/.bash_profile +# RUN source "/app/emsdk/emsdk_env.sh" -RUN git clone https://github.com/raysan5/raylib.git raylib \ - && cd raylib \ +RUN git clone https://github.com/raysan5/raylib.git libs/raylib \ + && cd libs/raylib \ && mkdir build && cd build \ - && cmake -DBUILD_SHARED_LIBS=ON .. \ + && cmake -DBUILD_SHARED_LIBS=OFF -DRAYLIB_STATIC=ON .. \ && make \ - && sudo make install + && sudo make install \ + && cd ../.. -# RUN git clone https://github.com/raysan5/raylib.git raylib \ -# && cd raylib \ -# && mkdir build && cd build \ -# && cmake -DBUILD_SHARED_LIBS=ON .. \ -# && make \ -# && make install +# RUN mkdir dist +# && cmake -DBUILD_SHARED_LIBS=ON .. \ + +ENV LD_LIBRARY_PATH=/app/libs/raylib/build/raylib + +RUN cd libs/raylib/src && \ + source /app/libs/emsdk/emsdk_env.sh && \ + emcc -c rcore.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 && \ + emcc -c rshapes.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 && \ + emcc -c rtextures.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 && \ + emcc -c rtext.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 && \ + emcc -c rmodels.c -Os -Wall -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 && \ + emcc -c utils.c -Os -Wall -DPLATFORM_WEB && \ + emcc -c raudio.c -Os -Wall -DPLATFORM_WEB && \ + emar rcs libraylib.a rcore.o rshapes.o rtextures.o rtext.o rmodels.o utils.o raudio.o && \ + cd ../.. CMD ["bash"] diff --git a/assets/Audio/Music/03_-_Medieval_Times.mp3 b/assets/Audio/Music/03_-_Medieval_Times.mp3 new file mode 100644 index 0000000..3e04a8c Binary files /dev/null and b/assets/Audio/Music/03_-_Medieval_Times.mp3 differ diff --git a/assets/Audio/Music/27_-_[Boss]_Neo_Cortex.mp3 b/assets/Audio/Music/27_-_[Boss]_Neo_Cortex.mp3 new file mode 100644 index 0000000..f8fb243 Binary files /dev/null and b/assets/Audio/Music/27_-_[Boss]_Neo_Cortex.mp3 differ diff --git a/assets/Audio/Music/Crash Bandicoot 3 Warped - Warp Room Theme.mp3 b/assets/Audio/Music/Crash Bandicoot 3 Warped - Warp Room Theme.mp3 new file mode 100644 index 0000000..0aa5841 Binary files /dev/null and b/assets/Audio/Music/Crash Bandicoot 3 Warped - Warp Room Theme.mp3 differ diff --git a/assets/Audio/Music/Crash_WarpRoomTheme.ogg b/assets/Audio/Music/Crash_WarpRoomTheme.ogg new file mode 100644 index 0000000..d84eece Binary files /dev/null and b/assets/Audio/Music/Crash_WarpRoomTheme.ogg differ diff --git a/assets/Audio/Music/GameTheme.ogg b/assets/Audio/Music/GameTheme.ogg new file mode 100644 index 0000000..30cc775 Binary files /dev/null and b/assets/Audio/Music/GameTheme.ogg differ diff --git a/assets/Audio/Music/GameTheme_2.ogg b/assets/Audio/Music/GameTheme_2.ogg new file mode 100644 index 0000000..4067a6c Binary files /dev/null and b/assets/Audio/Music/GameTheme_2.ogg differ diff --git a/assets/Audio/Music/gameOverTheme.ogg b/assets/Audio/Music/gameOverTheme.ogg new file mode 100644 index 0000000..f4a9e0c Binary files /dev/null and b/assets/Audio/Music/gameOverTheme.ogg differ diff --git a/assets/Audio/Music/gameOverTheme_2.ogg b/assets/Audio/Music/gameOverTheme_2.ogg new file mode 100644 index 0000000..75bf343 Binary files /dev/null and b/assets/Audio/Music/gameOverTheme_2.ogg differ diff --git a/assets/Audio/Sounds/WaterBalloon.wav b/assets/Audio/Sounds/WaterBalloon.wav new file mode 100644 index 0000000..69baf50 Binary files /dev/null and b/assets/Audio/Sounds/WaterBalloon.wav differ diff --git a/assets/Audio/Sounds/crateBreak.wav b/assets/Audio/Sounds/crateBreak.wav new file mode 100644 index 0000000..74765de Binary files /dev/null and b/assets/Audio/Sounds/crateBreak.wav differ diff --git a/assets/Audio/Sounds/gunShot.wav b/assets/Audio/Sounds/gunShot.wav new file mode 100644 index 0000000..548b15e Binary files /dev/null and b/assets/Audio/Sounds/gunShot.wav differ diff --git a/assets/Audio/Sounds/healmag.wav b/assets/Audio/Sounds/healmag.wav new file mode 100644 index 0000000..9ce1811 Binary files /dev/null and b/assets/Audio/Sounds/healmag.wav differ diff --git a/assets/Audio/Sounds/jellyFreed.wav b/assets/Audio/Sounds/jellyFreed.wav new file mode 100644 index 0000000..3bb129b Binary files /dev/null and b/assets/Audio/Sounds/jellyFreed.wav differ diff --git a/assets/Audio/Sounds/outOfAmmo.wav b/assets/Audio/Sounds/outOfAmmo.wav new file mode 100644 index 0000000..3288a00 Binary files /dev/null and b/assets/Audio/Sounds/outOfAmmo.wav differ diff --git a/assets/Audio/Sounds/pain.wav b/assets/Audio/Sounds/pain.wav new file mode 100644 index 0000000..df711e8 Binary files /dev/null and b/assets/Audio/Sounds/pain.wav differ diff --git a/assets/Audio/Sounds/playerSpotted.wav b/assets/Audio/Sounds/playerSpotted.wav new file mode 100644 index 0000000..853cf7c Binary files /dev/null and b/assets/Audio/Sounds/playerSpotted.wav differ diff --git a/assets/Audio/Sounds/powerUpSound.wav b/assets/Audio/Sounds/powerUpSound.wav new file mode 100644 index 0000000..110d51c Binary files /dev/null and b/assets/Audio/Sounds/powerUpSound.wav differ diff --git a/assets/Audio/Sounds/shotgunReload.wav b/assets/Audio/Sounds/shotgunReload.wav new file mode 100644 index 0000000..7a5c8e3 Binary files /dev/null and b/assets/Audio/Sounds/shotgunReload.wav differ diff --git a/assets/Audio/Sounds/victorySound.wav b/assets/Audio/Sounds/victorySound.wav new file mode 100644 index 0000000..9973188 Binary files /dev/null and b/assets/Audio/Sounds/victorySound.wav differ diff --git a/assets/Fonts/Gtek.ttf b/assets/Fonts/Gtek.ttf new file mode 100644 index 0000000..9e53294 Binary files /dev/null and b/assets/Fonts/Gtek.ttf differ diff --git a/assets/Fonts/Oxin.ttf b/assets/Fonts/Oxin.ttf new file mode 100644 index 0000000..75f4119 Binary files /dev/null and b/assets/Fonts/Oxin.ttf differ diff --git a/assets/Fonts/Reckoner.ttf b/assets/Fonts/Reckoner.ttf new file mode 100644 index 0000000..bf295b0 Binary files /dev/null and b/assets/Fonts/Reckoner.ttf differ diff --git a/assets/Fonts/Reckoner_Bold.ttf b/assets/Fonts/Reckoner_Bold.ttf new file mode 100644 index 0000000..4a887cb Binary files /dev/null and b/assets/Fonts/Reckoner_Bold.ttf differ diff --git a/assets/Fonts/Sansation.ttf b/assets/Fonts/Sansation.ttf new file mode 100644 index 0000000..d85fbc8 Binary files /dev/null and b/assets/Fonts/Sansation.ttf differ diff --git a/assets/Maps/colmap1.txt b/assets/Maps/colmap1.txt new file mode 100644 index 0000000..816942c --- /dev/null +++ b/assets/Maps/colmap1.txt @@ -0,0 +1,21 @@ +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 +1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + diff --git a/assets/Maps/map1.txt b/assets/Maps/map1.txt new file mode 100644 index 0000000..bbcb697 --- /dev/null +++ b/assets/Maps/map1.txt @@ -0,0 +1,18 @@ +Data/Textures/tileset.png +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 02,06 xx,xx xx,xx xx,xx 02,06 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 03,06 03,05 xx,xx xx,xx xx,xx 03,05 03,06 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 02,06 03,05 03,05 xx,xx xx,xx xx,xx 03,05 03,05 02,06 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 +xx,xx xx,xx xx,xx xx,xx xx,xx xx,xx 12,04 12,03 13,03 13,04 xx,xx xx,xx 02,06 03,06 02,07 03,07 02,07 xx,xx xx,xx xx,xx 02,07 03,07 02,07 03,06 12,03 13,03 00,00 xx,xx xx,xx 00,00 09,00 09,00 00,00 xx,xx xx,xx 00,00 09,00 09,00 09,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 xx,xx xx,xx 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 00,00 \ No newline at end of file diff --git a/assets/Textures/Bullets_small.png b/assets/Textures/Bullets_small.png new file mode 100644 index 0000000..80e5418 Binary files /dev/null and b/assets/Textures/Bullets_small.png differ diff --git a/assets/Textures/FirstAidKit.png b/assets/Textures/FirstAidKit.png new file mode 100644 index 0000000..bb2cd8e Binary files /dev/null and b/assets/Textures/FirstAidKit.png differ diff --git a/assets/Textures/GameBackground_1.png b/assets/Textures/GameBackground_1.png new file mode 100644 index 0000000..fb1dfbc Binary files /dev/null and b/assets/Textures/GameBackground_1.png differ diff --git a/assets/Textures/GameBackground_2.jpg b/assets/Textures/GameBackground_2.jpg new file mode 100644 index 0000000..4ecc462 Binary files /dev/null and b/assets/Textures/GameBackground_2.jpg differ diff --git a/assets/Textures/GameBackground_3.png b/assets/Textures/GameBackground_3.png new file mode 100644 index 0000000..5d487f7 Binary files /dev/null and b/assets/Textures/GameBackground_3.png differ diff --git a/assets/Textures/Thumbs.db b/assets/Textures/Thumbs.db new file mode 100644 index 0000000..02eaeb5 Binary files /dev/null and b/assets/Textures/Thumbs.db differ diff --git a/assets/Textures/TitleScreenBackground.png b/assets/Textures/TitleScreenBackground.png new file mode 100644 index 0000000..8c4bbb7 Binary files /dev/null and b/assets/Textures/TitleScreenBackground.png differ diff --git a/assets/Textures/TutorialBackground.png b/assets/Textures/TutorialBackground.png new file mode 100644 index 0000000..38d9c25 Binary files /dev/null and b/assets/Textures/TutorialBackground.png differ diff --git a/assets/Textures/TutorialBackground2.png b/assets/Textures/TutorialBackground2.png new file mode 100644 index 0000000..7cb6fe4 Binary files /dev/null and b/assets/Textures/TutorialBackground2.png differ diff --git a/assets/Textures/VictoryScreenBackground.png b/assets/Textures/VictoryScreenBackground.png new file mode 100644 index 0000000..e280433 Binary files /dev/null and b/assets/Textures/VictoryScreenBackground.png differ diff --git a/assets/Textures/bullet_hud.png b/assets/Textures/bullet_hud.png new file mode 100644 index 0000000..f3e97e4 Binary files /dev/null and b/assets/Textures/bullet_hud.png differ diff --git a/assets/Textures/crosshair_3.png b/assets/Textures/crosshair_3.png new file mode 100644 index 0000000..976c520 Binary files /dev/null and b/assets/Textures/crosshair_3.png differ diff --git a/assets/Textures/enemy.png b/assets/Textures/enemy.png new file mode 100644 index 0000000..9634995 Binary files /dev/null and b/assets/Textures/enemy.png differ diff --git a/assets/Textures/flag.png b/assets/Textures/flag.png new file mode 100644 index 0000000..b0d429e Binary files /dev/null and b/assets/Textures/flag.png differ diff --git a/assets/Textures/gunleft.png b/assets/Textures/gunleft.png new file mode 100644 index 0000000..378b29f Binary files /dev/null and b/assets/Textures/gunleft.png differ diff --git a/assets/Textures/gunleft_2.png b/assets/Textures/gunleft_2.png new file mode 100644 index 0000000..baa108d Binary files /dev/null and b/assets/Textures/gunleft_2.png differ diff --git a/assets/Textures/gunright.png b/assets/Textures/gunright.png new file mode 100644 index 0000000..b0c3790 Binary files /dev/null and b/assets/Textures/gunright.png differ diff --git a/assets/Textures/gunright_2.png b/assets/Textures/gunright_2.png new file mode 100644 index 0000000..f5e50c0 Binary files /dev/null and b/assets/Textures/gunright_2.png differ diff --git a/assets/Textures/happyjelly.png b/assets/Textures/happyjelly.png new file mode 100644 index 0000000..dfd6f6c Binary files /dev/null and b/assets/Textures/happyjelly.png differ diff --git a/assets/Textures/happyjelly2.png b/assets/Textures/happyjelly2.png new file mode 100644 index 0000000..aa2501f Binary files /dev/null and b/assets/Textures/happyjelly2.png differ diff --git a/assets/Textures/happyjelly_icon.ico b/assets/Textures/happyjelly_icon.ico new file mode 100644 index 0000000..0cd7a36 Binary files /dev/null and b/assets/Textures/happyjelly_icon.ico differ diff --git a/assets/Textures/heart.png b/assets/Textures/heart.png new file mode 100644 index 0000000..c733c24 Binary files /dev/null and b/assets/Textures/heart.png differ diff --git a/assets/Textures/heart_empty.png b/assets/Textures/heart_empty.png new file mode 100644 index 0000000..5e14740 Binary files /dev/null and b/assets/Textures/heart_empty.png differ diff --git a/assets/Textures/player.png b/assets/Textures/player.png new file mode 100644 index 0000000..899f2a1 Binary files /dev/null and b/assets/Textures/player.png differ diff --git a/assets/Textures/powerUpAnimation.png b/assets/Textures/powerUpAnimation.png new file mode 100644 index 0000000..28185d5 Binary files /dev/null and b/assets/Textures/powerUpAnimation.png differ diff --git a/assets/Textures/tileset.png b/assets/Textures/tileset.png new file mode 100644 index 0000000..5a558ef Binary files /dev/null and b/assets/Textures/tileset.png differ diff --git a/assets/Textures/woodencrate.png b/assets/Textures/woodencrate.png new file mode 100644 index 0000000..91ba721 Binary files /dev/null and b/assets/Textures/woodencrate.png differ diff --git a/include/entities/Background.h b/include/entities/Background.h new file mode 100644 index 0000000..dc9ad8b --- /dev/null +++ b/include/entities/Background.h @@ -0,0 +1,45 @@ +#ifndef BACKGROUND_H +#define BACKGROUND_H + +#include "raylib.h" +#include "enums/EBackground.h" +#include +#include "entities/TextureWrapper.h" +#include "services/AssetService.h" +#include "services/StateService.h" + +class Background { + public: + Background() { + + } + Background(EBackground background){ + // Texture2D texture = AssetService::getInstance().getBackground(background); + TextureWrapper wrapper = TextureWrapper(AssetService::getInstance().getBackground(background), StateService::getInstance().getScreenSize(), {0,0}); + wrapper.setSourceRect({0,0,wrapper.getSize().x, wrapper.getSize().y}); + textures.push_back(wrapper); + } + Background(std::vector backgrounds){ + for(int i = 0; i < backgrounds.size(); i++) { + this->textures.push_back(backgrounds[i]); + } + } + ~Background(){} + // Vector2 getPosition(); + // void updatePosition(Vector2 deltaPos); + // void setPosition(Vector2 position); + void draw(){ + for(int i = 0; i < textures.size(); i++) { + TextureWrapper texture = textures[i]; + // Rectangle sourceRect = {0, 0, texture.getSize().x, texture.getSize().y}; + DrawTextureRec(texture.getTexture(), texture.getSourceRect(), texture.getPosition(),WHITE); + } + } + private: + std::vector textures; + // Vector2 position; + // Vector2 size; +}; + + +#endif \ No newline at end of file diff --git a/include/entities/Game.h b/include/entities/Game.h new file mode 100644 index 0000000..71491ce --- /dev/null +++ b/include/entities/Game.h @@ -0,0 +1,90 @@ +#ifndef GAME_H +#define GAME_H + +#include "entities/Map.h" +#include "entities/Background.h" +#include "services/StateService.h" +#include "services/AudioService.h" +#include "services/MapService.h" +#include "services/InputService.h" +#include "entities/Player.h" + +class Game +{ +public: + Game() + { + TextureWrapper wrapper1 = TextureWrapper(AssetService::getInstance().getBackground(EBackground::GAME1), {GetScreenWidth()*2.0f,(float)GetScreenHeight()}, {0,0}); + wrapper1.setSourceRect({0,0,wrapper1.getSize().x, wrapper1.getSize().y}); + TextureWrapper wrapper2 = TextureWrapper(AssetService::getInstance().getBackground(EBackground::GAME2), {864.0f,(float)GetScreenHeight()}, {wrapper1.getSize().x,0.0}); + wrapper2.setSourceRect({0,200,wrapper2.getSize().x, 200+wrapper2.getSize().y}); + TextureWrapper wrapper3 = TextureWrapper(AssetService::getInstance().getBackground(EBackground::GAME3), {1792.0f,(float)GetScreenHeight()}, {wrapper1.getSize().x+wrapper2.getSize().x,0.0}); + wrapper3.setSourceRect({64,200,64+wrapper3.getSize().x, 200+wrapper3.getSize().y}); + + std::vector wrappers; + wrappers.push_back(wrapper1); + wrappers.push_back(wrapper2); + wrappers.push_back(wrapper3); + this->background = Background(wrappers); + this->map = Map(); + MapService::getInstance().setMap(this->map); + + Vector2 screenSize = StateService::getInstance().getScreenSize(); + Camera2D camera = {0}; + camera.offset = (Vector2){screenSize.x / 2.0f, screenSize.y / 2.0f}; // Set offset to center + camera.target = (Vector2){screenSize.x / 2.0f, screenSize.y / 2.0f}; // Initially at the center of the world + camera.rotation = 0.0f; + camera.zoom = 1.0f; + this->camera = camera; + + this->player = Player(); + this->player.getTexture().setPosition({200,350}); + + InputService::getInstance().setKeysToWatch({KEY_SPACE, KEY_A, KEY_D}, {MOUSE_BUTTON_LEFT}); + + AudioService::getInstance().setMusic(EMusic::GAME); + AudioService::getInstance().playMusic(); + } + ~Game() + { + } + + void logic() + { + // this->camera.offset.x -= 1.5; + this->player.logic(); + if(this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f)) { + this->camera.offset = {(StateService::getInstance().getScreenSize().x / 2.0f) +((StateService::getInstance().getScreenSize().x / 2.0f) - this->player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f}; + + } + } + + void draw() + { + BeginDrawing(); + BeginMode2D(this->camera); + + this->background.draw(); + this->map.draw(); + this->player.draw(); + + EndMode2D(); + EndDrawing(); + } + +private: + Camera2D camera; + Background background; + Map map; + Player player; + // std::vector enemies + // std::vector crates + // std::vector playerBullets + // std::vector enemyBullets + // std::vector jellies + // std::vector ammo + // std::vector healthpacks + // Powerup powerup +}; + +#endif \ No newline at end of file diff --git a/include/entities/Map.h b/include/entities/Map.h new file mode 100644 index 0000000..7aeece0 --- /dev/null +++ b/include/entities/Map.h @@ -0,0 +1,47 @@ +#ifndef MAP_H +#define MAP_H + +#include +#include "raylib.h" +#include "entities/TextureWrapper.h" +#include + +/** + * Holds the collision and texture maps for the game world + */ +class Map +{ +public: + Map(); + ~Map() {} + + void draw(); + + /** Checks and returns which corners of the object have been collided with */ + std::unordered_map checkForCollision(TextureWrapper texture); + + int getTileSize() { + return this->tileSize; + } + +private: + /** Holds the number for every single tile, which refers to a certain sprite in the tileset */ + std::vector> map; + /** Holds 1s (collision) and 0s (no collision) for every tile */ + std::vector> colMap; + + unsigned int tileSize = 32; + + Texture2D tileset; + + void loadMap(); + void loadColMap(); + void loadTileset(); + + /** + * Converts the corners of the object to the matching tiles, so that they can be checked for collision + */ + std::unordered_map cornersToTilePos(std::unordered_map corners); +}; + +#endif \ No newline at end of file diff --git a/include/entities/Player.h b/include/entities/Player.h new file mode 100644 index 0000000..eea1a0b --- /dev/null +++ b/include/entities/Player.h @@ -0,0 +1,123 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include "raylib.h" +#include +#include "services/AssetService.h" +#include "services/MapService.h" +#include "services/InputService.h" +#include "entities/TextureWrapper.h" +#include "enums/ECorner.h" + +class Player +{ +public: + Player() + { + TextureWrapper wrapper = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER), {32, 32}, {200, 200}); + wrapper.setSourceRect({0, 0, 32, 32}); + this->texture = wrapper; + } + ~Player() + { + } + + void logic() + { + gravity(); + movement(); + handleCollision(); + } + + void draw() + { + DrawTextureRec(this->texture.getTexture(), this->texture.getSourceRect(), this->texture.getPosition(), WHITE); + } + + TextureWrapper &getTexture() + { + return this->texture; + } + +protected: +private: + TextureWrapper texture; + Vector2 velocity = {0, 0}; + + std::vector timesCollision; // Holds the amount of times the player has collided with a tile, and which corner of the player is touching a tile + bool groundCollision; // Keeps track of whether or not the player has collided with the ground + bool crateTopCollision; + /** + * Holds the corners of the player + * Is used for precise collision detection + */ + + void gravity() + { + if (!groundCollision) + { + velocity.y += 0.6f; + } + else + { + // velocity.y = 0.0f; + } + } + + void movement() + { + velocity.x = 0.0f; + if (InputService::getInstance().isKeyDown(KEY_A)) + { + velocity.x -= 5.0f; + } + else if (InputService::getInstance().isKeyDown(KEY_D)) + { + velocity.x += 5.0f; + } + + if (InputService::getInstance().isKeyPressed(KEY_SPACE) && groundCollision) + { + velocity.y -= 7.2f; + } + } + + /** + * Stores the current position + * Applies the current velocity + * Checks for collision, and removes all velocities that are causing collisions + * Set the object exactly against the object it is colliding with position + */ + void handleCollision() + { + Vector2 tempPos = this->texture.getPosition(); + this->texture.move(velocity); + + groundCollision = false; + std::unordered_map collisions = MapService::getInstance().getMap().checkForCollision(this->texture); + + if (collisions[ECorner::BOTTOM_LEFT] || collisions[ECorner::BOTTOM_RIGHT]) + { + velocity.y = 0.0f; + groundCollision = true; + this->texture.setPosition({this->texture.getPosition().x, floorf(this->texture.getPosition().y / MapService::getInstance().getMap().getTileSize()) * MapService::getInstance().getMap().getTileSize()}); + } + if (collisions[ECorner::LEFT_TOP] && collisions[ECorner::LEFT_BOTTOM]) + { + velocity.x = 0.0f; + this->texture.setPosition({ceilf(this->texture.getPosition().x / MapService::getInstance().getMap().getTileSize()) * MapService::getInstance().getMap().getTileSize(), this->texture.getPosition().y}); + } + if (collisions[ECorner::TOP_LEFT] || collisions[ECorner::TOP_RIGHT]) + { + velocity.y = 0.0f; + this->texture.setPosition({this->texture.getPosition().x, (ceilf(this->texture.getPosition().y / MapService::getInstance().getMap().getTileSize())) * MapService::getInstance().getMap().getTileSize()}); + } + if (collisions[ECorner::RIGHT_TOP] && collisions[ECorner::RIGHT_BOTTOM]) + { + velocity.x = 0.0f; + this->texture.setPosition({floorf(this->texture.getPosition().x / MapService::getInstance().getMap().getTileSize()) * MapService::getInstance().getMap().getTileSize(), this->texture.getPosition().y}); + } + } +}; + +#endif diff --git a/include/entities/Text.h b/include/entities/Text.h new file mode 100644 index 0000000..21dd3b0 --- /dev/null +++ b/include/entities/Text.h @@ -0,0 +1,48 @@ +#ifndef TEXT_H +#define TEXT_H + +#include "raylib.h" +#include "enums/EFont.h" +#include +#include +#include "services/AssetService.h" + +class Text { + public: + Text(std::string text, EFont font, int fontSize = 30, int spacing = 0, Color color = WHITE, Vector2 position = {100,100}); + ~Text(){} + + Vector2 getDimensions(); + + void setPosition(Vector2 position) { + this->position = position; + } + + void setColor(Color color) { + this->color = color; + } + + void setText(std::string text) { + this->text = text; + } + + Vector2 getPosition() { + return position; + } + + std::string getText() { + return this->text; + } + + void draw(); + + private: + std::string text; + Font font; + int fontSize; + int spacing; + Color color; + Vector2 position; +}; + +#endif \ No newline at end of file diff --git a/include/entities/TextureWrapper.h b/include/entities/TextureWrapper.h new file mode 100644 index 0000000..accd1c8 --- /dev/null +++ b/include/entities/TextureWrapper.h @@ -0,0 +1,75 @@ +#ifndef TEXTURE_WRAPPER_H +#define TEXTURE_WRAPPER_H + +#include "raylib.h" +#include "enums/ECorner.h" +#include + +class TextureWrapper { + public: + TextureWrapper(){} + TextureWrapper(Texture2D texture, Vector2 size = {32,32}, Vector2 position = {0,0}, Rectangle sourceRect = {0,0,32,32}) { + this->texture = texture; + this->size = size; + this->position = position; + } + ~TextureWrapper() { + + } + + Texture2D getTexture() { + return this->texture; + } + + Rectangle getSourceRect(){ + return this->sourceRect; + } + + Vector2 getSize() { + return this->size; + } + + Vector2 getPosition() { + return this->position; + } + + void setSourceRect(Rectangle rect) { + this->sourceRect = rect; + } + + void setPosition(Vector2 position) { + this->position = position; + } + + void move(Vector2 deltaPos) { + this->position = {this->position.x + deltaPos.x, this->position.y + deltaPos.y}; + } + + /** Returns the 4 corners of the texture */ + std::unordered_map getCorners() { + std::unordered_map corners; + float top = this->position.y; + float right = this->position.x+this->size.x; + float bottom = this->position.y + this->size.y; + float left = this->position.x; + float margin = 8; // Space to the corner + corners[ECorner::TOP_LEFT] = {left+margin, top}; + corners[ECorner::TOP_RIGHT] = {right-margin, top}; + corners[ECorner::RIGHT_TOP] = {right, top+margin}; + corners[ECorner::RIGHT_BOTTOM] = {right, bottom-margin}; + corners[ECorner::BOTTOM_RIGHT] = {right-margin, bottom}; + corners[ECorner::BOTTOM_LEFT] = {left+margin, bottom}; + corners[ECorner::LEFT_BOTTOM] = {left, bottom-margin}; + corners[ECorner::LEFT_TOP] = {left, top+margin}; + + return corners; + } + + private: + Texture2D texture; + Rectangle sourceRect; + Vector2 size; + Vector2 position; +}; + +#endif \ No newline at end of file diff --git a/include/enums/EBackground.h b/include/enums/EBackground.h new file mode 100644 index 0000000..166bb44 --- /dev/null +++ b/include/enums/EBackground.h @@ -0,0 +1,13 @@ +#ifndef EBACKGROUND_H +#define EBACKGROUND_H + +enum class EBackground { + TUTORIAL, + GAME1, + GAME2, + GAME3, + VICTORY +}; + + +#endif \ No newline at end of file diff --git a/include/enums/ECorner.h b/include/enums/ECorner.h new file mode 100644 index 0000000..e4d46db --- /dev/null +++ b/include/enums/ECorner.h @@ -0,0 +1,19 @@ +#ifndef CORNERS_H +#define CORNERS_H + +/** + * All corners of a GameObject + */ +enum class ECorner { + TOP_LEFT, + TOP_RIGHT, + RIGHT_TOP, + RIGHT_BOTTOM, + BOTTOM_RIGHT, + BOTTOM_LEFT, + LEFT_BOTTOM, + LEFT_TOP +}; + + +#endif \ No newline at end of file diff --git a/include/enums/EFont.h b/include/enums/EFont.h new file mode 100644 index 0000000..598b745 --- /dev/null +++ b/include/enums/EFont.h @@ -0,0 +1,15 @@ +#ifndef EFONT_H +#define EFONT_H + +/** + * All available fonts + */ +enum class EFont { + GTEK, + OXIN, + RECKONER_BOLD, + RECKONER, + SANSATION, +}; + +#endif \ No newline at end of file diff --git a/include/enums/EMap.h b/include/enums/EMap.h new file mode 100644 index 0000000..c9f64c1 --- /dev/null +++ b/include/enums/EMap.h @@ -0,0 +1,10 @@ +#ifndef EMAP_H +#define EMAP_H + +enum class EMap { + TEXTURE, + COLLISION +}; + + +#endif \ No newline at end of file diff --git a/include/enums/EMusic.h b/include/enums/EMusic.h new file mode 100644 index 0000000..40739c3 --- /dev/null +++ b/include/enums/EMusic.h @@ -0,0 +1,11 @@ +#ifndef EMUSIC_H +#define EMUSIC_H + +enum class EMusic { + NONE, + MAIN, + GAME, + GAME_OVER +}; + +#endif \ No newline at end of file diff --git a/include/enums/EScreen.h b/include/enums/EScreen.h new file mode 100644 index 0000000..42b42e2 --- /dev/null +++ b/include/enums/EScreen.h @@ -0,0 +1,18 @@ +#ifndef ESCREEN_H +#define ESCREEN_H + +/** + * All possible screens that the game can be displaying + */ +enum class EScreen { + TITLE, + MAIN, + TUTORIAL, + GAME, + PAUSE, + GAMEOVER, + VICTORY, + CLOSE +}; + +#endif \ No newline at end of file diff --git a/include/enums/ESprite.h b/include/enums/ESprite.h new file mode 100644 index 0000000..5e70281 --- /dev/null +++ b/include/enums/ESprite.h @@ -0,0 +1,21 @@ +#ifndef ESPRITE_H +#define ESPRITE_H + +enum class ESprite { + PLAYER, + PLAYER_GUN_LEFT, + PLAYER_GUN_RIGHT, + ENEMY, + ENEMY_GUN_LEFT, + ENEMY_GUN_RIGHT, + CRATE, + JELLY, + HEALTHPACK, + AMMOPACK, + POWERUP, + HUD_HEART, + HUD_HEART_EMPTY, + HUD_AMMO +}; + +#endif \ No newline at end of file diff --git a/include/screens/GameScreen.h b/include/screens/GameScreen.h new file mode 100644 index 0000000..a5e7582 --- /dev/null +++ b/include/screens/GameScreen.h @@ -0,0 +1,18 @@ +#ifndef GAME_SCREEN_H +#define GAME_SCREEN_H + +#include "screens/Screen.h" +#include "entities/Game.h" + +class GameScreen: public Screen { + +public: + GameScreen(); + void logic() override; + void draw() override; + +private: + Game game; +}; + +#endif \ No newline at end of file diff --git a/include/screens/MainScreen.h b/include/screens/MainScreen.h new file mode 100644 index 0000000..34ecc0b --- /dev/null +++ b/include/screens/MainScreen.h @@ -0,0 +1,24 @@ +#ifndef MAIN_SCREEN_H +#define MAIN_SCREEN_H + +#include "screens/Screen.h" +#include +#include "entities/Text.h" + +class MainScreen : public Screen { +public: + MainScreen(); + + void logic() override; + void draw() override; + +private: + int hoveredButton = 0; + std::vector buttons; + + void mouseLogic(); + void keyboardLogic(); + void clickLogic(); +}; + +#endif \ No newline at end of file diff --git a/include/screens/Screen.h b/include/screens/Screen.h new file mode 100644 index 0000000..90270ec --- /dev/null +++ b/include/screens/Screen.h @@ -0,0 +1,23 @@ +#ifndef SCREEN_H +#define SCREEN_H + +class Screen +{ +public: + Screen(){} + ~Screen() {} + + /** + * Execute all logic for this frame + */ + virtual void logic() = 0; + /** + * Draw frame to the screen + */ + virtual void draw() = 0; + +private: + +}; + +#endif diff --git a/include/screens/TitleScreen.h b/include/screens/TitleScreen.h new file mode 100644 index 0000000..7975eaa --- /dev/null +++ b/include/screens/TitleScreen.h @@ -0,0 +1,20 @@ +#ifndef TITLE_SCREEN_H +#define TITLE_SCREEN_H + +#include "screens/Screen.h" +#include "raylib.h" +#include "entities/Text.h" + +class TitleScreen : public Screen { +public: + TitleScreen(); + + void logic() override; + void draw() override; + +private: + Music bg; + std::vector text; +}; + +#endif \ No newline at end of file diff --git a/include/screens/TutorialScreen.h b/include/screens/TutorialScreen.h new file mode 100644 index 0000000..2b48387 --- /dev/null +++ b/include/screens/TutorialScreen.h @@ -0,0 +1,22 @@ +#ifndef TUTORIAL_SCREEN_H +#define TUTORIAL_SCREEN_H + +#include "screens/Screen.h" +#include "entities/Background.h" +#include "entities/Text.h" + +class TutorialScreen : public Screen +{ +public: + TutorialScreen(); + ~TutorialScreen() {} + + void logic() override; + void draw() override; + +private: + std::vector text; + Background background; +}; + +#endif \ No newline at end of file diff --git a/include/services/AssetService.h b/include/services/AssetService.h new file mode 100644 index 0000000..5eec69e --- /dev/null +++ b/include/services/AssetService.h @@ -0,0 +1,57 @@ +#ifndef ASSET_SERVICE_H +#define ASSET_SERVICE_H + +#include "raylib.h" +#include +#include +#include +#include "enums/EFont.h" +#include "enums/EMusic.h" +#include "enums/EBackground.h" +#include "enums/EMap.h" +#include "enums/ESprite.h" +#include "services/Service.h" + +class AssetService: public Service +{ +public: + void setAssetDir(std::string assetDir){this->assetDir = assetDir;} + + Font getFont(EFont font, int fontSize); + Music getMusic(EMusic music) { + return this->music[music]; + } + Texture2D getBackground(EBackground background){ + return this->backgrounds[background]; + } + Texture2D loadTexture(std::string filename); + std::string getMapUrl(EMap map) { + return this->assetDir + this->maps[map]; + } + Texture2D getSprite(ESprite sprite) { + return this->sprites[sprite]; + } + +protected: + AssetService(); + +private: + /** Friend to allow access to the constructor */ + friend class Service; + + std::string assetDir; + std::unordered_map fonts; + std::vector sounds; + std::unordered_map music; + std::unordered_map backgrounds; + std::unordered_map maps; + std::unordered_map sprites; + + void setAssets(); + + Music loadMusic(std::string filename, bool loops); + Sound loadSound(std::string filename); + std::string getFontUrl(EFont font); +}; + +#endif \ No newline at end of file diff --git a/include/services/AudioService.h b/include/services/AudioService.h new file mode 100644 index 0000000..d065b67 --- /dev/null +++ b/include/services/AudioService.h @@ -0,0 +1,30 @@ +#ifndef AUDIO_SERVICE_H +#define AUDIO_SERVICE_H + +#include "raylib.h" +#include "enums/EMusic.h" +#include "services/Service.h" +#include + +class AudioService : public Service +{ +public: + void setMusic(EMusic music); + std::optional getMusic(){return music;} + EMusic getCurrentTrack(){return currentTrack;} + void playMusic(); + void pauseMusic(); + void stopMusic(); + + void playSound(); + void stopSounds(); + +protected: + +private: + std::optional music; + EMusic currentTrack = EMusic::NONE; + +}; + +#endif \ No newline at end of file diff --git a/include/services/InputService.h b/include/services/InputService.h new file mode 100644 index 0000000..e7f537b --- /dev/null +++ b/include/services/InputService.h @@ -0,0 +1,101 @@ +#ifndef INPUT_SERVICE_H +#define INPUT_SERVICE_H + +#include "Service.h" +#include "raylib.h" +#include +#include +#include + +/** + * Tracks all user input, which is then retrieved by the screens + */ +class InputService : public Service +{ +public: + /** + * Setting up the keys to watch, so that only the keys that might get pressed are being watched + */ + void setKeysToWatch(std::vector keysToWatch, std::vector mouseButtonsToWatch) + { + this->watchedKeys.clear(); + this->keysPressed.clear(); + this->keysDown.clear(); + + for (int i = 0; i < keysToWatch.size(); i++) + { + this->watchedKeys.insert(keysToWatch[i]); + this->keysPressed[keysToWatch[i]] = false; + this->keysDown[keysToWatch[i]] = false; + } + + setMouseButtonsToWatch(mouseButtonsToWatch); + } + + /** + * Checks if a button has been pressed + * The flow: + * 1. Screen constructor: Announce which keys to watch + * 2. StateService loop: Check keys, store the result + * 3. Screen logic: If pressed, execute logic + */ + void checkKeys() + { + for (auto key : watchedKeys) + { + keysPressed[key] = false; + keysDown[key] = false; + if (IsKeyPressed(key)) + { + keysPressed[key] = true; + } + if (IsKeyDown(key)) + { + keysDown[key] = true; + } + } + for (auto button : watchedMouseButtons) + { + mouseButtonsPressed[button] = false; + if (IsMouseButtonPressed(button)) + { + mouseButtonsPressed[button] = true; + } + } + } + + bool isKeyPressed(KeyboardKey key) + { + return keysPressed[key]; + } + + bool isKeyDown(KeyboardKey key) { + return keysDown[key]; + } + + bool isMouseButtonPressed(MouseButton button) + { + return mouseButtonsPressed[button]; + } + +private: + std::unordered_set watchedKeys; + std::unordered_map keysPressed; + std::unordered_map keysDown; + std::unordered_set watchedMouseButtons; + std::unordered_map mouseButtonsPressed; + + void setMouseButtonsToWatch(std::vector mouseButtonsToWatch) + { + this->watchedMouseButtons.clear(); + this->mouseButtonsPressed.clear(); + + for (int i = 0; i < mouseButtonsToWatch.size(); i++) + { + this->watchedMouseButtons.insert(mouseButtonsToWatch[i]); + this->mouseButtonsPressed[mouseButtonsToWatch[i]] = false; + } + } +}; + +#endif \ No newline at end of file diff --git a/include/services/MapService.h b/include/services/MapService.h new file mode 100644 index 0000000..139a60d --- /dev/null +++ b/include/services/MapService.h @@ -0,0 +1,27 @@ +#ifndef MAP_SERVICE_H +#define MAP_SERVICE_H + +#include "services/Service.h" +#include "entities/Map.h" +#include "entities/TextureWrapper.h" + +/** + * Allows all rigidbodies to check against the current Map + */ +class MapService : public Service +{ +public: + void setMap(Map map) + { + this->map = Map(); + } + + Map& getMap() { + return this->map; + } + +private: + Map map; +}; + +#endif \ No newline at end of file diff --git a/include/services/Service.h b/include/services/Service.h new file mode 100644 index 0000000..e76e147 --- /dev/null +++ b/include/services/Service.h @@ -0,0 +1,25 @@ +#ifndef SERVICE_H +#define SERVICE_H + +template +class Service +{ +public: + Service(const Service &) = delete; + Service &operator=(const Service &) = delete; + + static T& getInstance() + { + static T instance; + return instance; + } + +protected: + static T* instance; + Service() {} + +private: + +}; + +#endif \ No newline at end of file diff --git a/include/services/StateService.h b/include/services/StateService.h new file mode 100644 index 0000000..01960b6 --- /dev/null +++ b/include/services/StateService.h @@ -0,0 +1,61 @@ +#ifndef STATE_SERVICE_H +#define STATE_SERVICE_H + +#include +#include +#include "services/Service.h" +#include "screens/Screen.h" +#include "enums/EScreen.h" +#include "raylib.h" + +#if defined(PLATFORM_WEB) +#include +#endif + +/** + * Handles switching between screens + */ +class StateService : public Service +{ +public: + Vector2 getScreenSize() + { + return screenSize; + } + void setScreenSize(Vector2 screenSize) + { + this->screenSize = screenSize; + } + void setScreen(EScreen screen); + Screen *getScreen(); + /** + * Start the game loop + */ + void startGame(); + + static void staticStep() + { + if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + std::cout << "Input!" << std::endl; + } + // Access the singleton instance and call step + getInstance().step(); + } + +private: + std::unique_ptr currentScreen; + + bool gameRunning = true; + + Vector2 screenSize; + + /** + * One step of the gameloop + */ + void step(); + + void handleMusic(); +}; + +#endif \ No newline at end of file diff --git a/scripts/build_and_run_project.sh b/scripts/build_and_run_project.sh index daa81bf..96d0c67 100755 --- a/scripts/build_and_run_project.sh +++ b/scripts/build_and_run_project.sh @@ -1,4 +1,6 @@ #!/bin/bash clear -g++ src/main.cpp -o dist/websort_cpp -./dist/websort_cpp +# g++ src/main.cpp -o dist/jelly_rescue -L$LD_LIBRARY_PATH -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 +g++ $(find src/ -name "*.cpp") -o dist/jelly_rescue -I./include -L$LD_LIBRARY_PATH -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 +# g++ src/main.cpp -o dist/jelly_rescue -L$LD_LIBRARY_PATH -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 +./dist/jelly_rescue diff --git a/scripts/build_wasm.sh b/scripts/build_wasm.sh new file mode 100755 index 0000000..e921bfc --- /dev/null +++ b/scripts/build_wasm.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# emcc src/main.cpp -o dist/game.js -Wno-missing-braces -I/app/libs/raylib/build/raylib/include -L/app/libs/raylib/src /app/libs/raylib/src/libraylib.a -s USE_GLFW=3 -DPLATFORM_WEB + + +emcc $(find src/ -name "*.cpp") -o dist/game.js -Wno-missing-braces -I./include -I/app/libs/raylib/build/raylib/include -L/app/libs/raylib/src /app/libs/raylib/src/libraylib.a -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=268435456 -s MAXIMUM_MEMORY=4294967296 -s --preload-file assets@/assets -s USE_GLFW=3 -DPLATFORM_WEB +# -I./include +# -L$LD_LIBRARY_PATH +# -I. +# -L. +# -s --preload-file assets@/assets +# /app/libs/raylib/src/libraylib.a +# -Os -Wall +# --shell-file /app/raylib/src/shell.html +cd dist +python3 -m http.server 8080; \ No newline at end of file diff --git a/scripts/watch_project.sh b/scripts/watch_project.sh index 965c58d..5638ce4 100755 --- a/scripts/watch_project.sh +++ b/scripts/watch_project.sh @@ -1,2 +1,3 @@ #!/bin/bash -find ./src/ -name "*.cpp" -o -name "*.h" | entr -r ./scripts/build_and_run_project.sh \ No newline at end of file +find src/ -name "*.cpp" -o -wholename "./include/**/*.h" | entr -r ./scripts/build_and_run_project.sh +# find ./include/ -name "*.h" | entr -r ./scripts/build_and_run_project.sh \ No newline at end of file diff --git a/src/entities/Background.cpp b/src/entities/Background.cpp new file mode 100644 index 0000000..e31acfe --- /dev/null +++ b/src/entities/Background.cpp @@ -0,0 +1,39 @@ +#include "entities/Background.h" + +#include "services/AssetService.h" + +// Background::Background(EBackground background) +// { +// this->textures.push_back(AssetService::getInstance().getBackground(background)); +// this->position = {0,0}; +// } + +// Background::Background(std::vector backgrounds) +// { +// for(int i = 0; i < backgrounds.size(); i++) { +// this->textures.push_back(AssetService::getInstance().getBackground(backgrounds[i])); +// this->position = {0,0}; +// } +// } + +// Vector2 Background::getPosition() +// { +// return this->position; +// } + +// void Background::updatePosition(Vector2 deltaPos) +// { +// this->position = {this->position.x+deltaPos.x, this->position.y+deltaPos.y}; +// } + +// void Background::setPosition(Vector2 position) +// { +// this->position = position; +// } + +// void Background::draw() +// { +// for(int i = 0; i < textures.size(); i++) { +// DrawTexture(textures[i], position.x+ (i != 0 ? i*textures[i-1].width : 0), position.y, WHITE); +// } +// } diff --git a/src/entities/Map.cpp b/src/entities/Map.cpp new file mode 100644 index 0000000..c1ddcc5 --- /dev/null +++ b/src/entities/Map.cpp @@ -0,0 +1,180 @@ +#include "entities/Map.h" +#include +#include +#include +#include +#include "services/AssetService.h" +#include "entities/Map.h" + +Map::Map() +{ + loadTileset(); + loadMap(); + loadColMap(); +} + +void Map::loadMap() +{ + std::vector tempMap; + std::ifstream openfile(AssetService::getInstance().getMapUrl(EMap::TEXTURE)); + + map.clear(); + + if (openfile.is_open()) + { + std::string tileLocation; + openfile >> tileLocation; + // tileTexture.loadFromFile(tileLocation); + // tileSprites.setTexture(tileTexture); + while (!openfile.eof()) + { + std::string str, value; + std::getline(openfile, str); + std::stringstream stream(str); + + while (std::getline(stream, value, ' ')) + { + if (value.length() > 0) + { + std::string xx = value.substr(0, value.find(',')); + std::string yy = value.substr(value.find(',') + 1); + + int x = 0, y = 0, i, j; + // Look at all characters before the ',' + for (i = 0; i < xx.length(); i++) + { + // if one of them is not a number, break + if (!isdigit(xx[i])) + break; + } + for (j = 0; j < yy.length(); j++) + { + if (!isdigit(yy[j])) + break; + } + + // If all characters are numbers, convert string to int (the number that the sprite has in the sheet ( in this case, on the x axis) + if (i == xx.length()) + x = atoi(xx.c_str()); + else + x = -1; + // Otherwise, return -1 (aka no sprite) + + if (j == yy.length()) + y = atoi(yy.c_str()); + else + y = -1; + + // Hold both the x and y positions of the sprite + Vector2 vec2 = {(float)x, (float)y}; + tempMap.push_back(vec2); + } + } + + if (tempMap.size() > 0) + { + map.push_back(tempMap); + tempMap.clear(); + } + } + } +} + +void Map::loadColMap() +{ + std::vector tempColMap; + std::ifstream openfile(AssetService::getInstance().getMapUrl(EMap::COLLISION)); + + colMap.clear(); + + if (openfile.is_open()) + { + while (!openfile.eof()) + { + std::string str; + std::getline(openfile, str); + std::stringstream stream(str); + std::string value; + while (std::getline(stream, value, ' ')) + { + if (value.length() > 0) + { + int tempValue = atoi(value.c_str()); + tempColMap.push_back(tempValue); + } + } + colMap.push_back(tempColMap); + tempColMap.clear(); + } + } +} + +void Map::loadTileset() +{ + this->tileset = AssetService::getInstance().loadTexture("Textures/tileset.png"); +} + +std::unordered_map Map::cornersToTilePos(std::unordered_map corners) +{ + // std::cout << "Starting converting" << std::endl; + std::unordered_map cornersTilePos; + for (const auto &pair : corners) + { + // std::cout << "Foreach pair" << std::endl; + Vector2 original = corners[pair.first]; + cornersTilePos[pair.first] = {floorf(original.x / this->tileSize), floorf(original.y / this->tileSize)}; + } + return cornersTilePos; +} + +void Map::draw() +{ + for (int i = 0; i < map.size(); i++) + { + for (int j = 0; j < map[i].size(); j++) + { + if (map[i][j].x != -1 && map[i][j].y != -1) + { + // Rectangle source = {0,0,32,32}; + Rectangle sourceRect = {map[i][j].x * tileSize, map[i][j].y * tileSize, (float)tileSize, (float)tileSize}; + DrawTextureRec(tileset, sourceRect, {(float)j * tileSize, (float)i * tileSize}, WHITE); + // tileSprites.setPosition(j * tileSize, i * tileSize); + // tileSprites.setTextureRect(sf::IntRect(map[i][j].x * tileSize, map[i][j].y * tileSize, tileSize, tileSize)); + // GetWindow().draw(tileSprites); + } + } + } +} + +std::unordered_map Map::checkForCollision(TextureWrapper texture) +{ + // std::cout << "Converting.." << std::endl; + std::unordered_map cornersTilePos = cornersToTilePos(texture.getCorners()); + // std::cout << "Done with converting" << std::endl; + + std::unordered_map cornerCollisions; + + for (const auto &pair : cornersTilePos) + { + // std::cout << "foreach collision check" << std::endl; + Vector2 pos = cornersTilePos[pair.first]; + // std::cout << pos.x << " " << pos.y << std::endl; + if(colMap[pos.y][pos.x] == 1) { + cornerCollisions[pair.first] = true; + } else { + cornerCollisions[pair.first] = false; + } + } + // std::cout << "Finished collision checks" << std::endl; + + return cornerCollisions; + + // for (int i = 0; i < tiles.size(); i++) + // { + // if (colMap[tiles[i].y][tiles[i].x] == 1) + // { + // timesCollision.push_back(i); + // } + // } + +} diff --git a/src/entities/Text.cpp b/src/entities/Text.cpp new file mode 100644 index 0000000..226cdf3 --- /dev/null +++ b/src/entities/Text.cpp @@ -0,0 +1,23 @@ +#include "entities/Text.h" + +Text::Text(std::string text, EFont font, int fontSize, int spacing, Color color, Vector2 position) +{ + Font fnt = AssetService::getInstance().getFont(font, fontSize); + + this->text = text; + this->font = fnt; + this->fontSize = fontSize; + this->spacing = spacing; + this->color = color; + this->position = position; +} + +Vector2 Text::getDimensions() +{ + return MeasureTextEx(font, text.c_str(), (float)fontSize, (float)spacing); +} + +void Text::draw() +{ + DrawTextEx(font, text.c_str(), position, fontSize, spacing, color); +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e252ab4 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,66 @@ +#include "raylib.h" +// #include "screens/Screen.h" +// #include "screens/TitleScreen.h" +#include "services/StateService.h" +// #include + +// #if defined(PLATFORM_WEB) +// #include +// #endif + +// void step(); +// static void gameloop(); + +int main() +{ + StateService& stateService = StateService::getInstance(); + stateService.setScreenSize({640,544}); + stateService.startGame(); + // std::cout << "StateService instance: " << service << std::endl; + +// InitWindow(640, 544, "Jelly Rescue"); +// // SetTargetFPS(60); + +// // setScreen(EScreen::TITLE); + +// #if defined(PLATFORM_WEB) +// emscripten_set_main_loop(step, 0, 1); +// #else + +// while (!WindowShouldClose()) +// { +// step(); +// } +// #endif + +// CloseWindow(); + + return 0; +} + +// static void gameloop() +// { +// // InitAudioDevice(); +// InitWindow(640, 544, "Jelly Rescue"); +// // SetTargetFPS(60); + +// // setScreen(EScreen::TITLE); + +// #if defined(PLATFORM_WEB) +// emscripten_set_main_loop(step, 0, 1); +// #else + +// while (!WindowShouldClose()) +// { +// step(); +// } +// #endif + +// CloseWindow(); +// // CloseAudioDevice(); +// } + +// void step() +// { +// ClearBackground(BLACK); +// } \ No newline at end of file diff --git a/src/screens/GameScreen.cpp b/src/screens/GameScreen.cpp new file mode 100644 index 0000000..d3d445a --- /dev/null +++ b/src/screens/GameScreen.cpp @@ -0,0 +1,27 @@ +#include "screens/GameScreen.h" +#include "entities/Map.h" +#include "services/StateService.h" + +GameScreen::GameScreen() +{ + // std::vector bgs; + // bgs.push_back(EBackground::GAME1); + // bgs.push_back(EBackground::GAME2); + // bgs.push_back(EBackground::GAME3); + // this->background = Background(bgs); + // this->map = Map(); + + this->game = Game(); + // this->camera = camera; +} + +void GameScreen::logic() +{ + this->game.logic(); + // this->background.value().updatePosition({-2.5f,0}); + // this->camera.value().target.x += 1.0f; +} + +void GameScreen::draw() { + this->game.draw(); +} diff --git a/src/screens/MainScreen.cpp b/src/screens/MainScreen.cpp new file mode 100644 index 0000000..77f6293 --- /dev/null +++ b/src/screens/MainScreen.cpp @@ -0,0 +1,124 @@ +#include "screens/MainScreen.h" +#include "services/AudioService.h" +#include "services/StateService.h" +#include "raylib.h" +#include "services/InputService.h" + +MainScreen::MainScreen() +{ + const int TOP_GAP = 100; + const int BOTTOM_GAP = 50; + const int AMNT_OF_BUTTONS = 4; + const int TOTAL_SPACE = GetScreenHeight() - (TOP_GAP + BOTTOM_GAP); + const int SPACE_PER_ITEM = TOTAL_SPACE / AMNT_OF_BUTTONS; + + for (int i = 0; i < AMNT_OF_BUTTONS; i++) + { + Text txt = Text("new game", EFont::GTEK, 30, 0, WHITE); + buttons.push_back(txt); + } + buttons[0].setColor(RED); + buttons[1].setText("load game"); + buttons[2].setText("tutorial"); + buttons[3].setText("quit"); + + for (int i = 0; i < AMNT_OF_BUTTONS; i++) + { + buttons[i].setPosition({(float)(GetScreenWidth() - buttons[i].getDimensions().x) / 2.0f, (float)TOP_GAP + SPACE_PER_ITEM * i}); + } + + /** Will be ignored if already active (like when coming from the TitleScreen) */ + EMusic track = AudioService::getInstance().getCurrentTrack(); + if (track != EMusic::MAIN) + { + AudioService::getInstance().setMusic(EMusic::MAIN); + AudioService::getInstance().playMusic(); + } + + InputService::getInstance().setKeysToWatch({KEY_ENTER, KEY_UP, KEY_DOWN}, {MOUSE_BUTTON_LEFT}); +} + +void MainScreen::logic() +{ + // Vector2 mouseD = GetMouseDelta(); + // std::cout << mouseD.y <= rect.x && mousePos.x <= (rect.x+rect.width) && + if ((mousePos.x + textPadding) >= rect.x && mousePos.x <= (rect.x + rect.width + textPadding) && (mousePos.y + textPadding) >= rect.y && mousePos.y <= (rect.y + rect.height + textPadding)) + { + buttons[hoveredButton].setColor(WHITE); + hoveredButton = i; + buttons[hoveredButton].setColor(RED); + break; + } + } +} + +void MainScreen::keyboardLogic() +{ + if (InputService::getInstance().isKeyPressed(KEY_DOWN) || InputService::getInstance().isKeyPressed(KEY_UP)) + { + buttons[hoveredButton].setColor(WHITE); + /** Move up or down depending on the pressed button. +4 is used so that -1 becomes 3 (the last button) */ + hoveredButton = ((hoveredButton - (InputService::getInstance().isKeyPressed(KEY_DOWN) ? -1 : 1)) + 4) % 4; + buttons[hoveredButton].setColor(RED); + } +} + +void MainScreen::clickLogic() +{ + if (InputService::getInstance().isKeyPressed(KEY_ENTER) || InputService::getInstance().isMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + std::string selectedButton = buttons[hoveredButton].getText(); + + if (selectedButton == "new game") + StateService::getInstance().setScreen(EScreen::GAME); + else if (selectedButton == "load game") + { + } + else if (selectedButton == "tutorial") + StateService::getInstance().setScreen(EScreen::TUTORIAL); + else if (selectedButton == "quit") + StateService::getInstance().setScreen(EScreen::CLOSE); + } +} + +void MainScreen::draw() +{ + BeginDrawing(); + ClearBackground(BLACK); + + if (buttons.size() > 0) + { + for (int i = 0; i < buttons.size(); i++) + { + buttons[i].draw(); + } + } + EndDrawing(); +} \ No newline at end of file diff --git a/src/screens/Screen.cpp b/src/screens/Screen.cpp new file mode 100644 index 0000000..a9cf5ff --- /dev/null +++ b/src/screens/Screen.cpp @@ -0,0 +1,29 @@ +#include "screens/Screen.h" + +// void Screen::draw() +// { +// BeginDrawing(); + +// if (camera.has_value()) +// BeginMode2D(this->camera.value()); + +// if (!background.has_value()) +// ClearBackground(BLACK); +// else +// this->background.value().draw(); + +// if (map.has_value()) +// this->map.value().draw(); + +// if (text.size() > 0) +// { +// for (int t = 0; t < text.size(); t++) +// { +// text[t].draw(); +// } +// } +// if (camera.has_value()) +// EndMode2D(); + +// EndDrawing(); +// } \ No newline at end of file diff --git a/src/screens/TitleScreen.cpp b/src/screens/TitleScreen.cpp new file mode 100644 index 0000000..98e7f35 --- /dev/null +++ b/src/screens/TitleScreen.cpp @@ -0,0 +1,57 @@ +#include "screens/TitleScreen.h" +#include "services/AssetService.h" +#include "services/StateService.h" +#include "enums/EFont.h" +#include "services/AudioService.h" +#include +#include "services/InputService.h" + +TitleScreen::TitleScreen() +{ + Text textAbout = Text("Made by Ian Vink", EFont::SANSATION, 20, 0, WHITE); + textAbout.setPosition({(float)(GetScreenWidth() - textAbout.getDimensions().x) / 1.2f, + (float)(GetScreenHeight() - textAbout.getDimensions().y) / 6.0f}); + Text textCenter = Text("Jelly rescue", EFont::RECKONER_BOLD, 100, 0, {255, 25, 25, 255}); + textCenter.setPosition({(float)(GetScreenWidth() - textCenter.getDimensions().x) / 2.0f, + (float)(GetScreenHeight() - textCenter.getDimensions().y) / 2.0f}); + Text testSub = Text("Press Enter", EFont::SANSATION, 30, 0, WHITE); + testSub.setPosition({(float)(GetScreenWidth() - testSub.getDimensions().x) / 2.0f, + (float)(GetScreenHeight() - testSub.getDimensions().y) / 1.5f}); + + text.push_back(textAbout); + text.push_back(textCenter); + text.push_back(testSub); + + EMusic track = AudioService::getInstance().getCurrentTrack(); + if (track != EMusic::MAIN) + { + AudioService::getInstance().setMusic(EMusic::MAIN); + AudioService::getInstance().playMusic(); + } + + InputService::getInstance().setKeysToWatch({KEY_ENTER}, {MOUSE_BUTTON_LEFT}); +} + +void TitleScreen::logic() +{ + // std::cout << "Next screen!" << std::endl; + if (InputService::getInstance().isKeyPressed(KEY_ENTER) || InputService::getInstance().isMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + StateService::getInstance().setScreen(EScreen::MAIN); + } +} + +void TitleScreen::draw() +{ + BeginDrawing(); + ClearBackground(BLACK); + + if (text.size() > 0) + { + for (int t = 0; t < text.size(); t++) + { + text[t].draw(); + } + } + EndDrawing(); +} \ No newline at end of file diff --git a/src/screens/TutorialScreen.cpp b/src/screens/TutorialScreen.cpp new file mode 100644 index 0000000..86b7ea5 --- /dev/null +++ b/src/screens/TutorialScreen.cpp @@ -0,0 +1,40 @@ +#include "screens/TutorialScreen.h" + +#include "services/StateService.h" +#include "enums/EFont.h" +#include "enums/EScreen.h" +#include "services/InputService.h" + +TutorialScreen::TutorialScreen() { + Text textBack = Text("Press Enter to go back", EFont::SANSATION, 30, 0, RED); + textBack.setPosition({(float)(GetScreenWidth() - textBack.getDimensions().x) / 1.3f, + (float)(GetScreenHeight() - textBack.getDimensions().y) / 1.15f}); + this->text.push_back(textBack); + + this->background = Background(EBackground::TUTORIAL); + + InputService::getInstance().setKeysToWatch({KEY_ENTER}, {MOUSE_BUTTON_LEFT}); +} + +void TutorialScreen::logic() +{ + if ( InputService::getInstance().isKeyPressed(KEY_ENTER) || InputService::getInstance().isMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + StateService::getInstance().setScreen(EScreen::MAIN); + } +} + +void TutorialScreen::draw() +{ + BeginDrawing(); + this->background.draw(); + + if (text.size() > 0) + { + for (int t = 0; t < text.size(); t++) + { + text[t].draw(); + } + } + EndDrawing(); +} diff --git a/src/services/AssetService.cpp b/src/services/AssetService.cpp new file mode 100644 index 0000000..06039a9 --- /dev/null +++ b/src/services/AssetService.cpp @@ -0,0 +1,78 @@ +#include "services/AssetService.h" +#include +AssetService::AssetService() +{ + setAssetDir("assets/"); + setAssets(); +} + + +void AssetService::setAssets() +{ + fonts[EFont::GTEK] = "Fonts/Gtek.ttf"; + fonts[EFont::OXIN] = "Fonts/Oxin.ttf"; + fonts[EFont::RECKONER_BOLD] = "Fonts/Reckoner_Bold.ttf"; + fonts[EFont::RECKONER] = "Fonts/Reckoner.ttf"; + fonts[EFont::SANSATION] = "Fonts/Sansation.ttf"; + + music[EMusic::MAIN] = loadMusic("Audio/Music/Crash_WarpRoomTheme.ogg", true); + music[EMusic::GAME] = loadMusic("Audio/Music/GameTheme_2.ogg", true); + music[EMusic::GAME_OVER] = loadMusic("Audio/Music/gameOverTheme.ogg", false); + /** Todo: set volume */ + + backgrounds[EBackground::TUTORIAL] = loadTexture("Textures/TutorialBackground2.png"); + backgrounds[EBackground::GAME1] = loadTexture("Textures/GameBackground_1.png"); + backgrounds[EBackground::GAME2] = loadTexture("Textures/GameBackground_2.jpg"); + backgrounds[EBackground::GAME3] = loadTexture("Textures/GameBackground_3.png"); + backgrounds[EBackground::VICTORY] = loadTexture("Textures/VictoryScreenBackground.png"); + + maps[EMap::TEXTURE] = "Maps/map1.txt"; + maps[EMap::COLLISION] = "Maps/colmap1.txt"; + + sprites[ESprite::PLAYER] = loadTexture("Textures/player.png"); + sprites[ESprite::PLAYER_GUN_LEFT] = loadTexture("Textures/gunleft.png"); + sprites[ESprite::PLAYER_GUN_RIGHT] = loadTexture("Textures/gunright.png"); + sprites[ESprite::ENEMY] = loadTexture("Textures/enemy.png"); + sprites[ESprite::ENEMY_GUN_LEFT] = loadTexture("Textures/gunleft_2.png"); + sprites[ESprite::ENEMY_GUN_RIGHT] = loadTexture("Textures/gunright_2.png"); + sprites[ESprite::CRATE] = loadTexture("Textures/woodencrate.png"); + sprites[ESprite::JELLY] = loadTexture("Textures/happyjelly.png"); + sprites[ESprite::HEALTHPACK] = loadTexture("Textures/FirstAidKit.png"); + sprites[ESprite::AMMOPACK] = loadTexture("Textures/Bullets_small.png"); + sprites[ESprite::POWERUP] = loadTexture("Textures/powerUpAnimation.png"); + sprites[ESprite::HUD_HEART] = loadTexture("Textures/heart.png"); + sprites[ESprite::HUD_HEART_EMPTY] = loadTexture("Textures/heart_empty.png"); + sprites[ESprite::HUD_AMMO] = loadTexture("Textures/bullet_hud.png"); +} + +Font AssetService::getFont(EFont font, int fontSize) +{ + std::string fontUrl = getFontUrl(font); + Font fnt = LoadFontEx(fontUrl.c_str(), fontSize, 0, 0); + SetTextureFilter(fnt.texture, TEXTURE_FILTER_BILINEAR); + return fnt; +} + +Texture2D AssetService::loadTexture(std::string filename) +{ + Texture2D texture = LoadTexture((assetDir + filename).c_str()); + return texture; +} + +std::string AssetService::getFontUrl(EFont font) +{ + return assetDir + fonts[font]; +} + +Music AssetService::loadMusic(std::string filename, bool loops) +{ + Music music = LoadMusicStream((assetDir + filename).c_str()); + music.looping = loops; + return music; +} + +Sound AssetService::loadSound(std::string filename) +{ + Sound sound = LoadSound((assetDir + filename).c_str()); + return sound; +} diff --git a/src/services/AudioService.cpp b/src/services/AudioService.cpp new file mode 100644 index 0000000..64737c8 --- /dev/null +++ b/src/services/AudioService.cpp @@ -0,0 +1,49 @@ +#include "services/AudioService.h" +#include "services/AssetService.h" + +// AudioService::~AudioService() +// { +// if (!music.has_value()) +// return; +// UnloadMusicStream(music.value()); +// } + +void AudioService::setMusic(EMusic music) +{ + if (currentTrack == music) + return; + + this->currentTrack = music; + this->music = AssetService::getInstance().getMusic(music); +} + +void AudioService::playMusic() +{ + if (!music.has_value()) + return; + PlayMusicStream(music.value()); +} + +void AudioService::pauseMusic() +{ + if (!music.has_value()) + return; + PauseMusicStream(music.value()); +} + +void AudioService::stopMusic() +{ + if (music.has_value()) + { + StopMusicStream(music.value()); + } + this->currentTrack = EMusic::NONE; +} + +void AudioService::playSound() +{ +} + +void AudioService::stopSounds() +{ +} diff --git a/src/services/StateService.cpp b/src/services/StateService.cpp new file mode 100644 index 0000000..9c56ebf --- /dev/null +++ b/src/services/StateService.cpp @@ -0,0 +1,92 @@ +#include "services/StateService.h" +#include "raylib.h" +#include "screens/TitleScreen.h" +#include "screens/MainScreen.h" +#include "screens/TutorialScreen.h" +#include "screens/GameScreen.h" +#include +#include "services/AudioService.h" +#include "services/InputService.h" + +void StateService::setScreen(EScreen state) +{ + switch (state) + { + case EScreen::TITLE: + currentScreen = std::make_unique(); + break; + case EScreen::MAIN: + currentScreen = std::make_unique(); + break; + case EScreen::TUTORIAL: + currentScreen = std::make_unique(); + break; + case EScreen::GAME: + currentScreen = std::make_unique(); + break; + case EScreen::CLOSE: + gameRunning = false; + break; + default: + currentScreen = std::make_unique(); + } +} + +Screen *StateService::getScreen() +{ + return currentScreen.get(); +} + +void StateService::startGame() +{ + // if(!instance) + // return; + InitAudioDevice(); + // InitWindow(640,544, "Jelly Rescue"); + InitWindow(screenSize.x, screenSize.y, "Jelly Rescue"); + SetTargetFPS(60); + + // #if defined(PLATFORM_WEB) + // emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_CANVAS, nullptr, 1, staticStep); + // #endif + + // #if defined(PLATFORM_WEB) + // emscripten_set_focusin_callback(EMSCRIPTEN_EVENT_TARGET_CANVAS, nullptr, 1, [](const EmscriptenFocusEvent* event) { + // std::cout << "Canvas Focused!" << std::endl; + // }); + // #endif + + setScreen(EScreen::TITLE); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(StateService::staticStep, 0, 1); +#else + + // while (!WindowShouldClose() && instance->gameRunning) + while (!WindowShouldClose() && gameRunning) + { + step(); + } +#endif + + CloseWindow(); + CloseAudioDevice(); +} + +void StateService::handleMusic() +{ + std::optional music = AudioService::getInstance().getMusic(); + if (music.has_value()) + { + UpdateMusicStream(music.value()); + } +} + +void StateService::step() +{ + InputService::getInstance().checkKeys(); + + handleMusic(); + currentScreen->draw(); + currentScreen->logic(); +}