diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index 5bcd28fe..9f352ac4 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -1,4 +1,4 @@ -name: Linux Build epi env +name: Linux Build (Epitech Container) on: [push, pull_request] jobs: diff --git a/.github/workflows/webassembly.yml b/.github/workflows/build_web.yml similarity index 87% rename from .github/workflows/webassembly.yml rename to .github/workflows/build_web.yml index 0b729418..9c84b83b 100644 --- a/.github/workflows/webassembly.yml +++ b/.github/workflows/build_web.yml @@ -1,4 +1,4 @@ -name: Web Building +name: Web Build (Emscripten) on: push: branches: @@ -13,7 +13,7 @@ jobs: submodules: true - name: Exec shell: bash - run: ./emsdk.sh + run: ./build_web.sh - name: Check files creation run: | test -f build_web/bomberman.html diff --git a/.github/workflows/build.yml b/.github/workflows/build_windows.yml similarity index 98% rename from .github/workflows/build.yml rename to .github/workflows/build_windows.yml index beea1b7f..a3a21944 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build_windows.yml @@ -1,4 +1,4 @@ -name: Build +name: Windows Build on: [push, pull_request] jobs: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f24a0564..e87b9b9d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Tests +name: Unit Tests on: [push, pull_request] jobs: diff --git a/.gitignore b/.gitignore index 9e44c2a3..74044c49 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ cmake-build-debug .vscode build/* docs/* -emsdk/ -build_web/ \ No newline at end of file +emsdk/* +build_web/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 01c04fb3..78906406 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ add_subdirectory(${PROJECT_SOURCE_DIR}/lib/Ray) if (EMSCRIPTEN) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY --preload-file ../assets") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s NO_DISABLE_EXCEPTION_CATCHING --preload-file ../assets") set(CMAKE_EXECUTABLE_SUFFIX ".html") endif () @@ -20,13 +20,37 @@ set(SOURCES sources/Models/GameState.hpp sources/Runner/Runner.cpp sources/Runner/Runner.hpp + sources/Map/Map.cpp + sources/Map/Map.hpp sources/Component/Position/PositionComponent.cpp sources/Component/Position/PositionComponent.hpp sources/Component/Movable/MovableComponent.cpp sources/Component/Movable/MovableComponent.hpp + sources/Component/Controllable/ControllableComponent.hpp + sources/Component/Controllable/ControllableComponent.cpp + sources/Component/Gamepad/GamepadComponent.cpp + sources/Component/Gamepad/GamepadComponent.hpp + sources/Component/Keyboard/KeyboardComponent.cpp + sources/Component/Keyboard/KeyboardComponent.hpp + sources/Component/Health/HealthComponent.cpp + sources/Component/Health/HealthComponent.hpp sources/System/Movable/MovableSystem.hpp sources/System/Movable/MovableSystem.cpp + sources/System/Controllable/ControllableSystem.cpp + sources/System/Controllable/ControllableSystem.hpp + sources/System/Gamepad/GamepadSystem.cpp + sources/System/Gamepad/GamepadSystem.hpp + sources/System/Health/HealthSystem.cpp + sources/System/Health/HealthSystem.hpp + sources/System/Keyboard/KeyboardSystem.cpp + sources/System/Keyboard/KeyboardSystem.hpp + sources/System/Movable/MovableSystem.cpp + sources/System/Movable/MovableSystem.hpp sources/Models/Vector3.hpp + sources/Component/GridCentered/GridCenteredComponent.cpp + sources/Component/GridCentered/GridCenteredComponent.hpp + sources/System/GridCentered/GridCenteredSystem.cpp + sources/System/GridCentered/GridCenteredSystem.hpp sources/Models/Vector2.hpp sources/Component/Renderer/Drawable2DComponent.hpp sources/Component/Renderer/Drawable3DComponent.hpp @@ -34,8 +58,11 @@ set(SOURCES sources/System/Renderer/RenderSystem.cpp sources/Component/Renderer/CameraComponent.cpp sources/Component/Renderer/CameraComponent.hpp - ) - + sources/Component/Collision/CollisionComponent.cpp + sources/Component/Collision/CollisionComponent.hpp + sources/System/Collision/CollisionSystem.hpp + sources/System/Collision/CollisionSystem.cpp +) add_executable(bomberman sources/main.cpp ${SOURCES}) @@ -49,6 +76,8 @@ add_executable(unit_tests EXCLUDE_FROM_ALL tests/MainTest.cpp tests/EngineTests.cpp tests/CallbackTest.cpp + tests/CollisionTest.cpp + tests/MoveTests.cpp ) target_include_directories(unit_tests PUBLIC sources) target_link_libraries(unit_tests PUBLIC wal ray) diff --git a/README.md b/README.md index 7f81836d..18e93e7a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ A recreation of the classic Bomberman arcade game +[![Linux Build (Epitech Container)](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/build_linux.yml/badge.svg)](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/build_linux.yml) +[![Windows Build](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/build_windows.yml/badge.svg)](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/build_windows.yml) +[![Web Building](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/webassembly.yml/badge.svg)](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/webassembly.yml) +[![Unit Tests](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/test.yml/badge.svg)](https://github.com/AnonymusRaccoon/Bomberman/actions/workflows/test.yml) + Repository link: https://github.com/AnonymusRaccoon/Bomberman/ ## Demo @@ -31,7 +36,10 @@ cd Bomberman Create `build` dir and compile using CMake ```bash -mkdir build && cd build && cmake .. && make +mkdir build +cd build +cmake .. +cmake --build . ``` Enjoy ! @@ -65,4 +73,4 @@ Please adhere to this project's `code of conduct`. - [Arthur Jamet](https://github.com/Arthi-chaud "Arthi-Chaud") - [Louis Auzuret](https://github.com/GitBluub "Bluub") - [Benjamin Henry](https://github.com/EternalRat "EternalRat") -- [Tom Augier](https://github.com/TrueBabyChaise "TrueBabyChaise") \ No newline at end of file +- [Tom Augier](https://github.com/TrueBabyChaise "TrueBabyChaise") diff --git a/assets/player/blue.png b/assets/player/blue.png index d8cf2be5..bb40eb06 100644 Binary files a/assets/player/blue.png and b/assets/player/blue.png differ diff --git a/assets/wall/breakable_wall.mtl b/assets/wall/breakable_wall.mtl index 7925a729..86d5a0cf 100644 --- a/assets/wall/breakable_wall.mtl +++ b/assets/wall/breakable_wall.mtl @@ -1,12 +1,54 @@ -# Blender MTL File: 'None' -# Material Count: 1 - -newmtl Cube.001 -Ns 225.000000 -Ka 1.000000 1.000000 1.000000 -Kd 0.800000 0.800000 0.800000 -Ks 0.500000 0.500000 0.500000 -Ke 0.000000 0.000000 0.000000 -Ni 1.450000 -d 1.000000 -illum 2 +# Blender v2.92.0 OBJ File: '' +# www.blender.org +mtllib breakable_wall.mtl +o cube +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.000000 0.500000 +vt 0.333333 0.500000 +vt 0.666666 1.000000 +vt 1.000000 1.000000 +vt 0.666666 0.500000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.000000 0.500000 +vt 0.333333 0.500000 +vt 0.666666 0.000000 +vt 1.000000 0.000000 +vt 0.666666 0.500000 +vt 1.000000 0.500000 +vt 0.666666 0.500000 +vt 0.666666 1.000000 +vt 0.333333 0.000000 +vt 0.666666 0.000000 +vt 0.333333 0.500000 +vt 0.666666 0.500000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +usemtl cube +s 1 +f 1/1/1 2/2/1 3/3/1 +f 3/3/1 2/2/1 4/4/1 +f 3/5/2 4/6/2 5/7/2 +f 5/7/2 4/6/2 6/8/2 +f 5/9/3 6/10/3 7/11/3 +f 7/11/3 6/10/3 8/12/3 +f 7/13/4 8/14/4 1/15/4 +f 1/15/4 8/14/4 2/16/4 +f 2/17/5 8/12/5 4/18/5 +f 4/18/5 8/12/5 6/10/5 +f 7/19/6 1/20/6 5/21/6 +f 5/21/6 1/20/6 3/22/6 diff --git a/assets/wall/breakable_wall.obj b/assets/wall/breakable_wall.obj index 320cb55e..144c9997 100644 --- a/assets/wall/breakable_wall.obj +++ b/assets/wall/breakable_wall.obj @@ -1,338 +1,61 @@ -# Blender v2.92.0 OBJ File: '' -# www.blender.org -mtllib breakable_wall.mtl -o Cube.002 -v 0.404250 -0.428000 -0.404250 -v 0.404250 -0.428000 0.404250 -v -0.404250 -0.428000 0.404250 -v -0.404250 -0.428000 -0.404250 -v -0.404250 0.436000 0.404250 -v 0.404250 0.436000 0.404250 -v 0.404250 0.436000 -0.404250 -v -0.404250 0.436000 -0.404250 -v 0.432000 0.408250 -0.404250 -v 0.432000 0.408250 0.404250 -v 0.432000 -0.400250 0.404250 -v 0.432000 -0.400250 -0.404250 -v 0.404250 -0.500000 -0.404250 -v -0.404250 -0.500000 -0.404250 -v -0.404250 -0.500000 -0.504000 -v 0.404250 -0.500000 -0.504000 -v -0.404250 -0.500000 0.404250 -v 0.404250 -0.500000 0.404250 -v 0.404250 -0.500000 0.504000 -v -0.404250 -0.500000 0.504000 -v -0.404250 0.508000 -0.404250 -v 0.404250 0.508000 -0.404250 -v 0.404250 0.508000 -0.504000 -v -0.404250 0.508000 -0.504000 -v 0.404250 0.508000 0.404250 -v -0.404250 0.508000 0.404250 -v -0.404250 0.508000 0.504000 -v 0.404250 0.508000 0.504000 -v 0.504000 0.408250 -0.404250 -v 0.504000 -0.400250 -0.404250 -v 0.504000 -0.400250 -0.504000 -v 0.504000 0.408250 -0.504000 -v 0.504000 -0.400250 0.404250 -v 0.504000 0.408250 0.404250 -v 0.504000 0.408250 0.504000 -v 0.504000 -0.400250 0.504000 -v -0.504000 0.408250 0.404250 -v -0.504000 -0.400250 0.404250 -v -0.504000 -0.400250 0.504000 -v -0.504000 0.408250 0.504000 -v -0.504000 -0.400250 -0.404250 -v -0.504000 0.408250 -0.404250 -v -0.504000 0.408250 -0.504000 -v -0.504000 -0.400250 -0.504000 -v 0.404250 0.408250 0.504000 -v -0.404250 0.408250 0.504000 -v -0.404250 -0.400250 0.504000 -v 0.404250 -0.400250 0.504000 -v 0.504000 0.508000 -0.404250 -v 0.504000 0.508000 0.404250 -v 0.504000 -0.500000 0.404250 -v 0.504000 -0.500000 -0.404250 -v 0.404250 0.408250 -0.504000 -v -0.404250 0.408250 -0.504000 -v -0.404250 -0.400250 -0.504000 -v 0.404250 -0.400250 -0.504000 -v -0.504000 0.508000 -0.404250 -v -0.504000 0.508000 0.404250 -v -0.504000 -0.500000 0.404250 -v -0.504000 -0.500000 -0.404250 -v 0.504000 0.508000 -0.504000 -v 0.504000 -0.500000 -0.504000 -v 0.504000 -0.500000 0.504000 -v 0.504000 0.508000 0.504000 -v -0.504000 0.508000 0.504000 -v -0.504000 -0.500000 0.504000 -v -0.504000 -0.500000 -0.504000 -v -0.504000 0.508000 -0.504000 -v -0.404250 0.408250 0.432000 -v 0.404250 0.408250 0.432000 -v -0.404250 -0.400250 0.432000 -v 0.404250 -0.400250 0.432000 -v 0.404250 0.408250 -0.432000 -v -0.404250 0.408250 -0.432000 -v 0.404250 -0.400250 -0.432000 -v -0.404250 -0.400250 -0.432000 -v -0.432000 0.408250 0.404250 -v -0.432000 -0.400250 0.404250 -v -0.432000 0.408250 -0.404250 -v -0.432000 -0.400250 -0.404250 -vt 0.287300 0.056300 -vt 0.287300 0.282400 -vt 0.061200 0.282400 -vt 0.061200 0.056300 -vt 0.621800 0.620900 -vt 0.395400 0.620900 -vt 0.395400 0.394400 -vt 0.621800 0.394400 -vt 0.299200 0.394400 -vt 0.299200 0.620900 -vt 0.072700 0.620900 -vt 0.072700 0.394400 -vt 0.287300 0.036100 -vt 0.061200 0.036100 -vt 0.061200 0.008200 -vt 0.287300 0.008200 -vt 0.061200 0.302500 -vt 0.287300 0.302500 -vt 0.287300 0.330400 -vt 0.061200 0.330400 -vt 0.621800 0.374200 -vt 0.395400 0.374200 -vt 0.395400 0.346300 -vt 0.621800 0.346300 -vt 0.395400 0.641000 -vt 0.621800 0.641000 -vt 0.621800 0.669000 -vt 0.395400 0.669000 -vt 0.299200 0.374200 -vt 0.072700 0.374200 -vt 0.072700 0.346300 -vt 0.299200 0.346300 -vt 0.072700 0.641000 -vt 0.299200 0.641000 -vt 0.299200 0.669000 -vt 0.072700 0.669000 -vt 0.718100 0.641000 -vt 0.944500 0.641000 -vt 0.944500 0.669000 -vt 0.718100 0.669000 -vt 0.944500 0.374200 -vt 0.718100 0.374200 -vt 0.718100 0.346300 -vt 0.944500 0.346300 -vt 0.395400 0.696900 -vt 0.621800 0.696900 -vt 0.621800 0.963700 -vt 0.621800 0.991700 -vt 0.395400 0.991700 -vt 0.395400 0.963700 -vt 0.347300 0.394400 -vt 0.347300 0.620900 -vt 0.319300 0.620900 -vt 0.319300 0.394400 -vt 0.052500 0.394400 -vt 0.052500 0.620900 -vt 0.024600 0.620600 -vt 0.024600 0.394300 -vt 0.395400 0.318300 -vt 0.621800 0.318300 -vt 0.621800 0.051500 -vt 0.395400 0.051500 -vt 0.395400 0.023600 -vt 0.621800 0.023600 -vt 0.670000 0.394400 -vt 0.697900 0.394400 -vt 0.697900 0.620900 -vt 0.670000 0.620900 -vt 0.992600 0.620900 -vt 0.964700 0.620900 -vt 0.964700 0.394400 -vt 0.992600 0.394400 -vt 0.319300 0.366500 -vt 0.347300 0.366500 -vt 0.052500 0.366500 -vt 0.024600 0.366500 -vt 0.052500 0.648800 -vt 0.024600 0.648800 -vt 0.319300 0.648800 -vt 0.347300 0.648800 -vt 0.697900 0.648800 -vt 0.670000 0.648800 -vt 0.964700 0.648800 -vt 0.992600 0.648800 -vt 0.964700 0.366500 -vt 0.992600 0.366500 -vt 0.697900 0.366500 -vt 0.670000 0.366500 -vt 0.335400 0.282600 -vt 0.307500 0.282400 -vt 0.307500 0.056300 -vt 0.335400 0.056300 -vt 0.013200 0.282400 -vt 0.013200 0.056300 -vt 0.041100 0.056300 -vt 0.041100 0.282400 -vt 0.642000 0.620900 -vt 0.642000 0.394400 -vt 0.375200 0.394400 -vt 0.375200 0.620900 -vt 0.670000 0.717100 -vt 0.670000 0.943500 -vt 0.642000 0.943500 -vt 0.642000 0.717100 -vt 0.347300 0.717100 -vt 0.375200 0.717100 -vt 0.375200 0.943500 -vt 0.347300 0.943500 -vt 0.347300 0.298200 -vt 0.347300 0.071700 -vt 0.375200 0.071700 -vt 0.375200 0.298200 -vt 0.670000 0.071700 -vt 0.670000 0.298200 -vt 0.642000 0.298200 -vt 0.642000 0.071700 -vt 0.315200 0.008200 -vt 0.315200 0.036100 -vt 0.033300 0.008200 -vt 0.033300 0.036100 -vt 0.033300 0.302500 -vt 0.033300 0.330400 -vt 0.315200 0.302500 -vt 0.315200 0.330400 -vt 0.649800 0.374200 -vt 0.649800 0.346300 -vt 0.367400 0.374200 -vt 0.367400 0.346300 -vt 0.367400 0.669000 -vt 0.367400 0.641000 -vt 0.649800 0.669000 -vt 0.649800 0.641000 -vt 0.649800 0.696900 -vt 0.367400 0.696900 -vt 0.367400 0.991700 -vt 0.367400 0.963700 -vt 0.649800 0.963700 -vt 0.649800 0.991700 -vt 0.367400 0.318300 -vt 0.649800 0.318300 -vt 0.649800 0.023600 -vt 0.649800 0.051500 -vt 0.367400 0.051500 -vt 0.367400 0.023600 -vt 0.621800 0.717100 -vt 0.395400 0.717100 -vt 0.621800 0.943500 -vt 0.395400 0.943500 -vt 0.395400 0.298200 -vt 0.621800 0.298200 -vt 0.395400 0.071700 -vt 0.621800 0.071700 -vt 0.718100 0.620900 -vt 0.944500 0.620900 -vt 0.718100 0.394400 -vt 0.944500 0.394400 -vn 0.0000 -1.0000 -0.0000 -vn 0.0000 1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -0.7071 0.0000 0.7071 -vn 0.7071 0.0000 0.7071 -vn -0.7071 0.0000 -0.7071 -vn 0.7071 0.0000 -0.7071 -vn 0.7071 -0.7071 0.0000 -vn -0.7071 -0.7071 0.0000 -vn 0.7071 0.7071 0.0000 -vn -0.7071 0.7071 0.0000 -vn 0.0000 -0.7071 0.7071 -vn 0.0000 0.7071 0.7071 -vn 0.0000 -0.7071 -0.7071 -vn 0.0000 0.7071 -0.7071 -usemtl Cube.001 +# floor.obj +# + +mtllib floor.mtl +o floor + +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 + +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.666666 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.500000 +vt 0.333333 0.500000 +vt 0.666666 0.500000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.666666 1.000000 +vt 1.000000 1.000000 + +vn 0.000000 0.000000 1.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 + +g floor +usemtl floor +# Back s 1 -f 1/1/1 2/2/1 3/3/1 4/4/1 -f 5/5/2 6/6/2 7/7/2 8/8/2 -f 9/9/3 10/10/3 11/11/3 12/12/3 -f 13/13/1 14/14/1 15/15/1 16/16/1 -f 17/17/1 18/18/1 19/19/1 20/20/1 -f 21/21/2 22/22/2 23/23/2 24/24/2 -f 25/25/2 26/26/2 27/27/2 28/28/2 -f 29/29/3 30/30/3 31/31/3 32/32/3 -f 33/33/3 34/34/3 35/35/3 36/36/3 -f 37/37/4 38/38/4 39/39/4 40/40/4 -f 41/41/4 42/42/4 43/43/4 44/44/4 -f 45/45/5 28/28/5 27/27/5 46/46/5 -f 47/47/5 20/48/5 19/49/5 48/50/5 -f 49/51/3 50/52/3 34/53/3 29/54/3 -f 30/55/3 33/56/3 51/57/3 52/58/3 -f 53/59/6 54/60/6 24/24/6 23/23/6 -f 55/61/6 56/62/6 16/63/6 15/64/6 -f 57/65/4 42/66/4 37/67/4 58/68/4 -f 59/69/4 38/70/4 41/71/4 60/72/4 -f 29/54/3 32/73/3 61/74/3 49/51/3 -f 31/75/3 30/55/3 52/58/3 62/76/3 -f 33/56/3 36/77/3 63/78/3 51/57/3 -f 35/79/3 34/53/3 50/52/3 64/80/3 -f 37/67/4 40/81/4 65/82/4 58/68/4 -f 39/83/4 38/70/4 59/69/4 66/84/4 -f 41/71/4 44/85/4 67/86/4 60/72/4 -f 43/87/4 42/66/4 57/65/4 68/88/4 -f 51/89/1 18/90/1 13/91/1 52/92/1 -f 59/93/1 60/94/1 14/95/1 17/96/1 -f 57/65/2 58/68/2 26/97/2 21/98/2 -f 50/52/2 49/51/2 22/99/2 25/100/2 -f 40/101/5 39/102/5 47/103/5 46/104/5 -f 35/105/5 45/106/5 48/107/5 36/108/5 -f 32/109/6 31/110/6 56/111/6 53/112/6 -f 44/113/6 43/114/6 54/115/6 55/116/6 -f 16/16/1 62/117/1 52/118/1 13/13/1 -f 67/119/1 15/15/1 14/14/1 60/120/1 -f 59/121/1 17/17/1 20/20/1 66/122/1 -f 18/18/1 51/123/1 63/124/1 19/19/1 -f 57/125/2 21/21/2 24/24/2 68/126/2 -f 22/22/2 49/127/2 61/128/2 23/23/2 -f 28/28/2 64/129/2 50/130/2 25/25/2 -f 65/131/2 27/27/2 26/26/2 58/132/2 -f 65/131/5 40/133/5 46/46/5 27/27/5 -f 45/45/5 35/134/5 64/129/5 28/28/5 -f 19/49/5 63/135/5 36/136/5 48/50/5 -f 39/137/5 66/138/5 20/48/5 47/47/5 -f 53/59/6 23/23/6 61/128/6 32/139/6 -f 43/140/6 68/126/6 24/24/6 54/60/6 -f 67/141/6 44/142/6 55/61/6 15/64/6 -f 16/63/6 56/62/6 31/143/6 62/144/6 -f 13/13/7 1/1/7 4/4/8 14/14/8 -f 18/90/9 2/2/9 1/1/7 13/91/7 -f 17/17/10 3/3/10 2/2/9 18/18/9 -f 14/95/8 4/4/8 3/3/10 17/96/10 -f 21/21/8 8/8/8 7/7/7 22/22/7 -f 26/97/10 5/5/10 8/8/8 21/98/8 -f 25/25/9 6/6/9 5/5/10 26/26/10 -f 22/99/7 7/7/7 6/6/9 25/100/9 -f 46/46/11 69/145/11 70/146/12 45/45/12 -f 47/103/13 71/147/13 69/145/11 46/104/11 -f 48/50/14 72/148/14 71/147/13 47/47/13 -f 45/106/12 70/146/12 72/148/14 48/107/14 -f 29/29/15 9/9/15 12/12/16 30/30/16 -f 34/53/17 10/10/17 9/9/15 29/54/15 -f 33/33/18 11/11/18 10/10/17 34/34/17 -f 30/55/16 12/12/16 11/11/18 33/56/18 -f 53/59/12 73/149/12 74/150/11 54/60/11 -f 56/111/14 75/151/14 73/149/12 53/112/12 -f 55/61/13 76/152/13 75/151/14 56/62/14 -f 54/115/11 74/150/11 76/152/13 55/116/13 -f 37/37/17 77/153/17 78/154/18 38/38/18 -f 42/66/15 79/155/15 77/153/17 37/67/17 -f 41/41/16 80/156/16 79/155/15 42/42/15 -f 38/70/18 78/154/18 80/156/16 41/71/16 -f 76/152/6 74/150/6 73/149/6 75/151/6 -f 78/154/4 77/153/4 79/155/4 80/156/4 -f 72/148/5 70/146/5 69/145/5 71/147/5 +f 1/1/1 2/4/1 3/9/1 +f 3/9/1 2/4/1 4/12/1 +# Top +s 2 +f 3/1/2 4/4/2 5/9/2 +f 5/9/2 4/4/2 6/12/2 +# Front +s 3 +f 5/1/3 6/4/3 7/9/3 +f 7/9/3 6/4/3 8/12/3 +# Bottom +s 4 +f 7/1/4 8/4/4 1/9/4 +f 1/9/4 8/4/4 2/12/4 +# Right +s 5 +f 2/1/5 8/4/5 4/9/5 +f 4/9/5 8/4/5 6/12/5 +# Left +s 6 +f 7/1/6 1/4/6 5/9/6 +f 5/9/6 1/4/6 3/12/6 \ No newline at end of file diff --git a/assets/wall/breakable_wall.png b/assets/wall/breakable_wall.png index bdbc5fda..8e18cca8 100644 Binary files a/assets/wall/breakable_wall.png and b/assets/wall/breakable_wall.png differ diff --git a/assets/wall/floor.mtl b/assets/wall/floor.mtl new file mode 100644 index 00000000..7925a729 --- /dev/null +++ b/assets/wall/floor.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Cube.001 +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/assets/wall/floor.obj b/assets/wall/floor.obj new file mode 100644 index 00000000..144c9997 --- /dev/null +++ b/assets/wall/floor.obj @@ -0,0 +1,61 @@ +# floor.obj +# + +mtllib floor.mtl +o floor + +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 + +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.666666 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.500000 +vt 0.333333 0.500000 +vt 0.666666 0.500000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.666666 1.000000 +vt 1.000000 1.000000 + +vn 0.000000 0.000000 1.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 + +g floor +usemtl floor +# Back +s 1 +f 1/1/1 2/4/1 3/9/1 +f 3/9/1 2/4/1 4/12/1 +# Top +s 2 +f 3/1/2 4/4/2 5/9/2 +f 5/9/2 4/4/2 6/12/2 +# Front +s 3 +f 5/1/3 6/4/3 7/9/3 +f 7/9/3 6/4/3 8/12/3 +# Bottom +s 4 +f 7/1/4 8/4/4 1/9/4 +f 1/9/4 8/4/4 2/12/4 +# Right +s 5 +f 2/1/5 8/4/5 4/9/5 +f 4/9/5 8/4/5 6/12/5 +# Left +s 6 +f 7/1/6 1/4/6 5/9/6 +f 5/9/6 1/4/6 3/12/6 \ No newline at end of file diff --git a/assets/wall/floor.png b/assets/wall/floor.png new file mode 100644 index 00000000..74624ea9 Binary files /dev/null and b/assets/wall/floor.png differ diff --git a/assets/wall/hole.mtl b/assets/wall/hole.mtl new file mode 100644 index 00000000..7925a729 --- /dev/null +++ b/assets/wall/hole.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Cube.001 +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/assets/wall/hole.obj b/assets/wall/hole.obj new file mode 100644 index 00000000..519fef7e --- /dev/null +++ b/assets/wall/hole.obj @@ -0,0 +1,61 @@ +# hole.obj +# + +mtllib hole.mtl +o hole + +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 + +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.666666 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.500000 +vt 0.333333 0.500000 +vt 0.666666 0.500000 +vt 1.000000 0.500000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.666666 1.000000 +vt 1.000000 1.000000 + +vn 0.000000 0.000000 1.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 + +g floor +usemtl floor +# Back +s 1 +f 1/1/1 2/4/1 3/9/1 +f 3/9/1 2/4/1 4/12/1 +# Top +s 2 +f 3/1/2 4/4/2 5/9/2 +f 5/9/2 4/4/2 6/12/2 +# Front +s 3 +f 5/1/3 6/4/3 7/9/3 +f 7/9/3 6/4/3 8/12/3 +# Bottom +s 4 +f 7/1/4 8/4/4 1/9/4 +f 1/9/4 8/4/4 2/12/4 +# Right +s 5 +f 2/1/5 8/4/5 4/9/5 +f 4/9/5 8/4/5 6/12/5 +# Left +s 6 +f 7/1/6 1/4/6 5/9/6 +f 5/9/6 1/4/6 3/12/6 \ No newline at end of file diff --git a/assets/wall/hole.png b/assets/wall/hole.png new file mode 100644 index 00000000..fe9ee288 Binary files /dev/null and b/assets/wall/hole.png differ diff --git a/emsdk.sh b/build_web.sh similarity index 100% rename from emsdk.sh rename to build_web.sh diff --git a/lib/Ray/CMakeLists.txt b/lib/Ray/CMakeLists.txt index 17d97db0..d713eb1e 100644 --- a/lib/Ray/CMakeLists.txt +++ b/lib/Ray/CMakeLists.txt @@ -56,6 +56,7 @@ set(HEADERS sources/Model/ModelAnimations.hpp sources/Vector/Vector2.hpp sources/Vector/Vector3.hpp + sources/Utils/Cache.hpp ) set(SRC diff --git a/lib/Ray/sources/Controllers/Keyboard.hpp b/lib/Ray/sources/Controllers/Keyboard.hpp index be5c54d2..dcb474ce 100644 --- a/lib/Ray/sources/Controllers/Keyboard.hpp +++ b/lib/Ray/sources/Controllers/Keyboard.hpp @@ -1,4 +1,3 @@ - /* ** EPITECH PROJECT, 2021 ** Bomberman diff --git a/lib/Ray/sources/Drawables/2D/Circle.cpp b/lib/Ray/sources/Drawables/2D/Circle.cpp index c1b5b3cc..cdb63a38 100644 --- a/lib/Ray/sources/Drawables/2D/Circle.cpp +++ b/lib/Ray/sources/Drawables/2D/Circle.cpp @@ -6,6 +6,7 @@ */ #include "Drawables/2D/Circle.hpp" +#include "Drawables/Image.hpp" namespace RAY::Drawables::Drawables2D { diff --git a/lib/Ray/sources/Drawables/2D/Line.cpp b/lib/Ray/sources/Drawables/2D/Line.cpp index 2425ac47..f412236b 100644 --- a/lib/Ray/sources/Drawables/2D/Line.cpp +++ b/lib/Ray/sources/Drawables/2D/Line.cpp @@ -7,6 +7,7 @@ #include "Drawables/2D/Line.hpp" #include +#include "Drawables/Image.hpp" namespace RAY::Drawables::Drawables2D { diff --git a/lib/Ray/sources/Drawables/2D/Point.cpp b/lib/Ray/sources/Drawables/2D/Point.cpp index 34f9f5f7..6118840d 100644 --- a/lib/Ray/sources/Drawables/2D/Point.cpp +++ b/lib/Ray/sources/Drawables/2D/Point.cpp @@ -6,6 +6,7 @@ */ #include "Drawables/2D/Point.hpp" +#include "Drawables/Image.hpp" namespace RAY::Drawables::Drawables2D { diff --git a/lib/Ray/sources/Drawables/2D/Rectangle.cpp b/lib/Ray/sources/Drawables/2D/Rectangle.cpp index 86a1242d..9f623bee 100644 --- a/lib/Ray/sources/Drawables/2D/Rectangle.cpp +++ b/lib/Ray/sources/Drawables/2D/Rectangle.cpp @@ -7,6 +7,7 @@ #include "Drawables/2D/Rectangle.hpp" #include +#include "Drawables/Image.hpp" namespace RAY::Drawables::Drawables2D { @@ -48,4 +49,15 @@ namespace RAY::Drawables::Drawables2D { ImageDrawRectangleV(image, this->_position, this->_dimensions, this->_color); } + + Rectangle::operator ::Rectangle() const + { + ::Rectangle rect; + + rect.x = this->_position.x; + rect.y = this->_position.y; + rect.width = this->_dimensions.x; + rect.height = this->_dimensions.y; + return rect; + } } \ No newline at end of file diff --git a/lib/Ray/sources/Drawables/2D/Rectangle.hpp b/lib/Ray/sources/Drawables/2D/Rectangle.hpp index 18f25d4f..e0d32dff 100644 --- a/lib/Ray/sources/Drawables/2D/Rectangle.hpp +++ b/lib/Ray/sources/Drawables/2D/Rectangle.hpp @@ -20,7 +20,7 @@ namespace RAY::Drawables::Drawables2D { //! @param position position of top-left point //! @param dimensions dimensions of the rectangle //! @param Color Color of the rectangle - Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color); + Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color = WHITE); //! @brief Rectangle constructor //! @param x x-position of top-left point @@ -28,7 +28,7 @@ namespace RAY::Drawables::Drawables2D { //! @param width width of the rectangle //! @param length length of the rectangle //! @param Color Color of the rectangle - Rectangle(int x, int y, int width, int height, const Color &color); + Rectangle(int x, int y, int width, int height, const Color &color = WHITE); //! @brief A default copy constructor Rectangle(const Rectangle &) = default; @@ -37,7 +37,7 @@ namespace RAY::Drawables::Drawables2D { Rectangle &operator=(const Rectangle &) = default; //! @brief A default destructor - ~Rectangle() override = default; + virtual ~Rectangle() override = default; //! @return the dimensions of the rectangle const Vector2 &getDimensions(void); @@ -49,13 +49,16 @@ namespace RAY::Drawables::Drawables2D { Rectangle &setDimensions(int x, int y); //! @brief Draw point on window - void drawOn(RAY::Window &) override; + virtual void drawOn(RAY::Window &) override; //! @brief Draw point on image - void drawOn(RAY::Image &image) override; + virtual void drawOn(RAY::Image &image) override; - private: + protected: //! @brief Diemnsions of the rectangle Vector2 _dimensions; + + INTERNAL: + operator ::Rectangle() const; }; }; diff --git a/lib/Ray/sources/Drawables/2D/Text.cpp b/lib/Ray/sources/Drawables/2D/Text.cpp index 9c679034..327d8fd1 100644 --- a/lib/Ray/sources/Drawables/2D/Text.cpp +++ b/lib/Ray/sources/Drawables/2D/Text.cpp @@ -6,7 +6,7 @@ */ #include "Drawables/2D/Text.hpp" - +#include "Drawables/Image.hpp" #include namespace RAY::Drawables::Drawables2D diff --git a/lib/Ray/sources/Drawables/2D/Triangle.cpp b/lib/Ray/sources/Drawables/2D/Triangle.cpp index 4e90d58c..2a4e6a56 100644 --- a/lib/Ray/sources/Drawables/2D/Triangle.cpp +++ b/lib/Ray/sources/Drawables/2D/Triangle.cpp @@ -7,6 +7,7 @@ #include "Drawables/2D/Triangle.hpp" #include "Exceptions/RayError.hpp" +#include "Drawables/Image.hpp" namespace RAY::Drawables::Drawables2D { diff --git a/lib/Ray/sources/Drawables/ADrawable2D.cpp b/lib/Ray/sources/Drawables/ADrawable2D.cpp index af031e36..0dd9804a 100644 --- a/lib/Ray/sources/Drawables/ADrawable2D.cpp +++ b/lib/Ray/sources/Drawables/ADrawable2D.cpp @@ -6,6 +6,7 @@ */ #include "Drawables/ADrawable2D.hpp" +#include "Image.hpp" namespace RAY::Drawables { diff --git a/lib/Ray/sources/Drawables/ADrawable2D.hpp b/lib/Ray/sources/Drawables/ADrawable2D.hpp index 46a9407b..f2364539 100644 --- a/lib/Ray/sources/Drawables/ADrawable2D.hpp +++ b/lib/Ray/sources/Drawables/ADrawable2D.hpp @@ -10,10 +10,12 @@ #include #include "Vector/Vector2.hpp" -#include "Image.hpp" #include "Drawables/IDrawable.hpp" #include "Color.hpp" +namespace RAY { + class Image; +} namespace RAY::Drawables { //! @brief Abstraction of any two-dimensionnal drawable class ADrawable2D: public IDrawable diff --git a/lib/Ray/sources/Drawables/Image.cpp b/lib/Ray/sources/Drawables/Image.cpp index 0145e642..9676bc95 100644 --- a/lib/Ray/sources/Drawables/Image.cpp +++ b/lib/Ray/sources/Drawables/Image.cpp @@ -6,36 +6,57 @@ */ #include "Drawables/Image.hpp" -#include "Drawables/IDrawable.hpp" +#include "Drawables/ADrawable2D.hpp" +#include "Drawables/2D/Rectangle.hpp" -RAY::Image::Image(const std::string &filename): - _image(LoadImage(filename.c_str())) -{ -} +namespace RAY { + Cache<::Image> Image::_imagesCache(LoadImage, UnloadImage); -RAY::Image::Image(RAY::Texture &texture): - _image(GetTextureData(texture)) -{ + Image::Image(const std::string &filename): + Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE), + _image(_imagesCache.fetch(filename)) + { + this->_dimensions = Vector2(this->_image->width, this->_image->height); + } -} + bool Image::exportTo(const std::string &outputPath) + { + ExportImage(*this->_image, outputPath.c_str()); + return true; + } -RAY::Image::~Image() -{ - UnloadImage(_image); -} + Image::operator ::Image() const + { + return *this->_image; + } -bool RAY::Image::exportTo(const std::string &outputPath) -{ - ExportImage(_image, outputPath.c_str()); - return true; -} + Image::operator ::Image *() + { + return this->_image.get(); + } -RAY::Image::operator ::Image() const -{ - return _image; -} + void Image::draw(Drawables::ADrawable2D &drawable) + { + drawable.drawOn(*this); + } -RAY::Image::operator ::Image *() -{ - return &this->_image; + void Image::drawOn(RAY::Window &) + { + //Since the image is a shared object, when it is resized, it mush be resized after to its previous dimensions + Vector2 oldDims = Vector2(this->_image->width, this->_image->height); + + ImageResize(*this, this->_dimensions.x, this->_dimensions.y); + Texture texture(*this); + + DrawTexture(texture, this->_position.x, this->_position.y, this->_color); + ImageResize(*this, oldDims.x, oldDims.y); + } + + void Image::drawOn(RAY::Image &image) + { + Drawables::Drawables2D::Rectangle dest(this->_position, this->getDimensions()); + Drawables::Drawables2D::Rectangle src(Vector2(0, 0), this->getDimensions()); + + ImageDraw(image, *this, dest, src, this->_color); + } } \ No newline at end of file diff --git a/lib/Ray/sources/Drawables/Image.hpp b/lib/Ray/sources/Drawables/Image.hpp index ac802580..840be518 100644 --- a/lib/Ray/sources/Drawables/Image.hpp +++ b/lib/Ray/sources/Drawables/Image.hpp @@ -11,43 +11,47 @@ #include #include #include "Texture.hpp" +#include "Utils/Cache.hpp" +#include "Drawables/2D/Rectangle.hpp" namespace RAY { - namespace Drawables { - class ADrawable2D; - } //! @brief Object representation of a framebuffer - class Image { + class Image: public Drawables::Drawables2D::Rectangle { public: //! @brief Create an image, loading a file //! @param filename: path to file to load Image(const std::string &filename); - //! @brief Create an image, using data from a texure - //! @param texture: texture to extract data from - Image(Texture &texture); - //! @brief A default copy constructor - Image(const Image &image) = delete; + Image(const Image &image) = default; //! @brief An image is assignable - Image &operator=(const Image &image) = delete; + Image &operator=(const Image &image) = default; //! @brief Image destructor, will unload ressources - ~Image(); + ~Image() override = default; //! @brief export to file //! @param outputPath: path of output bool exportTo(const std::string &outputPath); - - //! @brief draw drawable + //! @brief draw drawable on image void draw(Drawables::ADrawable2D &); + //! @brief Draw image on window + void drawOn(RAY::Window &) override; + + //! @brief Draw image on another image + void drawOn(RAY::Image &image) override; + + private: //! @brief Image, really, that's just it... - ::Image _image; + std::shared_ptr<::Image> _image; + + static Cache<::Image> _imagesCache; + INTERNAL: //! @brief get image diff --git a/lib/Ray/sources/Drawables/Texture.cpp b/lib/Ray/sources/Drawables/Texture.cpp index a92e1349..befe8579 100644 --- a/lib/Ray/sources/Drawables/Texture.cpp +++ b/lib/Ray/sources/Drawables/Texture.cpp @@ -9,34 +9,22 @@ namespace RAY { + Cache<::Texture> Texture::_texturesCache(LoadTexture, UnloadTexture); + Texture::Texture(const std::string &filename): - _texture(LoadTexture(filename.c_str())), + _texture(_texturesCache.fetch(filename)), _resourcePath(filename) { } - Texture::Texture(const Texture &texture): - _texture(LoadTexture(texture._resourcePath.c_str())), - _resourcePath(texture._resourcePath) + Texture::Texture(const Image &image): + _texture(std::make_shared<::Texture>(LoadTextureFromImage(image))), + _resourcePath() { } - - Texture &Texture::operator=(const Texture &other) - { - UnloadTexture(this->_texture); - this->_resourcePath = other._resourcePath; - this->_texture = LoadTexture(this->_resourcePath.c_str()); - return *this; - } - - Texture::~Texture() - { - UnloadTexture(this->_texture); - } - Texture::operator ::Texture() const { - return this->_texture; + return *this->_texture; } } diff --git a/lib/Ray/sources/Drawables/Texture.hpp b/lib/Ray/sources/Drawables/Texture.hpp index a2054b1a..6fb2be66 100644 --- a/lib/Ray/sources/Drawables/Texture.hpp +++ b/lib/Ray/sources/Drawables/Texture.hpp @@ -10,6 +10,7 @@ #include #include +#include "Utils/Cache.hpp" namespace RAY { @@ -20,22 +21,28 @@ namespace RAY //! @param filename: path to file to load Texture(const std::string &filename); - //! @brief A texture is not copy constructable - Texture(const Texture &); + //! @brief A texture is copy constructable + Texture(const Texture &) = default; - //! @brief An image is assignable - Texture &operator=(const Texture &); + //! @brief A textrue can be loaded from an image + Texture(const Image &); + + //! @brief An texture is assignable + Texture &operator=(const Texture &) = default; - //! @brief Texture destructor, will unload ressources - ~Texture(); + //! @brief Texture destructor, will not unload ressources + ~Texture() = default; protected: private: //! @brief Texture, really, that's just it... - ::Texture _texture; + std::shared_ptr<::Texture> _texture; + //! @brief path to the file the texture is loaded from std::string _resourcePath; + static Cache<::Texture> _texturesCache; + INTERNAL: //! @return libray Texture struct operator ::Texture() const; diff --git a/lib/Ray/sources/Font.cpp b/lib/Ray/sources/Font.cpp index 00711def..c4288463 100644 --- a/lib/Ray/sources/Font.cpp +++ b/lib/Ray/sources/Font.cpp @@ -7,16 +7,14 @@ #include "Font.hpp" +RAY::Cache<::Font> RAY::Font::_fontsCache(LoadFont, UnloadFont); + RAY::Font::Font(const std::string &filename): - _font(LoadFont(filename.c_str())) + _font(_fontsCache.fetch(filename)) { } -RAY::Font::Font() +RAY::Font::Font(): + _font(std::make_shared<::Font>()) { } - -RAY::Font::~Font() -{ - UnloadFont(this->_font); -} diff --git a/lib/Ray/sources/Font.hpp b/lib/Ray/sources/Font.hpp index 1ad65a1e..a403dcb3 100644 --- a/lib/Ray/sources/Font.hpp +++ b/lib/Ray/sources/Font.hpp @@ -10,6 +10,7 @@ #include #include +#include "Utils/Cache.hpp" namespace RAY { @@ -29,13 +30,15 @@ namespace RAY //! @brief An font is assignable Font &operator=(const Font &) = default; - //! @brief Unload font at destruction - ~Font(); + //! @brief Default destructor + ~Font() = default; protected: private: //! @brief Font, really, that's just it... - ::Font _font; + std::shared_ptr<::Font> _font; + + static Cache<::Font> _fontsCache; }; } diff --git a/lib/Ray/sources/Model/Model.cpp b/lib/Ray/sources/Model/Model.cpp index cb4cd024..aab5fdc6 100644 --- a/lib/Ray/sources/Model/Model.cpp +++ b/lib/Ray/sources/Model/Model.cpp @@ -7,17 +7,21 @@ #include "Model/Model.hpp" #include "Exceptions/RayError.hpp" +#include + namespace RAY::Drawables::Drawables3D { + RAY::Cache<::Model> Model::_modelsCache(LoadModel, UnloadModel); + Model::Model(const std::string &filename, std::optional> texture, + const RAY::Vector3 &scale, const RAY::Vector3 &position, const RAY::Vector3 &rotationAxis, - float rotationAngle, - const RAY::Vector3 &scale) + float rotationAngle) : ADrawable3D(position, WHITE), - _model(LoadModel(filename.c_str())), + _model(_modelsCache.fetch(filename)), _rotationAxis(rotationAxis), _rotationAngle(rotationAngle), _scale(scale) @@ -27,33 +31,29 @@ namespace RAY::Drawables::Drawables3D { } Model::Model(const Mesh &mesh) - : ADrawable3D({0, 0, 0}, WHITE), _model(LoadModelFromMesh(mesh)) + : ADrawable3D({0, 0, 0}, WHITE), + _model(std::make_shared<::Model>(LoadModelFromMesh(mesh))) { } - Model::~Model() - { - UnloadModel(this->_model); - } - bool Model::unloadKeepMeshes() { - UnloadModelKeepMeshes(_model); + UnloadModelKeepMeshes(*this->_model); return true; } bool Model::setAnimation(const RAY::ModelAnimation &animation) { - if (!IsModelAnimationValid(this->_model, animation)) + if (!IsModelAnimationValid(*this->_model, animation)) throw RAY::Exception::NotCompatibleError("The animation is not compatible with the model"); - UpdateModelAnimation(this->_model, animation, animation.getFrameCounter()); + UpdateModelAnimation(*this->_model, animation, animation.getFrameCounter()); return true; } bool Model::setTextureToMaterial(Model::MaterialType materialType, const std::string &texturePath) { this->_textureList.emplace(materialType, texturePath); - SetMaterialTexture(&this->_model.materials[materialType], + SetMaterialTexture(&this->_model->materials[materialType], materialType, this->_textureList.at(materialType)); return true; @@ -61,12 +61,12 @@ namespace RAY::Drawables::Drawables3D { Model::operator ::Model() const { - return this->_model; + return *this->_model; } int Model::getBoneCount() const { - return this->_model.boneCount; + return this->_model->boneCount; } Model &Model::setRotationAngle(float rotationAngle) @@ -104,6 +104,6 @@ namespace RAY::Drawables::Drawables3D { void Model::drawOn(RAY::Window &) { - DrawModelEx(this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color); + DrawModelEx(*this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color); } } \ No newline at end of file diff --git a/lib/Ray/sources/Model/Model.hpp b/lib/Ray/sources/Model/Model.hpp index 039304ae..7a7e3fdf 100644 --- a/lib/Ray/sources/Model/Model.hpp +++ b/lib/Ray/sources/Model/Model.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include "Utils/Cache.hpp" namespace RAY::Drawables::Drawables3D { //! @brief Basic 3D Model type @@ -27,10 +27,10 @@ namespace RAY::Drawables::Drawables3D { //! @param filePath: path to file to load Model(const std::string &filePath, std::optional> texture = std::nullopt, + const RAY::Vector3 &scale = RAY::Vector3(1, 1, 1), const RAY::Vector3 &position = {0, 0, 0}, const RAY::Vector3 &rotationAxis = RAY::Vector3(0, 1, 0), - float rotationAngle = 0, - const RAY::Vector3 &scale = RAY::Vector3(1, 1, 1)); + float rotationAngle = 0); //! @brief Create an model, loading a file //! @param mesh: mesh to load @@ -42,8 +42,8 @@ namespace RAY::Drawables::Drawables3D { //! @brief A model is assignable Model& operator=(const Model &model) = default; - //! @brief Model destructor, unloads all related data - ~Model(); + //! @brief Model destructor, model's data will be deleted if it's the last entity alive + ~Model() override = default; //! @brief Unload model (excluding meshes) from memory (RAM and/or VRAM) bool unloadKeepMeshes(); @@ -81,9 +81,9 @@ namespace RAY::Drawables::Drawables3D { private: //! @brief Raw data from raylib - ::Model _model; + std::shared_ptr<::Model> _model; //! @brief The list of textures that can be applied to this model. - std::map _textureList; + std::unordered_map _textureList; //! @brief Rotation property RAY::Vector3 _rotationAxis; //! @brief Rotation property @@ -91,6 +91,8 @@ namespace RAY::Drawables::Drawables3D { //! @brief Scale of the shape RAY::Vector3 _scale; + static RAY::Cache<::Model> _modelsCache; + INTERNAL: //! @brief A RAY Model is cast-able in libray's model operator ::Model() const; diff --git a/lib/Ray/sources/Model/ModelAnimations.cpp b/lib/Ray/sources/Model/ModelAnimations.cpp index 224b9979..0bd88c03 100644 --- a/lib/Ray/sources/Model/ModelAnimations.cpp +++ b/lib/Ray/sources/Model/ModelAnimations.cpp @@ -7,8 +7,10 @@ #include "Model/ModelAnimations.hpp" +RAY::Cache<::ModelAnimation> RAY::ModelAnimations::_animationsCache(LoadModelAnimations, UnloadModelAnimations); + RAY::ModelAnimations::ModelAnimations(const std::string &filePath): - _animationsPtr(LoadModelAnimations(filePath.c_str(), &this->_animationCount)) + _animationsPtr(_animationsCache.fetch(filePath, &this->_animationCount)) { ::ModelAnimation *ptr = this->_animationsPtr.get(); @@ -16,11 +18,6 @@ RAY::ModelAnimations::ModelAnimations(const std::string &filePath): this->_animations.push_back(RAY::ModelAnimation(ptr[i])); } -RAY::ModelAnimations::~ModelAnimations() -{ - UnloadModelAnimations(this->_animationsPtr.release(), this->_animationCount); -} - RAY::ModelAnimation &RAY::ModelAnimations::operator[](int index) { return this->_animations[index]; diff --git a/lib/Ray/sources/Model/ModelAnimations.hpp b/lib/Ray/sources/Model/ModelAnimations.hpp index cad0d038..ba46a0e4 100644 --- a/lib/Ray/sources/Model/ModelAnimations.hpp +++ b/lib/Ray/sources/Model/ModelAnimations.hpp @@ -11,6 +11,7 @@ #include "Model/ModelAnimation.hpp" #include #include +#include "Utils/Cache.hpp" namespace RAY { //! @brief A Holder for Model Animations @@ -23,8 +24,8 @@ namespace RAY { //! @brief Only single entity can hold these animations pointers ModelAnimations(const ModelAnimations &) = delete; - //! @brief Unloads all animations - ~ModelAnimations(); + //! @brief Default constructor + ~ModelAnimations() = default; //! @brief Only single entity can hold these animations pointers ModelAnimations &operator=(const ModelAnimations &) = delete; @@ -37,13 +38,15 @@ namespace RAY { private: //! @brief Holds the pointer returned by the loading function - std::unique_ptr<::ModelAnimation> _animationsPtr; + std::shared_ptr<::ModelAnimation> _animationsPtr; //! @brief A holder for animations std::vector _animations; //! @brief the number of loaded animations int _animationCount; + + static Cache<::ModelAnimation> _animationsCache; }; } diff --git a/lib/Ray/sources/Utils/Cache.hpp b/lib/Ray/sources/Utils/Cache.hpp new file mode 100644 index 00000000..f30fa3ff --- /dev/null +++ b/lib/Ray/sources/Utils/Cache.hpp @@ -0,0 +1,81 @@ +/* +** EPITECH PROJECT, 2021 +** Bomberman +** File description: +** Cache +*/ + +#pragma once +#include +#include +#include + +namespace RAY { + //! @brief A templated class used to cache ressources, indexed with a string + template + class Cache { + public: + //! @brief + Cache(std::function dataLoader, std::function dataUnloader): + _dataLoader(dataLoader), _dataUnloader(dataUnloader) + {}; + + //! @brief Default destructor, will destroy ray's data + ~Cache() = default; + + //! @brief default copy constructor + Cache(const Cache &) = default; + + //! @brief a cache is assignable + Cache &operator=(const Cache &) = default; + + //! @param path path of the file + //! @return a newly loaded ressource if it hasn't be previously loaded, or one from cache + std::shared_ptrfetch(const std::string &path) + { + if (this->_cache.find(path) == this->_cache.end()) + this->_cache.emplace(path, std::shared_ptr( + new T(this->_dataLoader(path.c_str())), [this](T *p) { + this->_dataUnloader(*p); + delete p; + })); + return _cache[path]; + }; + private: + //! @brief function to call to load data + std::function _dataLoader; + + //! @brief function to call when the ray data will be unloaded + std::function _dataUnloader; + + //! @brief map storing shared ptr of caches + std::unordered_map> _cache; + }; + + template<> + class Cache<::ModelAnimation> { + public: + Cache(std::function<::ModelAnimation *(const char *, int *)> dataLoader, std::functiondataUnloader): + _dataLoader(dataLoader), _dataUnloader(dataUnloader) + {}; + std::shared_ptr<::ModelAnimation> fetch(const std::string &path, int *counter) + { + if (this->_cache.find(path) == this->_cache.end()) + this->_cache.emplace(path, std::shared_ptr<::ModelAnimation>( + this->_dataLoader(path.c_str(), counter), [this, counter](::ModelAnimation *p) { + this->_dataUnloader(p, *counter); + delete p; + })); + return _cache[path]; + }; + private: + //! @brief function to call to load data + std::function<::ModelAnimation *(const char *, int *)> _dataLoader; + + //! @brief function to call when the ray data will be unloaded + std::function _dataUnloader; + + //! @brief map storing shared ptr of caches + std::unordered_map> _cache; + }; +} diff --git a/lib/Ray/sources/Window.cpp b/lib/Ray/sources/Window.cpp index c89c6363..2cef08f1 100644 --- a/lib/Ray/sources/Window.cpp +++ b/lib/Ray/sources/Window.cpp @@ -11,6 +11,7 @@ #include "Controllers/Mouse.hpp" #include "Drawables/ADrawable2D.hpp" #include "Drawables/ADrawable3D.hpp" +#include "Drawables/Image.hpp" std::optional RAY::Window::_instance = std::nullopt; @@ -102,7 +103,7 @@ void RAY::Window::setFPS(unsigned int fps) SetTargetFPS(fps); } -void RAY::Window::clear(const RAY::Color &color) +void RAY::Window::clear(RAY::Color color) { ClearBackground(color); } diff --git a/lib/Ray/sources/Window.hpp b/lib/Ray/sources/Window.hpp index a02c78f9..2aa128ec 100644 --- a/lib/Ray/sources/Window.hpp +++ b/lib/Ray/sources/Window.hpp @@ -11,7 +11,6 @@ #include #include #include -#include "Drawables/Image.hpp" #include "Vector/Vector2.hpp" #include "Vector/Vector3.hpp" #include "Controllers/Keyboard.hpp" @@ -22,6 +21,7 @@ namespace RAY { //! @brief Window manager + class Image; namespace Drawables { class IDrawable; class ADrawable3D; @@ -90,7 +90,7 @@ namespace RAY { //! @brief Set background color (framebuffer clear color) //! @param color The color to clear the screen (default: black) - void clear(const Color &color = BLACK); + void clear(Color color = BLACK); //! @brief Different states of the view of the window enum displayState { diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp new file mode 100644 index 00000000..22cbdef8 --- /dev/null +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -0,0 +1,42 @@ +// +// Created by Louis Auzuret on 2021-05-20. +// + +#include "Component/Collision/CollisionComponent.hpp" + + +namespace BBM +{ + CollisionComponent::CollisionComponent(WAL::Entity &entity) + : WAL::Component(entity) + { } + + WAL::Component *CollisionComponent::clone(WAL::Entity &entity) const + { + return new CollisionComponent(entity); + } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, std::function onCollide, std::function onCollided, Vector3f bound) + : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound(bound) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, std::function onCollide, std::function onCollided, float boundSize) + : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound({boundSize, boundSize, boundSize}) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, Vector3f bound) + : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound(bound) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, float boundSize) + : WAL::Component(entity), onCollide(onCollide), onCollided(onCollided), bound({boundSize, boundSize, boundSize}) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, Vector3f bound) + : WAL::Component(entity), onCollide(), onCollided(), bound(bound) + { } + + CollisionComponent::CollisionComponent(WAL::Entity &entity, float boundSize) + : WAL::Component(entity), onCollide(), onCollided(), bound({boundSize, boundSize, boundSize}) + { } +} \ No newline at end of file diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp new file mode 100644 index 00000000..4636c79a --- /dev/null +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -0,0 +1,57 @@ +// +// Created by Louis Auzuret on 2021-05-20. +// + +#pragma once + +#include "Models/Callback.hpp" +#include "Models/Vector3.hpp" +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + class CollisionComponent : public WAL::Component + { + private: + public: + //! @brief onCollide functions to be called + WAL::Callback onCollide; + //! @brief onCollided functions to be called + WAL::Callback onCollided; + //! @brief Bound size on all axis + Vector3f bound; + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief A component can't be instantiated, it should be derived. + explicit CollisionComponent(WAL::Entity &entity); + + //! @brief Constructor with a callback function + CollisionComponent(WAL::Entity &entity, std::function onCollide, std::function onCollided, Vector3f bound); + + //! @brief Constructor with a callback function, same boundSize for all axis + CollisionComponent(WAL::Entity &entity, std::function onCollide, std::function onCollided, float boundSize = 0); + + //! @brief Constructor with a WAL::Callback + CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided,Vector3f bound); + + //! @brief Constructor with a WAL::Callback, same boundSize for all axis + CollisionComponent(WAL::Entity &entity, WAL::Callback onCollide, WAL::Callback onCollided, float boundSize = 0); + + //! @brief Constructor of collider with no callback + CollisionComponent(WAL::Entity &entity, Vector3f bound); + + //! @brief Constructor no callback, same boundSize for all axis + CollisionComponent(WAL::Entity &entity, float boundSize); + + //! @brief Default copy constructor + CollisionComponent(const CollisionComponent &) = default; + + //! @brief default destructor + ~CollisionComponent() override = default; + + //! @brief A component can't be assigned + CollisionComponent &operator=(const CollisionComponent &) = delete; + }; +} \ No newline at end of file diff --git a/sources/Component/Controllable/ControllableComponent.cpp b/sources/Component/Controllable/ControllableComponent.cpp new file mode 100644 index 00000000..959d372a --- /dev/null +++ b/sources/Component/Controllable/ControllableComponent.cpp @@ -0,0 +1,17 @@ +// +// Created by Zoe Roux on 5/24/21. +// + +#include "ControllableComponent.hpp" + +namespace BBM +{ + ControllableComponent::ControllableComponent(WAL::Entity &entity) + : WAL::Component(entity) + {} + + WAL::Component *ControllableComponent::clone(WAL::Entity &entity) const + { + return new ControllableComponent(entity); + } +} \ No newline at end of file diff --git a/sources/Component/Controllable/ControllableComponent.hpp b/sources/Component/Controllable/ControllableComponent.hpp new file mode 100644 index 00000000..8376d43f --- /dev/null +++ b/sources/Component/Controllable/ControllableComponent.hpp @@ -0,0 +1,38 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + class ControllableComponent : public WAL::Component + { + public: + //! @brief The X and Z abscis of the movement. + Vector2f move; + //! @brief input value for jump + bool jump = false; + //! @brief input value for bomb + bool bomb = false; + //! @brief input value for pause + bool pause = false; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Initialize a new controllable component. + explicit ControllableComponent(WAL::Entity &entity); + //! @brief A Controllable component is copy constructable. + ControllableComponent(const ControllableComponent &) = default; + //! @brief default destructor + ~ControllableComponent() override = default; + //! @brief A Controllable component can't be assigned + ControllableComponent &operator=(const ControllableComponent &) = delete; + }; +} \ No newline at end of file diff --git a/sources/Component/Gamepad/GamepadComponent.cpp b/sources/Component/Gamepad/GamepadComponent.cpp new file mode 100644 index 00000000..0b889b7a --- /dev/null +++ b/sources/Component/Gamepad/GamepadComponent.cpp @@ -0,0 +1,34 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#include "GamepadComponent.hpp" + +namespace BBM +{ + GamepadComponent::GamepadComponent(WAL::Entity &entity) + : WAL::Component(entity), _ID(0) + {} + + GamepadComponent::GamepadComponent(WAL::Entity &entity, int ID) + : WAL::Component(entity), _ID(ID) + {} + + WAL::Component *GamepadComponent::clone(WAL::Entity &entity) const + { + return new GamepadComponent(entity, _ID); + } + + GamepadComponent &GamepadComponent::setID(int ID) + { + this->_ID = ID; + return *this; + } + + int GamepadComponent::getID() const + { + return this->_ID; + } + +} // namespace BMM diff --git a/sources/Component/Gamepad/GamepadComponent.hpp b/sources/Component/Gamepad/GamepadComponent.hpp new file mode 100644 index 00000000..be00a49b --- /dev/null +++ b/sources/Component/Gamepad/GamepadComponent.hpp @@ -0,0 +1,62 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include "Controllers/Gamepad.hpp" +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +using Button = RAY::Controller::GamePad::Button; +using Gamepad = RAY::Controller::GamePad; + +namespace BBM +{ + class GamepadComponent : public WAL::Component + { + private: + //! @brief Identifier of the gamepad, used to fetch events + int _ID; + public: + //! @brief jump key + Button keyJump = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; + //! @brief bomb key + Button keyBomb = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; + //! @brief pause key + Button keyPause = GAMEPAD_BUTTON_MIDDLE; + //! @brief move right key + Button keyRight = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; + //! @brief move left key + Button keyLeft = GAMEPAD_BUTTON_LEFT_FACE_LEFT; + //! @brief move up key + Button keyUp = GAMEPAD_BUTTON_LEFT_FACE_UP; + //! @brief move down key + Button keyDown = GAMEPAD_BUTTON_LEFT_FACE_DOWN; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new gampad component using default keys. + explicit GamepadComponent(WAL::Entity &entity); + + //! @brief Create a new PositionComponent at a certain position + GamepadComponent(WAL::Entity &entity, int id); + + //! @brief A Gamepad component is copy constructable. + GamepadComponent(const GamepadComponent &) = default; + + //! @brief default destructor + ~GamepadComponent() override = default; + + //! @brief A Gamepad component can't be assigned + GamepadComponent &operator=(const GamepadComponent &) = delete; + + //! @brief Set the ID of the Gamepad the events must be fetch from; + GamepadComponent &setID(int ID); + + //! @brief Get the ID of the Gamepad the events must be fetch from; + int getID() const; + }; +} \ No newline at end of file diff --git a/sources/Component/GridCentered/GridCenteredComponent.cpp b/sources/Component/GridCentered/GridCenteredComponent.cpp new file mode 100644 index 00000000..d4b333b4 --- /dev/null +++ b/sources/Component/GridCentered/GridCenteredComponent.cpp @@ -0,0 +1,17 @@ +// +// Created by Zoe Roux on 5/24/21. +// + +#include "GridCenteredComponent.hpp" + +namespace BBM +{ + GridCenteredComponent::GridCenteredComponent(WAL::Entity &entity) + : WAL::Component(entity) + {} + + WAL::Component *GridCenteredComponent::clone(WAL::Entity &entity) const + { + return new GridCenteredComponent(entity); + } +} \ No newline at end of file diff --git a/sources/Component/GridCentered/GridCenteredComponent.hpp b/sources/Component/GridCentered/GridCenteredComponent.hpp new file mode 100644 index 00000000..d4de0eed --- /dev/null +++ b/sources/Component/GridCentered/GridCenteredComponent.hpp @@ -0,0 +1,33 @@ +// +// Created by Zoe Roux on 5/24/21. +// + +#pragma once + +#include + +namespace BBM +{ + //! @brief A component to slowly center entities to the middle of their current block. + //! This allow flexibility in their movement will preventing them from getting stuck at every corner. + class GridCenteredComponent : public WAL::Component + { + public: + //! @brief The force factor applied at each frame. + float force = 1; + + //! @inherit + Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new, default GridCenteredComponent. + //! @param entity The entity attached to this component. + explicit GridCenteredComponent(WAL::Entity &entity); + //! @brief A GridCenteredComponent is copy constructable + //! @param other The other GridCenteredComponent to copy. + GridCenteredComponent(const GridCenteredComponent &other) = default; + //! @brief A default destructor + ~GridCenteredComponent() override = default; + //! @brief A GridCenteredComponent is not assignable + GridCenteredComponent &operator=(const GridCenteredComponent &) = delete; + }; +} diff --git a/sources/Component/Health/HealthComponent.cpp b/sources/Component/Health/HealthComponent.cpp new file mode 100644 index 00000000..fe81fabb --- /dev/null +++ b/sources/Component/Health/HealthComponent.cpp @@ -0,0 +1,43 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// Edited by Louis Auzuret on 2021-05-20. +// + +#include "HealthComponent.hpp" + +namespace BBM +{ + HealthComponent::HealthComponent(WAL::Entity &entity) + : WAL::Component(entity), + _healthPoint() + {} + + HealthComponent::HealthComponent(WAL::Entity &entity, unsigned int healthPoint) + : WAL::Component(entity), + _healthPoint(healthPoint) + {} + + WAL::Component *HealthComponent::clone(WAL::Entity &entity) const + { + return new HealthComponent(entity); + } + + void HealthComponent::addHealthPoint(unsigned int healthPoint) + { + this->_healthPoint += healthPoint; + } + + void HealthComponent::takeDmg(unsigned int damage) + { + if (damage >= this->_healthPoint) { + this->_healthPoint = 0; + } else + this->_healthPoint -= damage; + } + + unsigned int HealthComponent::getHealthPoint(void) const + { + return (this->_healthPoint); + } +} \ No newline at end of file diff --git a/sources/Component/Health/HealthComponent.hpp b/sources/Component/Health/HealthComponent.hpp new file mode 100644 index 00000000..2eadafc5 --- /dev/null +++ b/sources/Component/Health/HealthComponent.hpp @@ -0,0 +1,53 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// Edited by Louis Auzuret on 2021-05-20. +// + +#pragma once + +#include +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + class HealthComponent : public WAL::Component + { + + private: + //! @brief life of an entity + unsigned int _healthPoint; + + public: + //! @brief The callback invoked on this entity's death. + WAL::Callback onDeath; + + //! @brief add health to the entity + void addHealthPoint(unsigned int healthPoint); + + //! @brief reduce health + void takeDmg(unsigned int damage); + + //! @brief return health point of the entity + unsigned int getHealthPoint(void) const; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief A Health component can't be instantiated, it should be derived. + explicit HealthComponent(WAL::Entity &entity); + + //! @brief Constructor + HealthComponent(WAL::Entity &entity, unsigned int healthPoint); + + //! @brief A Health component can't be instantiated, it should be derived. + HealthComponent(const HealthComponent &) = default; + + //! @brief default destructor + ~HealthComponent() override = default; + + //! @brief A Health component can't be assigned + HealthComponent &operator=(const HealthComponent &) = delete; + }; +} \ No newline at end of file diff --git a/sources/Component/Keyboard/KeyboardComponent.cpp b/sources/Component/Keyboard/KeyboardComponent.cpp new file mode 100644 index 00000000..de379862 --- /dev/null +++ b/sources/Component/Keyboard/KeyboardComponent.cpp @@ -0,0 +1,19 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#include "KeyboardComponent.hpp" + +namespace BBM +{ + KeyboardComponent::KeyboardComponent(WAL::Entity &entity) + : WAL::Component(entity) + {} + + WAL::Component *KeyboardComponent::clone(WAL::Entity &entity) const + { + return new KeyboardComponent(entity); + } + +} // namespace BMM diff --git a/sources/Component/Keyboard/KeyboardComponent.hpp b/sources/Component/Keyboard/KeyboardComponent.hpp new file mode 100644 index 00000000..bd0f2ab7 --- /dev/null +++ b/sources/Component/Keyboard/KeyboardComponent.hpp @@ -0,0 +1,49 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include +#include "Component/Component.hpp" +#include "Entity/Entity.hpp" + +using Key = RAY::Controller::Keyboard::Key; + +namespace BBM +{ + class KeyboardComponent : public WAL::Component + { + public: + //! @brief jump key + Key keyJump = KEY_SPACE; + //! @brief bomb key + Key keyBomb = KEY_E; + //! @brief pause key + Key keyPause = KEY_ESCAPE; + //! @brief move right key + Key keyRight = KEY_A; + //! @brief move left key + Key keyLeft = KEY_D; + //! @brief move up key + Key keyUp = KEY_W; + //! @brief move down key + Key keyDown = KEY_S; + + //! @inherit + WAL::Component *clone(WAL::Entity &entity) const override; + + //! @brief Create a new keyboard component using default keys. + explicit KeyboardComponent(WAL::Entity &entity); + + //! @brief A Keyboard component is copy constructable. + KeyboardComponent(const KeyboardComponent &) = default; + + //! @brief default destructor + ~KeyboardComponent() override = default; + + //! @brief A Keyboard component can't be assigned + KeyboardComponent &operator=(const KeyboardComponent &) = delete; + }; +} \ No newline at end of file diff --git a/sources/Component/Movable/MovableComponent.cpp b/sources/Component/Movable/MovableComponent.cpp index 4fc9bc0c..51f0707d 100644 --- a/sources/Component/Movable/MovableComponent.cpp +++ b/sources/Component/Movable/MovableComponent.cpp @@ -19,4 +19,15 @@ namespace BBM { this->_acceleration += force; } + + void MovableComponent::resetVelocity(void) + { + this->_velocity = {0, 0, 0}; + } + + const Vector3f &MovableComponent::getVelocity(void) const + { + return _velocity; + } + } // namespace WAL \ No newline at end of file diff --git a/sources/Component/Movable/MovableComponent.hpp b/sources/Component/Movable/MovableComponent.hpp index 7656a960..13c8bf90 100644 --- a/sources/Component/Movable/MovableComponent.hpp +++ b/sources/Component/Movable/MovableComponent.hpp @@ -18,10 +18,17 @@ namespace BBM //! @brief The velocity of the entity. Vector3f _velocity; public: + //! @brief Add an instant force to this entity. //! @param force The force to add to this entity's acceleration. The force is added instantly and in one go. void addForce(Vector3f force); + //! @brief Set velocity to 0 + void resetVelocity(void); + + //! @brief Get velocity + const Vector3f &getVelocity(void) const; + //! @inherit WAL::Component *clone(WAL::Entity &entity) const override; diff --git a/sources/Component/Renderer/CameraComponent.cpp b/sources/Component/Renderer/CameraComponent.cpp index 3f6c1239..5934d527 100644 --- a/sources/Component/Renderer/CameraComponent.cpp +++ b/sources/Component/Renderer/CameraComponent.cpp @@ -6,8 +6,9 @@ namespace BBM { - CameraComponent::CameraComponent(WAL::Entity &entity) - : Component(entity) + CameraComponent::CameraComponent(WAL::Entity &entity, Vector3f target) + : Component(entity), + target(target) {} WAL::Component *BBM::CameraComponent::clone(WAL::Entity &entity) const diff --git a/sources/Component/Renderer/CameraComponent.hpp b/sources/Component/Renderer/CameraComponent.hpp index 1aa5cc38..3f8e7fc5 100644 --- a/sources/Component/Renderer/CameraComponent.hpp +++ b/sources/Component/Renderer/CameraComponent.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace BBM { @@ -13,11 +14,14 @@ namespace BBM class CameraComponent : public WAL::Component { public: + //! @brief The camera's target, the cam will look at this position. + Vector3f target; + //! @inherit Component *clone(WAL::Entity &entity) const override; //! @brief Ctor - explicit CameraComponent(WAL::Entity &); + explicit CameraComponent(WAL::Entity &, Vector3f target = Vector3f()); //! @brief A camera component is copy constructable. CameraComponent(const CameraComponent &) = default; //! @brief Default destructor. diff --git a/sources/Component/Renderer/Drawable2DComponent.hpp b/sources/Component/Renderer/Drawable2DComponent.hpp index 4bab9434..227eacd6 100644 --- a/sources/Component/Renderer/Drawable2DComponent.hpp +++ b/sources/Component/Renderer/Drawable2DComponent.hpp @@ -6,7 +6,7 @@ #include #include "Component/Component.hpp" -#include "Drawables/ADrawable3D.hpp" +#include "Drawables/ADrawable2D.hpp" #include "Model/Model.hpp" namespace BBM diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp new file mode 100644 index 00000000..3c0b2f7f --- /dev/null +++ b/sources/Map/Map.cpp @@ -0,0 +1,238 @@ +// +// Created by Tom Augier on 5/26/21. +// Edited by Benjamin Henry on 5/26/21. +// + +#include "Map.hpp" + +namespace RAY3D = RAY::Drawables::Drawables3D; + +namespace BBM +{ + void MapGenerator::generateUnbreakableBlock(int width, int height, std::shared_ptr scene) + { + std::string unbreakableObj = "assets/wall/unbreakable_wall.obj"; + std::string unbreakablePnj = "assets/wall/unbreakable_wall.png"; + + for (int i = 0; i < width + 1; i++) { + for (int j = 0; j < height + 1; j++) { + if (!(i % 2) && !(j % 2)) { + scene->addEntity("Unbreakable Wall") + .addComponent(Vector3f(i, 0, j)) + //.addComponent(1) + .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj)); + } + } + } + } + + void MapGenerator::generateWall(int width, int height, std::shared_ptr scene) + { + std::string unbreakableObj = "assets/wall/unbreakable_wall.obj"; + std::string unbreakablePnj = "assets/wall/unbreakable_wall.png"; + + scene->addEntity("Bottom Wall") + .addComponent(Vector3f((width + 1) / 2, 0, -1)) + //.addComponent(1) + .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); + scene->addEntity("Upper Wall") + .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) + //.addComponent(1) + .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); + scene->addEntity("Left Wall") + .addComponent(Vector3f(width + 1, 0, (height + 1) / 2)) + //.addComponent(1) + .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3)); + scene->addEntity("Right Wall") + .addComponent(Vector3f(-1, 0, (height + 1) / 2)) + //.addComponent(1) + .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3)); + } + + void MapGenerator::generateFloor(int width, int height, std::shared_ptr scene) + { + scene->addEntity("Floor") + .addComponent(Vector3f(width / 2, -1, height / 2)) + //.addComponent(1) + .addComponent("assets/wall/floor.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/floor.png"), RAY::Vector3(width + 2, 0, height + 2)); + } + + void MapGenerator::createElement(Vector3f coords, std::shared_ptr scene, BlockType blockType) + { + std::map elements = { + {BREAKABLE, &createBreakable}, + {UNBREAKABLE, &createUnbreakable}, + {HOLE, &createHole}, + {FLOOR, &createFloor}, + /* {BUMPER, &createBumper}, + {STAIRS, &createStairs} */ + }; + + try { + auto element = elements.at(blockType); + element(coords, scene); + } catch (std::exception const &err) { + return; + } + } + + void MapGenerator::createBreakable(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Breakable Block") + .addComponent(coords) + .addComponent(1) + //.addComponent(1) + .addComponent("assets/wall/breakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/breakable_wall.png")); + } + + void MapGenerator::createFloor(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Floor") + .addComponent(Vector3f(coords)) + //.addComponent(1) + .addComponent("assets/wall/floor.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/floor.png")); + } + + void MapGenerator::createUnbreakable(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Unbreakable Block") + .addComponent(coords) + //.addComponent(1) + .addComponent("assets/wall/unbreakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/unbreakable_wall.png")); + } + + void MapGenerator::createHole(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Hole Block") + .addComponent(Vector3f(coords.x, coords.y - 1, coords.z)) + .addComponent("assets/wall/hole.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/hole.png")); + /* .addComponent([](const WAL::Entity &entity, WAL::Entity &other) { + if (other.hasComponent()) { + auto &health = other.getComponent(); + health.takeDmg(health.getHealthPoint()); + } + }); */ + } + + void MapGenerator::createBumper(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Bumper Block") + .addComponent(Vector3f(coords.x, coords.y - 1, coords.z)) + .addComponent("assets/wall/bumper_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/bumper_block.png")); + /* .addComponent([](const WAL::Entity &entity, WAL::Entity &other) { + if (other.hasComponent()) { + auto &movable = other.getComponent(); + movable.addForce(Vector3f(0, 5, 0)); + } + } */ + } + + void MapGenerator::createStairs(Vector3f coords, std::shared_ptr scene) + { + scene->addEntity("Stairs Block") + .addComponent(coords) + //.addComponent(1) + .addComponent("assets/wall/stairs_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/stairs_block.png")); + } + + bool MapGenerator::isCloseToBlockType(std::map, BlockType> map, int x, int y, int z, BlockType blockType) + { + return (map[std::make_tuple(x - 1, y, z)] == blockType || + map[std::make_tuple(x + 1, y, z)] == blockType || + map[std::make_tuple(x, y, z + 1)] == blockType || + map[std::make_tuple(x, y, z - 1)] == blockType); + } + + MapGenerator::BlockType MapGenerator::getRandomBlockType() + { + double rnd = static_cast(std::rand())/RAND_MAX; + + if (rnd > 0.95) + return HOLE; + if (rnd > 0.10) + return BREAKABLE; + return NOTHING; + } + + MapGenerator::MapBlock MapGenerator::createHeight(MapBlock map, int width, int height) + { + double rnd = static_cast(std::rand())/RAND_MAX; + + if (rnd > 0.60) { + for (int i = 0; i < width; i++) { + map[std::make_tuple(i, 1, height)] = map[std::make_tuple(i, 0, height)]; + map[std::make_tuple(i, 0, height)] = FLOOR; + } + for (int j = 0; j < height; j++) { + map[std::make_tuple(width, 1, j)] = map[std::make_tuple(width, 0, j)]; + map[std::make_tuple(width, 0, j)] = FLOOR; + } + } + if (rnd > 0.30) { + for (int i = width - width/4; i < width + width/4 + 1; i++) { + for (int j = height - height/4; j < height + height/4 + 1; j++) { + map[std::make_tuple(i, 1, j)] = map[std::make_tuple(i, 0, j)]; + map[std::make_tuple(i, 0, j)] = FLOOR; + } + } + } + return map; + } + + MapGenerator::MapBlock MapGenerator::createSpawner(MapBlock map, int width, int height) + { + map[std::make_tuple(0, 0, 0)] = SPAWNER; + map[std::make_tuple(width, 0, 0)] = SPAWNER; + map[std::make_tuple(0, 0, height)] = SPAWNER; + map[std::make_tuple(width, 0, height)] = SPAWNER; + + return map; + } + + MapGenerator::MapBlock MapGenerator::createMap(int width, int height) + { + MapBlock map; + + width = width % 2 ? width + 1 : width; + height = height % 2 ? height + 1 : height; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) + map[std::make_tuple(i, 0, j)] = NOTHING; + } + map = createSpawner(map, width, height); + for (int i = 0; i < width + 1; i++) { + for (int j = 0; j < height + 1; j++) { + if (map[std::make_tuple(i, 0, j)] == SPAWNER) + continue; + if (isCloseToBlockType(map, i , 0, j, SPAWNER)) + map[std::make_tuple(i, 0, j)] = NOTHING; + else + map[std::make_tuple(i, 0, j)] = getRandomBlockType(); + if (map[std::make_tuple(i, 0, j)] == UNBREAKABLE && isCloseToBlockType(map, i, 0, j, UNBREAKABLE)) + map[std::make_tuple(i, 0, j)] = BREAKABLE; + } + } + for (int i = 0; i < width + 1; i++) { + for (int j = 0; j < height + 1; j++) { + if (!((i + 1) % 2) && !((j + 1) % 2)) + map[std::make_tuple(i, 0, j)] = UNBREAKABLE; + } + } + map = createHeight(map, width, height); + return (map); + } + + void MapGenerator::loadMap(int width, int height, std::map, + BlockType> map, std::shared_ptr scene) + { + generateWall(width, height, scene); + generateFloor(width, height, scene); + for (int x = 0; x < width + 1; x++) { + for (int z = 0; z < height + 1; z++) { + for (int y = 0; y < 1 + 1; y++) + createElement(Vector3f(x, y, z), scene, map[std::make_tuple(x, y, z)]); + } + } + } + +} // namespace BBM \ No newline at end of file diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp new file mode 100644 index 00000000..177d836f --- /dev/null +++ b/sources/Map/Map.hpp @@ -0,0 +1,137 @@ +// +// Created by Tom Augier on 5/26/21. +// Edited by Benjamin Henry on 5/26/21. +// + + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include "Component/Renderer/Drawable3DComponent.hpp" +#include "System/Renderer/RenderSystem.hpp" +#include "Scene/Scene.hpp" +#include "Model/Model.hpp" +#include "Component/Component.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Health/HealthComponent.hpp" +#include "Component/Movable/MovableComponent.hpp" + +namespace BBM +{ + + class MapGenerator + { + private: + //! @brief Enum of the block available. + enum BlockType { + NOTHING, + BREAKABLE, + HOLE, + FLOOR, + BUMPER, + STAIRS, + SPAWNER, + UNBREAKABLE + }; + + using MapElem = std::function scene)>; + using MapBlock = std::map, BlockType>; + + //! @brief Generate random block type + static BlockType getRandomBlockType(); + + //! @param map ASCII map + //! @param x x index on the block + //! @param z z index on the block + //! @param blockType blockType to compare with position + static bool isCloseToBlockType(std::map, BlockType> map, int x, int y, int z, BlockType blockType); + + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the unbreakable block of the map + static void generateUnbreakableBlock(int width, int height, std::shared_ptr scene); + + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the wall of the map + static void generateWall(int width, int height, std::shared_ptr scene); + + //! @param width Width of the map + //! @param height Height of the map + //! @param scene Scene where the map is instanced + //! @brief Generate the floor of the map + static void generateFloor(int width, int height, std::shared_ptr scene); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create element of the map + static void createElement(Vector3f coords, std::shared_ptr scene, BlockType blockType); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create breakable of the map + static void createBreakable(Vector3f coords, std::shared_ptr scene); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create unbreakable of the map + static void createUnbreakable(Vector3f coords, std::shared_ptr scene); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create hole of the map + static void createHole(Vector3f coords, std::shared_ptr scene); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create bumper of the map + static void createBumper(Vector3f coords, std::shared_ptr scene); + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create bumper of the map + static void createFloor(Vector3f coords, std::shared_ptr scene); + + + //! @param coords coords of the element + //! @param scene Scene where the map is instanced + //! @brief Create stair of the map + static void createStairs(Vector3f coords, std::shared_ptr scene); + + //! @param map Map to load with block declared inside + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate map of block to be loaded + static MapBlock createSpawner(MapBlock map, int width, int height); + + //! @param map Map to load with block declared inside + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate height for the map + static MapBlock createHeight(MapBlock map, int width, int height); + + + public: + + //! @param width Width of the map + //! @param height Height of the map + //! @brief Generate map of block to be loaded + static MapBlock createMap(int width, int height); + + //! @param width Width of the map + //! @param height Height of the map + //! @param map Map to load with block declared inside + //! @param scene Scene where the map is instanced + //! @brief Generate the map + static void loadMap(int width, int height, MapBlock map, std::shared_ptr scene); + + }; +} // namespace BBM \ No newline at end of file diff --git a/sources/Models/Vector2.hpp b/sources/Models/Vector2.hpp index 07904949..629a11b8 100644 --- a/sources/Models/Vector2.hpp +++ b/sources/Models/Vector2.hpp @@ -129,6 +129,11 @@ namespace BBM { double mag = this->magnitude(); + if (mag == 0) { + this->x = 0; + this->y = 0; + return *this; + } this->x /= mag; this->y /= mag; return *this; @@ -138,6 +143,8 @@ namespace BBM { T mag = this->magnitude(); + if (mag == 0) + return Vector2(); return Vector2(this->x / mag, this->y / mag); } diff --git a/sources/Models/Vector3.hpp b/sources/Models/Vector3.hpp index 5579b382..dc1752f1 100644 --- a/sources/Models/Vector3.hpp +++ b/sources/Models/Vector3.hpp @@ -136,6 +136,12 @@ namespace BBM { double mag = this->magnitude(); + if (mag == 0) { + this->x = 0; + this->y = 0; + this->z = 0; + return *this; + } this->x /= mag; this->y /= mag; this->z /= mag; @@ -146,6 +152,8 @@ namespace BBM { T mag = this->magnitude(); + if (mag == 0) + return Vector3(); return Vector3(this->x / mag, this->y / mag, this->z / mag); } @@ -158,6 +166,22 @@ namespace BBM { return RAY::Vector3(this->x, this->y, this->z); } + + static Vector3 min(Vector3 a, Vector3 b) + { + Vector3 min = { std::min(a.x, b.x), + std::min(a.y, b.y), + std::min(a.z, b.z)}; + return min; + } + + static Vector3 max(Vector3 a, Vector3 b) + { + Vector3 max = { std::max(a.x, b.x), + std::max(a.y, b.y), + std::max(a.z, b.z)}; + return max; + } }; typedef Vector3 Vector3f; diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index b39c2e5f..683e3bbb 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -9,14 +9,23 @@ #include #include #include +#include #include -#include "Component/Position/PositionComponent.hpp" +#include +#include +#include +#include +#include +#include +#include +#include #include "Models/Vector2.hpp" #include "Component/Renderer/CameraComponent.hpp" #include "Component/Renderer/Drawable2DComponent.hpp" #include "Component/Renderer/Drawable3DComponent.hpp" #include "Runner.hpp" #include "Models/GameState.hpp" +#include "Map/Map.hpp" namespace RAY2D = RAY::Drawables::Drawables2D; namespace RAY3D = RAY::Drawables::Drawables3D; @@ -33,6 +42,15 @@ namespace BBM engine.shouldClose = true; } + void addSystems(WAL::Wal &wal) + { + wal.addSystem() + .addSystem() + .addSystem() + .addSystem(wal) + .addSystem(); + } + void enableRaylib(WAL::Wal &wal) { RAY::TraceLog::setLevel(LOG_WARNING); @@ -43,25 +61,38 @@ namespace BBM std::shared_ptr loadGameScene() { auto scene = std::make_shared(); - scene->addEntity("cube") - .addComponent(10, 10, 0) - .addComponent(Vector2f(), Vector2f(10, 10), GREEN); - scene->addEntity("cube2") - .addComponent() - .addComponent(Vector2f(), Vector2f(10, 10), RED); scene->addEntity("player") .addComponent() - .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")); + .addComponent("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png")) + .addComponent() + .addComponent() + .addComponent(2) + .addComponent(); + scene->addEntity("cube") + .addComponent(-5, 0, -5) + .addComponent(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED) + .addComponent() + .addComponent() + .addComponent([](WAL::Entity &, const WAL::Entity &){}, + [](WAL::Entity &actual, const WAL::Entity &) { + try { + auto &mov = actual.getComponent(); + mov.resetVelocity(); + } catch (std::exception &e) { }; + }, 3); + scene->addEntity("camera") - .addComponent(10, 10, 15) - .addComponent(); + .addComponent(8, 20, 7) + .addComponent(Vector3f(8, 0, 8)); + std::srand(std::time(NULL)); + MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; } int run() { WAL::Wal wal; - wal.addSystem(); + addSystems(wal); enableRaylib(wal); wal.scene = loadGameScene(); diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp new file mode 100644 index 00000000..24971304 --- /dev/null +++ b/sources/System/Collision/CollisionSystem.cpp @@ -0,0 +1,52 @@ +// +// Created by Louis Auzuret on 5/20/21 +// + +#include "Component/Movable/MovableComponent.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Collision/CollisionComponent.hpp" +#include "System/Collision/CollisionSystem.hpp" + +namespace BBM +{ + CollisionSystem::CollisionSystem(WAL::Wal &wal) + : WAL::System({typeid(PositionComponent), typeid(CollisionComponent)}), _wal(wal) + { + + } + + bool CollisionSystem::collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB) + { + bool overlapX = (minA.x <= maxB.x && maxA.x >= minB.x) || (minB.x <= maxA.x && maxB.x >= minA.x); + bool overlapY = (minA.y <= maxB.y && maxA.y >= minB.y) || (minB.y <= maxA.y && maxB.y >= minA.y); + bool overlapZ = (minA.z <= maxB.z && maxA.z >= minB.z) || (minB.z <= maxA.z && maxB.z >= minA.z); + + return (overlapX && overlapY && overlapZ); + } + + void CollisionSystem::onFixedUpdate(WAL::Entity &entity) + { + auto &posA = entity.getComponent(); + auto &col = entity.getComponent(); + Vector3f position = posA.position; + if (entity.hasComponent(typeid(MovableComponent))) + position += entity.getComponent().getVelocity(); + Vector3f minA = Vector3f::min(position, position + col.bound); + Vector3f maxA = Vector3f::max(position, position + col.bound); + for (auto &other : _wal.scene->getEntities()) { + if (&other == &entity) + continue; + if (!other.hasComponent() || + !other.hasComponent()) + continue; + auto colB = other.getComponent(); + auto posB = other.getComponent().position; + Vector3f minB = Vector3f::min(posB, posB + colB.bound); + Vector3f maxB = Vector3f::max(posB, posB + colB.bound); + if (collide(minA, maxA, minB, maxB)) { + col.onCollide(entity, other); + colB.onCollided(entity, other); + } + } + } +} \ No newline at end of file diff --git a/sources/System/Collision/CollisionSystem.hpp b/sources/System/Collision/CollisionSystem.hpp new file mode 100644 index 00000000..b3d78b55 --- /dev/null +++ b/sources/System/Collision/CollisionSystem.hpp @@ -0,0 +1,37 @@ + +// +// Created by Louis Auzuret on 5/20/21 +// + +#pragma once + +#include +#include "Wal.hpp" +#include "System/System.hpp" +#include "Models/Vector3.hpp" + +namespace BBM +{ + //! @brief A system to handle collisions. + class CollisionSystem : public WAL::System + { + private: + //! @brief reference to the ECS engine to get other entities + WAL::Wal &_wal; + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + CollisionSystem(WAL::Wal &wal); + //! @brief A Collision system is copy constructable + CollisionSystem(const CollisionSystem &) = default; + //! @brief A default destructor + ~CollisionSystem() override = default; + //! @brief A Collision system is assignable. + CollisionSystem &operator=(const CollisionSystem &) = default; + + //! @brief check AABB collision + static bool collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB); + }; +} \ No newline at end of file diff --git a/sources/System/Controllable/ControllableSystem.cpp b/sources/System/Controllable/ControllableSystem.cpp new file mode 100644 index 00000000..0a9c789c --- /dev/null +++ b/sources/System/Controllable/ControllableSystem.cpp @@ -0,0 +1,30 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#include "ControllableSystem.hpp" +#include "Component/Movable/MovableComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + float ControllableSystem::speed = .25f; + + ControllableSystem::ControllableSystem() + : WAL::System({ + typeid(ControllableComponent), + typeid(MovableComponent) + }) + {} + + void ControllableSystem::onFixedUpdate(WAL::Entity &entity) + { + auto &controllable = entity.getComponent(); + auto &movable = entity.getComponent(); + Vector2f move = controllable.move.normalized() * ControllableSystem::speed; + + movable.addForce(Vector3f(move.x, controllable.jump, move.y)); + } +} \ No newline at end of file diff --git a/sources/System/Controllable/ControllableSystem.hpp b/sources/System/Controllable/ControllableSystem.hpp new file mode 100644 index 00000000..fac4db08 --- /dev/null +++ b/sources/System/Controllable/ControllableSystem.hpp @@ -0,0 +1,31 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include "System/System.hpp" + +namespace BBM +{ + //! @brief A system to handle Controllable entities. + class ControllableSystem : public WAL::System + { + public: + //! @brief The speed applied to every controllable entities. + static float speed; + + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + ControllableSystem(); + //! @brief A Controllable system is copy constructable + ControllableSystem(const ControllableSystem &) = default; + //! @brief A default destructor + ~ControllableSystem() override = default; + //! @brief A Controllable system is assignable. + ControllableSystem &operator=(const ControllableSystem &) = default; + }; +} diff --git a/sources/System/Gamepad/GamepadSystem.cpp b/sources/System/Gamepad/GamepadSystem.cpp new file mode 100644 index 00000000..5df6bd96 --- /dev/null +++ b/sources/System/Gamepad/GamepadSystem.cpp @@ -0,0 +1,43 @@ +// +// Created by Arthur Jamet on 2021-05-31. +// + +#include "GamepadSystem.hpp" +#include "Component/Gamepad/GamepadComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Entity/Entity.hpp" +#include "Controllers/Gamepad.hpp" + +using Button = RAY::Controller::GamePad::Button; +using Gamepad = RAY::Controller::GamePad; + +namespace BBM +{ + GamepadSystem::GamepadSystem() + : WAL::System({ + typeid(GamepadComponent), + typeid(ControllableComponent) + }) + {} + + void GamepadSystem::onFixedUpdate(WAL::Entity &entity) + { + const auto &gamepadComponent = entity.getComponent(); + auto &controllable = entity.getComponent(); + Gamepad gamepad(gamepadComponent.getID()); + + const std::map keyPressedMap = { + {gamepadComponent.keyJump, controllable.jump}, + {gamepadComponent.keyBomb, controllable.bomb}, + {gamepadComponent.keyPause, controllable.pause} + }; + + for (auto key : keyPressedMap) + key.second = gamepad.isPressed(key.first); + controllable.move = Vector2f(); + controllable.move.x += gamepad.isPressed(gamepadComponent.keyRight); + controllable.move.x -= gamepad.isPressed(gamepadComponent.keyLeft); + controllable.move.y += gamepad.isPressed(gamepadComponent.keyUp); + controllable.move.y -= gamepad.isPressed(gamepadComponent.keyDown); + } +} \ No newline at end of file diff --git a/sources/System/Gamepad/GamepadSystem.hpp b/sources/System/Gamepad/GamepadSystem.hpp new file mode 100644 index 00000000..9c8c705f --- /dev/null +++ b/sources/System/Gamepad/GamepadSystem.hpp @@ -0,0 +1,28 @@ +// +// Created by Arthur Jamet on 2021-05-31. +// + +#pragma once + +#include "System/System.hpp" +#include + +namespace BBM +{ + //! @brief A system to handle Gamepad entities. + class GamepadSystem : public WAL::System + { + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + GamepadSystem(); + //! @brief A Gamepad system is copy constructable + GamepadSystem(const GamepadSystem &) = default; + //! @brief A default destructor + ~GamepadSystem() override = default; + //! @brief A Gamepad system is assignable. + GamepadSystem &operator=(const GamepadSystem &) = default; + }; +} diff --git a/sources/System/GridCentered/GridCenteredSystem.cpp b/sources/System/GridCentered/GridCenteredSystem.cpp new file mode 100644 index 00000000..5dcca1a9 --- /dev/null +++ b/sources/System/GridCentered/GridCenteredSystem.cpp @@ -0,0 +1,25 @@ +// +// Created by Zoe Roux on 5/24/21. +// + +#include "Component/Movable/MovableComponent.hpp" +#include "Component/GridCentered/GridCenteredComponent.hpp" +#include "GridCenteredSystem.hpp" + +namespace BBM +{ + GridCenteredSystem::GridCenteredSystem() + : WAL::System({ + typeid(GridCenteredComponent), + typeid(MovableComponent), +// typeid(PositionComponent) + }) + {} + + void GridCenteredSystem::onFixedUpdate(WAL::Entity &entity) + { + auto &grid = entity.getComponent(); + auto &movement = entity.getComponent(); +// movement.addForce(grid.force * ) + } +} \ No newline at end of file diff --git a/sources/System/GridCentered/GridCenteredSystem.hpp b/sources/System/GridCentered/GridCenteredSystem.hpp new file mode 100644 index 00000000..e84e65fb --- /dev/null +++ b/sources/System/GridCentered/GridCenteredSystem.hpp @@ -0,0 +1,26 @@ +// +// Created by Zoe Roux on 5/24/21. +// + +#pragma once + +#include + +namespace BBM +{ + //! @brief The system handling GridCenteredComponent + class GridCenteredSystem : public WAL::System + { + public: + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + GridCenteredSystem(); + //! @brief A GridCenteredSystem is copyable. + GridCenteredSystem(const GridCenteredSystem &) = default; + //! @brief A default destructor + ~GridCenteredSystem() override = default; + //! @brief A GridCenteredSystem is assignable + GridCenteredSystem &operator=(const GridCenteredSystem &) = default; + }; +} diff --git a/sources/System/Health/HealthSystem.cpp b/sources/System/Health/HealthSystem.cpp new file mode 100644 index 00000000..90bbfbb9 --- /dev/null +++ b/sources/System/Health/HealthSystem.cpp @@ -0,0 +1,26 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#include "HealthSystem.hpp" +#include "Component/Health/HealthComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Entity/Entity.hpp" + +namespace BBM +{ + HealthSystem::HealthSystem() + : WAL::System({ + typeid(HealthComponent) + }) + {} + + void HealthSystem::onFixedUpdate(WAL::Entity &entity) + { + auto &health = entity.getComponent(); + + if (health.getHealthPoint() == 0) + health.onDeath(entity); + } +} \ No newline at end of file diff --git a/sources/System/Health/HealthSystem.hpp b/sources/System/Health/HealthSystem.hpp new file mode 100644 index 00000000..15ca2062 --- /dev/null +++ b/sources/System/Health/HealthSystem.hpp @@ -0,0 +1,28 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include "System/System.hpp" + +namespace BBM +{ + //! @brief A system to handle Health entities. + class HealthSystem : public WAL::System + { + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + HealthSystem(); + //! @brief A Health system is copy constructable + HealthSystem(const HealthSystem &) = default; + //! @brief A default destructor + ~HealthSystem() override = default; + //! @brief A Health system is assignable. + HealthSystem &operator=(const HealthSystem &) = default; + }; +} diff --git a/sources/System/Keyboard/KeyboardSystem.cpp b/sources/System/Keyboard/KeyboardSystem.cpp new file mode 100644 index 00000000..13ad9804 --- /dev/null +++ b/sources/System/Keyboard/KeyboardSystem.cpp @@ -0,0 +1,47 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#include +#include "KeyboardSystem.hpp" +#include "Component/Keyboard/KeyboardComponent.hpp" +#include "Component/Controllable/ControllableComponent.hpp" +#include "Entity/Entity.hpp" +#include "Controllers/Keyboard.hpp" + +using Keyboard = RAY::Controller::Keyboard; + +namespace BBM +{ + KeyboardSystem::KeyboardSystem() + : WAL::System({ + typeid(KeyboardComponent), + typeid(ControllableComponent) + }) + {} + + void KeyboardSystem::onFixedUpdate(WAL::Entity &entity) + { + const auto &keyboard = entity.getComponent(); + auto &controllable = entity.getComponent(); + + const std::map keyPressedMap = { + {keyboard.keyJump, controllable.jump}, + {keyboard.keyBomb, controllable.bomb}, + {keyboard.keyPause, controllable.pause} + }; + + for (auto key : keyPressedMap) + key.second = Keyboard::isDown(key.first); + controllable.move = Vector2f(); + if (Keyboard::isDown(keyboard.keyRight)) + controllable.move.x += 1; + if (Keyboard::isDown(keyboard.keyLeft)) + controllable.move.x -= 1; + if (Keyboard::isDown(keyboard.keyUp)) + controllable.move.y += 1; + if (Keyboard::isDown(keyboard.keyDown)) + controllable.move.y -= 1; + } +} \ No newline at end of file diff --git a/sources/System/Keyboard/KeyboardSystem.hpp b/sources/System/Keyboard/KeyboardSystem.hpp new file mode 100644 index 00000000..f17c5f15 --- /dev/null +++ b/sources/System/Keyboard/KeyboardSystem.hpp @@ -0,0 +1,29 @@ +// +// Created by Tom Augier on 2021-05-20. +// Edited by Benjamin Henry on 2021-05-20. +// + +#pragma once + +#include "System/System.hpp" +#include + +namespace BBM +{ + //! @brief A system to handle keyboard entities. + class KeyboardSystem : public WAL::System + { + public: + //! @inherit + void onFixedUpdate(WAL::Entity &entity) override; + + //! @brief A default constructor + KeyboardSystem(); + //! @brief A keyboard system is copy constructable + KeyboardSystem(const KeyboardSystem &) = default; + //! @brief A default destructor + ~KeyboardSystem() override = default; + //! @brief A keyboard system is assignable. + KeyboardSystem &operator=(const KeyboardSystem &) = default; + }; +} diff --git a/sources/System/Movable/MovableSystem.cpp b/sources/System/Movable/MovableSystem.cpp index 5b57ebba..1c439345 100644 --- a/sources/System/Movable/MovableSystem.cpp +++ b/sources/System/Movable/MovableSystem.cpp @@ -5,7 +5,6 @@ #include "Component/Position/PositionComponent.hpp" #include "MovableSystem.hpp" #include "Component/Movable/MovableComponent.hpp" -#include "Wal.hpp" namespace BBM { @@ -21,8 +20,8 @@ namespace BBM auto &movable = entity.getComponent(); auto &position = entity.getComponent(); - position.position += movable._velocity * WAL::Wal::timestep.count(); - movable._velocity = movable._acceleration * WAL::Wal::timestep.count(); + position.position += movable._velocity; + movable._velocity = movable._acceleration; movable._acceleration = Vector3f(); } } // namespace WAL \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index bd13441a..cfb244b4 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -23,5 +23,6 @@ int main(int argc, char **argv) usage(argv[0]); return 1; } + //return demo(); return BBM::run(); } diff --git a/tests/CollisionTest.cpp b/tests/CollisionTest.cpp new file mode 100644 index 00000000..69c75207 --- /dev/null +++ b/tests/CollisionTest.cpp @@ -0,0 +1,97 @@ +// +// Created by Louis Auzuret on 5/31/21. +// + +#include +#include "Entity/Entity.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "Component/Movable/MovableComponent.hpp" +#include "System/Movable/MovableSystem.hpp" +#include "System/Collision/CollisionSystem.hpp" +#include "Wal.hpp" + +#define private public +#include "Component/Collision/CollisionComponent.hpp" + +using namespace WAL; +using namespace BBM; + + +TEST_CASE("Collision test", "[Component][System]") +{ + Wal wal; + CollisionSystem collision(wal); + wal.scene = std::shared_ptr(new Scene); + wal.scene->addEntity("player") + .addComponent() + .addComponent([](Entity &actual, const Entity &) { + try { + auto &pos = actual.getComponent(); + pos.position.x = 1; + pos.position.y = 1; + pos.position.z = 1; + } catch (std::exception &e) {}; + }, [](Entity &, const Entity &){}, 5.0); + Entity &entity = wal.scene->getEntities()[0]; + REQUIRE(entity.getComponent().position == Vector3f()); + + entity.getComponent().bound.x = 5; + entity.getComponent().bound.y = 5; + entity.getComponent().bound.z = 5; + + collision.onUpdate(entity, std::chrono::nanoseconds(1)); + collision.onFixedUpdate(entity); + REQUIRE(entity.getComponent().position.x == 0.0); + REQUIRE(entity.getComponent().position.y == 0.0); + REQUIRE(entity.getComponent().position.z == 0.0); + + wal.scene->addEntity("block") + .addComponent(2,2,2) + .addComponent(1); + Entity &player = wal.scene->getEntities()[0]; + collision.onUpdate(entity, std::chrono::nanoseconds(1)); + REQUIRE(player.hasComponent(typeid(PositionComponent))); + collision.onFixedUpdate(player); + REQUIRE(wal.scene->getEntities().size() == 2); + REQUIRE(player.hasComponent(typeid(PositionComponent))); + REQUIRE(player.getComponent().position.x == 1.0); + REQUIRE(player.getComponent().position.y == 1); + REQUIRE(player.getComponent().position.z == 1); +} + + +TEST_CASE("Collsion test with movable", "[Component][System]") +{ + Wal wal; + CollisionSystem collision(wal); + MovableSystem movable; + wal.scene = std::shared_ptr(new Scene); + wal.scene->addEntity("player") + .addComponent() + .addComponent([](Entity &actual, const Entity &) {}, [](Entity &actual, const Entity &) {}, 5.0) + .addComponent(); + + wal.scene->addEntity("block") + .addComponent(0, 0, 0) + .addComponent([](Entity &actual, const Entity &){}, [](Entity &actual, const Entity &) { + try { + auto &mov = actual.getComponent(); + mov.resetVelocity(); + } catch (std::exception &e) {}; + }, 1); + Entity &entity = wal.scene->getEntities()[0]; + REQUIRE(entity.getComponent().position == Vector3f()); + + entity.getComponent().bound.x = 5; + entity.getComponent().bound.y = 5; + entity.getComponent().bound.z = 5; + + entity.getComponent().addForce({1, 1, 1}); + collision.onUpdate(entity, std::chrono::nanoseconds(1)); + collision.onFixedUpdate(entity); + movable.onUpdate(entity, std::chrono::nanoseconds(1)); + movable.onFixedUpdate(entity); + REQUIRE(entity.getComponent().position.x == 0.0); + REQUIRE(entity.getComponent().position.y == 0.0); + REQUIRE(entity.getComponent().position.z == 0.0); +} \ No newline at end of file diff --git a/tests/MoveTests.cpp b/tests/MoveTests.cpp new file mode 100644 index 00000000..cd37d22a --- /dev/null +++ b/tests/MoveTests.cpp @@ -0,0 +1,51 @@ +// +// Created by Zoe Roux on 5/31/21. +// + +#include "Entity/Entity.hpp" +#include "Component/Position/PositionComponent.hpp" +#include "System/Movable/MovableSystem.hpp" +#include "System/Controllable/ControllableSystem.hpp" +#include +#include +#include + +#define private public +#include + +using namespace WAL; +using namespace BBM; + + +TEST_CASE("Move test", "[Component][System]") +{ + Scene scene; + scene.addEntity("player") + .addComponent() + .addComponent() + .addComponent(); + Entity &entity = scene.getEntities()[0]; + + REQUIRE(entity.getComponent().position == Vector3f()); + + entity.getComponent().move = Vector2f(1, 1); + + ControllableSystem controllable; + controllable.onUpdate(entity, std::chrono::nanoseconds(1)); + controllable.onFixedUpdate(entity); + REQUIRE(entity.getComponent()._acceleration.x > 0); + REQUIRE(entity.getComponent()._acceleration.z > 0); + + MovableSystem movable; + movable.onUpdate(entity, std::chrono::nanoseconds(1)); + movable.onFixedUpdate(entity); + REQUIRE(entity.getComponent()._velocity.x > 0); + REQUIRE(entity.getComponent()._velocity.z > 0); + REQUIRE(entity.getComponent()._acceleration.x == 0); + REQUIRE(entity.getComponent()._acceleration.z == 0); + movable.onUpdate(entity, std::chrono::nanoseconds(1)); + movable.onFixedUpdate(entity); + REQUIRE(entity.getComponent().position.x > 0); + REQUIRE(entity.getComponent().position.z > 0); + +} \ No newline at end of file diff --git a/wasm-server.py b/wasm-server.py index d9dde32c..77aad1db 100644 --- a/wasm-server.py +++ b/wasm-server.py @@ -18,7 +18,7 @@ if sys.version_info < (3, 7, 5): if __name__ == '__main__': - PORT = 8081 + PORT = 8080 with socketserver.TCPServer(("", PORT), WasmHandler) as httpd: print("Listening on port {}. Press Ctrl+C to stop.".format(PORT)) httpd.serve_forever()