Merge pull request #101 from AnonymusRaccoon/wasm

Web Assembly Support
This commit is contained in:
Arthi-chaud
2021-06-03 15:45:57 +02:00
committed by GitHub
29 changed files with 404 additions and 302 deletions
+22
View File
@@ -0,0 +1,22 @@
name: Web Build (Emscripten)
on:
push:
branches:
wasm
jobs:
Push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
submodules: true
- name: Exec
shell: bash
run: ./build_web.sh
- name: Check files creation
run: |
test -f build_web/bomberman.html
test -f build_web/bomberman.js
test -f build_web/bomberman.wasm
test -f build_web/bomberman.data
+4 -1
View File
@@ -3,4 +3,7 @@ cmake-build-debug
./bomberman
.vscode
build/*
docs/*
docs/*
emsdk/
build_web/*
wasm-python.py
+10 -8
View File
@@ -10,6 +10,13 @@ include_directories(bomberman sources)
add_subdirectory(${PROJECT_SOURCE_DIR}/lib/wal)
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")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_DISABLE_EXCEPTION_CATCHING --shell-file ../sources/wasm/frontend.html --preload-file ../assets")
set(CMAKE_EXECUTABLE_SUFFIX ".html")
endif ()
set(SOURCES
sources/Models/GameState.hpp
sources/Runner/Runner.cpp
@@ -46,16 +53,12 @@ set(SOURCES
sources/System/GridCentered/GridCenteredSystem.cpp
sources/System/GridCentered/GridCenteredSystem.hpp
sources/Models/Vector2.hpp
sources/Component/Renderer/Drawable3DComponent.hpp
sources/Component/Renderer/Drawable2DComponent.hpp
sources/System/Renderer/Renderer3DSystem.hpp
sources/System/Renderer/Renderer2DSystem.hpp
sources/System/Renderer/RenderScreenSystem.hpp
sources/System/Renderer/RenderScreenSystem.cpp
sources/Component/Renderer/Drawable3DComponent.hpp
sources/System/Renderer/RenderSystem.hpp
sources/System/Renderer/RenderSystem.cpp
sources/Component/Renderer/CameraComponent.cpp
sources/Component/Renderer/CameraComponent.hpp
sources/System/Renderer/Render2DScreenSystem.cpp
sources/System/Renderer/Render2DScreenSystem.hpp
sources/Component/Animation/AnimationsComponent.cpp
sources/Component/Animation/AnimationsComponent.hpp
sources/System/Animation/AnimationsSystem.cpp
@@ -65,7 +68,6 @@ set(SOURCES
sources/System/Collision/CollisionSystem.hpp
sources/System/Collision/CollisionSystem.cpp
)
add_executable(bomberman
sources/main.cpp
${SOURCES}
Executable
+11
View File
@@ -0,0 +1,11 @@
#! /bin/bash
EMSDK_PATH=./emsdk
if [[ ! -d ./emsdk ]]; then
git clone https://github.com/emscripten-core/emsdk.git
fi
./emsdk/emsdk install latest
./emsdk/emsdk activate latest
source ./emsdk/emsdk_env.sh
mkdir -p build_web
emcmake cmake -S . -B build_web -DPLATFORM=Web &&
cmake --build build_web
+1
View File
@@ -9,6 +9,7 @@
#define RAYERROR_HPP_
#include <stdexcept>
#include <string>
namespace RAY::Exception {
//! @brief base exception class for RAY lib
+11 -2
View File
@@ -108,10 +108,14 @@ void RAY::Window::clear(RAY::Color color)
ClearBackground(color);
}
void RAY::Window::draw()
void RAY::Window::beginDrawing()
{
BeginDrawing();
}
void RAY::Window::endDrawing()
{
EndDrawing();
BeginDrawing();
}
void RAY::Window::useCamera(RAY::Camera::Camera2D &camera)
@@ -168,3 +172,8 @@ void RAY::Window::setIcon(RAY::Image &img)
{
SetWindowIcon(img);
}
bool RAY::Window::isReady() const
{
return IsWindowReady();
}
+7 -2
View File
@@ -102,8 +102,10 @@ namespace RAY {
NONE,
};
//! @brief Draw the content of the buffer on the screen.
void draw();
//! @brief Setup canvas (framebuffer) to start drawing
void beginDrawing();
//! @brief End canvas drawing and swap buffers (double buffering)
void endDrawing();
//! @brief Initialize 2D mode with custom camera (2D)
void useCamera(Camera::Camera2D &camera);
@@ -131,6 +133,9 @@ namespace RAY {
//! @brief Draw a 3d mesh with material and transform
void draw(const Mesh &mesh, const Material &material, const Matrix &transform);
//! @return true if the window's context has been correctly initialized
bool isReady() const;
private:
//! @brief Creates window, and opens it if openNow is set to true
+3
View File
@@ -14,6 +14,9 @@ if (NOT raylib_FOUND)
SET(FETCHCONTENT_QUIET NO)
FetchContent_Populate(raylib)
SET(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
if (EMSCRIPTEN)
SET(PLATFORM Web)
endif()
ADD_SUBDIRECTORY(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR})
SET(raylib_FOUND TRUE)
endif()
+1 -1
View File
@@ -17,6 +17,6 @@ add_library(wal
sources/Component/Component.cpp
sources/System/System.cpp
sources/Models/Callback.hpp
)
sources/Models/TypeHolder.hpp)
target_include_directories(wal PUBLIC sources)
+13
View File
@@ -10,6 +10,7 @@
#include <memory>
#include "Component/Component.hpp"
#include "Exception/WalError.hpp"
#include "Models/TypeHolder.hpp"
namespace WAL
{
@@ -83,6 +84,18 @@ namespace WAL
return *this;
}
//! @brief Add a component to this entity. The component is constructed in place.
//! @throw DuplicateError is thrown if a component with the same type already exist.
//! @return This entity is returned
template<typename T, typename TNested, typename ...Types>
Entity &addComponent(Types &&...params)
{
if (this->hasComponent<T>())
throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists.");
this->_components.push_back(std::make_unique<T>(*this, TypeHolder<TNested>(), std::forward<Types>(params)...));
return *this;
}
//! @brief Copy a component to this entity.
//! @return This entity is returned.
Entity &addComponent(const Component &component);
+13
View File
@@ -0,0 +1,13 @@
//
// Created by Zoe Roux on 2021-06-02.
//
#pragma once
namespace WAL
{
//! @brief A class only used to specify template arguments.
template<typename T>
class TypeHolder {};
}
+5 -3
View File
@@ -41,8 +41,10 @@ namespace WAL
{
// TODO use an hashmap to cache results.
const auto &dependency = system.getDependencies();
return std::ranges::all_of(dependency.begin(), dependency.end(), [&entity](const auto &dependency) {
return entity.hasComponent(dependency);
});
for (const auto &dependency : system.getDependencies()) {
if (!entity.hasComponent(dependency))
return false;
}
return true;
}
} // namespace WAL
+34
View File
@@ -15,6 +15,10 @@
#include "System/System.hpp"
#include "Models/Callback.hpp"
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
namespace WAL
{
//! @brief The main WAL class, it is used to setup and run the ECS.
@@ -109,7 +113,13 @@ namespace WAL
void run(const std::function<void (Wal &, T &)> &callback, T state = T())
{
Callback<Wal &, T &> update(callback);
#if defined(PLATFORM_WEB)
std::tuple iterationParams(this, &update, &state);
return emscripten_set_main_loop_arg((em_arg_callback_func)runIteration<T>, (void *)&iterationParams, 0, 1);
#else
return this->run(update, state);
#endif
}
//! @brief Start the game loop
@@ -137,6 +147,30 @@ namespace WAL
}
}
#if defined(PLATFORM_WEB)
template<typename T>
static void runIteration(void *param)
{
static auto iterationParams = reinterpret_cast<std::tuple<Wal *, Callback<Wal &, T &> *, T *> *>(param);
static const Callback<Wal &, T &> callback = *((Callback<Wal &, T &> *)std::get<1>(*iterationParams));
static T *state = (T *)std::get<2>(*iterationParams);
static Wal *wal = (Wal *)std::get<0>(*iterationParams);
static auto lastTick = std::chrono::steady_clock::now();
static std::chrono::nanoseconds fBehind(0);
auto now = std::chrono::steady_clock::now();
std::chrono::nanoseconds dtime = now - lastTick;
fBehind += dtime;
lastTick = now;
while (fBehind > Wal::timestep) {
fBehind -= Wal::timestep;
wal->_fixedUpdate();
}
wal->_update(dtime);
callback(*wal, *state);
}
#endif
//! @brief A default constructor
Wal() = default;
//! @brief A WAL can't be copy constructed
@@ -4,36 +4,37 @@
#pragma once
#include <Models/TypeHolder.hpp>
#include "Component/Component.hpp"
#include "Drawables/ADrawable2D.hpp"
#include "Model/Model.hpp"
namespace BBM
{
template <class T>
class Drawable2DComponent : public WAL::Component
{
public:
//! @brief The type of the component
T member;
std::shared_ptr<RAY::Drawables::ADrawable2D> drawable;
//! ctor
Drawable2DComponent(WAL::Entity &entity, T member)
//! @brief ctor
Drawable2DComponent(WAL::Entity &entity, std::shared_ptr<RAY::Drawables::ADrawable2D> drawable)
: WAL::Component(entity),
member(std::move(member))
drawable(std::move(drawable))
{}
//! ctor
template<typename ...Params>
explicit Drawable2DComponent(WAL::Entity &entity, Params &&...params)
template<typename T, typename ...Params>
explicit Drawable2DComponent(WAL::Entity &entity, WAL::TypeHolder<T>, Params &&...params)
: WAL::Component(entity),
member(std::forward<Params>(params)...)
drawable(new T(std::forward<Params>(params)...))
{}
//! @brief Clone a component for another or the same entity.
//! @param entity The entity that owns the ne component.
WAL::Component *clone(WAL::Entity &entity) const override
{
return new Drawable2DComponent(entity, this->member);
return new Drawable2DComponent(entity, this->drawable);
}
//! @brief Default copy ctor
@@ -42,7 +43,5 @@ namespace BBM
~Drawable2DComponent() override = default;
//! @brief Default assignment operator
Drawable2DComponent &operator=(const Drawable2DComponent &) = delete;
};
}
@@ -4,37 +4,37 @@
#pragma once
#include <Models/TypeHolder.hpp>
#include "Component/Component.hpp"
#include "Drawables/ADrawable3D.hpp"
#include "Model/Model.hpp"
namespace BBM
{
template <class T>
class Drawable3DComponent : public WAL::Component
{
public:
//! @brief The type of the component
T member;
std::shared_ptr<RAY::Drawables::ADrawable3D> drawable;
//! @brief ctor
Drawable3DComponent(WAL::Entity &entity, T member)
Drawable3DComponent(WAL::Entity &entity, std::shared_ptr<RAY::Drawables::ADrawable3D> drawable)
: WAL::Component(entity),
member(std::move(member))
drawable(std::move(drawable))
{}
//! ctor
template<typename ...Params>
explicit Drawable3DComponent(WAL::Entity &entity, Params &&...params)
template<typename T, typename ...Params>
explicit Drawable3DComponent(WAL::Entity &entity, WAL::TypeHolder<T>, Params &&...params)
: WAL::Component(entity),
member(std::forward<Params>(params)...)
drawable(new T(std::forward<Params>(params)...))
{}
//! @brief Clone a component for another or the same entity.
//! @param entity The entity that owns the ne component.
WAL::Component *clone(WAL::Entity &entity) const override
{
return new Drawable3DComponent(entity, this->member);
return new Drawable3DComponent(entity, this->drawable);
}
//! @brief Default copy ctor
+12 -12
View File
@@ -20,7 +20,7 @@ namespace BBM
scene->addEntity("Unbreakable Wall")
.addComponent<PositionComponent>(Vector3f(i, 0, j))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj));
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj));
}
}
}
@@ -34,19 +34,19 @@ namespace BBM
scene->addEntity("Bottom Wall")
.addComponent<PositionComponent>(Vector3f((width + 1) / 2, 0, -1))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1));
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1));
scene->addEntity("Upper Wall")
.addComponent<PositionComponent>(Vector3f((width + 1) / 2, 0, height + 1))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1));
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1));
scene->addEntity("Left Wall")
.addComponent<PositionComponent>(Vector3f(width + 1, 0, (height + 1) / 2))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3));
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3));
scene->addEntity("Right Wall")
.addComponent<PositionComponent>(Vector3f(-1, 0, (height + 1) / 2))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3));
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 3));
}
void MapGenerator::generateFloor(int width, int height, std::shared_ptr<WAL::Scene> scene)
@@ -54,7 +54,7 @@ namespace BBM
scene->addEntity("Floor")
.addComponent<PositionComponent>(Vector3f(width / 2, -1, height / 2))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/floor.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/floor.png"), RAY::Vector3(width + 2, 0, height + 2));
.addComponent<Drawable3DComponent, RAY3D::Model>("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<WAL::Scene> scene, BlockType blockType)
@@ -82,7 +82,7 @@ namespace BBM
.addComponent<PositionComponent>(coords)
.addComponent<HealthComponent>(1)
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/breakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/breakable_wall.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/breakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/breakable_wall.png"));
}
void MapGenerator::createFloor(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
@@ -90,7 +90,7 @@ namespace BBM
scene->addEntity("Floor")
.addComponent<PositionComponent>(Vector3f(coords))
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/floor.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/floor.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/floor.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/floor.png"));
}
void MapGenerator::createUnbreakable(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
@@ -98,14 +98,14 @@ namespace BBM
scene->addEntity("Unbreakable Block")
.addComponent<PositionComponent>(coords)
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/unbreakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/unbreakable_wall.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/unbreakable_wall.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/unbreakable_wall.png"));
}
void MapGenerator::createHole(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
scene->addEntity("Hole Block")
.addComponent<PositionComponent>(Vector3f(coords.x, coords.y - 1, coords.z))
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/hole.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/hole.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/hole.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/hole.png"));
/* .addComponent<CollisionComponent>([](const WAL::Entity &entity, WAL::Entity &other) {
if (other.hasComponent<HealthComponent>()) {
auto &health = other.getComponent<HealthComponent>();
@@ -118,7 +118,7 @@ namespace BBM
{
scene->addEntity("Bumper Block")
.addComponent<PositionComponent>(Vector3f(coords.x, coords.y - 1, coords.z))
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/bumper_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/bumper_block.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/bumper_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/bumper_block.png"));
/* .addComponent<CollisionComponent>([](const WAL::Entity &entity, WAL::Entity &other) {
if (other.hasComponent<MovableComponent>()) {
auto &movable = other.getComponent<MovableComponent>();
@@ -132,7 +132,7 @@ namespace BBM
scene->addEntity("Stairs Block")
.addComponent<PositionComponent>(coords)
//.addComponent<CollisionComponent>(1)
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/wall/stairs_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/stairs_block.png"));
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/wall/stairs_block.obj", std::make_pair(MAP_DIFFUSE, "assets/wall/stairs_block.png"));
}
bool MapGenerator::isCloseToBlockType(std::map<std::tuple<int, int, int>, BlockType> map, int x, int y, int z, BlockType blockType)
+1 -1
View File
@@ -14,7 +14,7 @@
#include <tuple>
#include <algorithm>
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "System/Renderer/Renderer3DSystem.hpp"
#include "System/Renderer/RenderSystem.hpp"
#include "Scene/Scene.hpp"
#include "Model/Model.hpp"
#include "Component/Component.hpp"
+8 -15
View File
@@ -4,15 +4,13 @@
#include <Wal.hpp>
#include <iostream>
#include <System/Movable/MovableSystem.hpp>
#include <System/Renderer/RenderScreenSystem.hpp>
#include <System/Renderer/Render2DScreenSystem.hpp>
#include <System/Renderer/Renderer2DSystem.hpp>
#include "System/Movable/MovableSystem.hpp"
#include "System/Renderer/RenderSystem.hpp"
#include <Model/Model.hpp>
#include <Drawables/3D/Cube.hpp>
#include <Drawables/2D/Rectangle.hpp>
#include <Drawables/3D/Cube.hpp>
#include <TraceLog.hpp>
#include <System/Renderer/Renderer3DSystem.hpp>
#include <System/Keyboard/KeyboardSystem.hpp>
#include <System/Controllable/ControllableSystem.hpp>
#include <System/Collision/CollisionSystem.hpp>
@@ -23,6 +21,8 @@
#include <System/Gamepad/GamepadSystem.hpp>
#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 <Model/ModelAnimations.hpp>
@@ -58,14 +58,7 @@ namespace BBM
{
RAY::TraceLog::setLevel(LOG_WARNING);
RAY::Window &window = RAY::Window::getInstance(600, 400, "Bomberman", FLAG_WINDOW_RESIZABLE);
wal.addSystem<Renderer3DSystem<RAY3D::Model>>();
wal.addSystem<Renderer3DSystem<RAY3D::Cube>>();
wal.addSystem<AnimationsSystem>();
wal.addSystem<Render2DScreenSystem>(window)
.addSystem<Renderer2DSystem<RAY2D::Rectangle>>();
wal.addSystem<RenderScreenSystem>(window);
wal.addSystem<RenderSystem>(wal, window);
}
std::shared_ptr<WAL::Scene> loadGameScene()
@@ -73,7 +66,7 @@ namespace BBM
auto scene = std::make_shared<WAL::Scene>();
scene->addEntity("player")
.addComponent<PositionComponent>()
.addComponent<Drawable3DComponent<RAY3D::Model>>("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png"))
.addComponent<Drawable3DComponent, RAY3D::Model>("assets/player/player.iqm", std::make_pair(MAP_DIFFUSE, "assets/player/blue.png"))
.addComponent<ControllableComponent>()
.addComponent<KeyboardComponent>()
.addComponent<AnimationsComponent>(RAY::ModelAnimations("assets/player/player.iqm"), 1)
@@ -81,7 +74,7 @@ namespace BBM
.addComponent<MovableComponent>();
scene->addEntity("cube")
.addComponent<PositionComponent>(-5, 0, -5)
.addComponent<Drawable3DComponent<RAY3D::Cube>>(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED)
.addComponent<Drawable3DComponent, RAY3D::Cube>(Vector3f(-5, 0, -5), Vector3f(3, 3, 3), RED)
.addComponent<ControllableComponent>()
.addComponent<KeyboardComponent>()
.addComponent<CollisionComponent>([](WAL::Entity &, const WAL::Entity &){},
@@ -13,7 +13,7 @@ namespace BBM
AnimationsSystem::AnimationsSystem()
: WAL::System({
typeid(Drawable3DComponent<RAY::Drawables::Drawables3D::Model>),
typeid(Drawable3DComponent),
typeid(AnimationsComponent)
})
{
@@ -21,12 +21,15 @@ namespace BBM
void AnimationsSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds)
{
auto &model = entity.getComponent<Drawable3DComponent<RAY::Drawables::Drawables3D::Model>>();
auto &model = entity.getComponent<Drawable3DComponent>();
auto &anim = entity.getComponent<AnimationsComponent>();
if (anim.isDisabled())
return;
model.member.setAnimation(anim.getCurrentModelAnim());
anim.incCurrentAnimFrameCounter();
auto modelPtr = std::dynamic_pointer_cast<RAY::Drawables::Drawables3D::Model>(model.drawable);
if (modelPtr) {
modelPtr->setAnimation(anim.getCurrentModelAnim());
anim.incCurrentAnimFrameCounter();
}
}
}
@@ -8,6 +8,7 @@
#include <algorithm>
#include "Wal.hpp"
#include "System/System.hpp"
#include "Models/Vector3.hpp"
namespace BBM
{
@@ -1,19 +0,0 @@
//
// Created by Zoe Roux on 5/27/21.
//
#include "Render2DScreenSystem.hpp"
namespace BBM
{
Render2DScreenSystem::Render2DScreenSystem(RAY::Window &window)
: WAL::System({}),
_window(window),
_camera(RAY::Vector2(10, 10), RAY::Vector2(), 0)
{}
void Render2DScreenSystem::onSelfUpdate()
{
this->_window.useCamera(this->_camera);
}
}
@@ -1,33 +0,0 @@
//
// Created by Zoe Roux on 5/27/21.
//
#pragma once
#include <System/System.hpp>
#include <Window.hpp>
namespace BBM
{
class Render2DScreenSystem : public WAL::System
{
//! @brief The window to render on
RAY::Window &_window;
//! @brief The camera used to render.
RAY::Camera::Camera2D _camera;
public:
//! @brief A method called after all entities that this system manage has been updated.
//! @note render on screen here
void onSelfUpdate() override;
//! @brief ctor
explicit Render2DScreenSystem(RAY::Window &window);
//! @brief Default copy ctor
Render2DScreenSystem(const Render2DScreenSystem &) = default;
//! @brief Default dtor
~Render2DScreenSystem() override = default;
//! @brief A render screen system can't be assigned.
Render2DScreenSystem &operator=(const Render2DScreenSystem &) = delete;
};
}
@@ -1,36 +0,0 @@
//
// Created by Zoe Roux on 5/27/21.
//
#include "RenderScreenSystem.hpp"
#include "Component/Renderer/CameraComponent.hpp"
#include "Component/Position/PositionComponent.hpp"
namespace BBM
{
RenderScreenSystem::RenderScreenSystem(RAY::Window &window)
: WAL::System({
typeid(CameraComponent),
typeid(PositionComponent)
}),
_window(window),
_camera(Vector3f(), Vector3f(), Vector3f(0, 1, 0), 50, CAMERA_PERSPECTIVE)
{
this->_window.setFPS(60);
}
void RenderScreenSystem::onSelfUpdate()
{
this->_window.draw();
this->_window.clear();
this->_window.useCamera(this->_camera);
}
void RenderScreenSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime)
{
const auto &pos = entity.getComponent<PositionComponent>();
const auto &cam = entity.getComponent<CameraComponent>();
_camera.setPosition(pos.position);
_camera.setTarget(cam.target);
}
}
+66
View File
@@ -0,0 +1,66 @@
//
// Created by Zoe Roux on 5/27/21.
//
#include <Component/Renderer/Drawable3DComponent.hpp>
#include "Models/Vector2.hpp"
#include "RenderSystem.hpp"
#include "Component/Renderer/CameraComponent.hpp"
#include "Component/Position/PositionComponent.hpp"
#include "Component/Renderer/Drawable2DComponent.hpp"
#include "Drawables/ADrawable2D.hpp"
#include "Drawables/ADrawable3D.hpp"
namespace BBM
{
RenderSystem::RenderSystem(WAL::Wal &wal, RAY::Window &window)
: WAL::System({
typeid(CameraComponent),
typeid(PositionComponent)
}),
_wal(wal),
_window(window),
_camera(Vector3f(), Vector3f(), Vector3f(0, 1, 0), 50, CAMERA_PERSPECTIVE)
{}
void RenderSystem::onSelfUpdate()
{
this->_camera.update();
this->_window.beginDrawing();
this->_window.clear();
this->_window.useCamera(this->_camera);
for (auto &entity : this->_wal.scene->getEntities()) {
if (!entity.hasComponent<Drawable3DComponent>()
|| !entity.hasComponent<PositionComponent>())
continue;
auto &drawable = entity.getComponent<Drawable3DComponent>();
auto &pos = entity.getComponent<PositionComponent>();
drawable.drawable->setPosition(pos.position);
drawable.drawable->drawOn(this->_window);
}
this->_window.unuseCamera();
// TODO sort entities based on the Z axis
for (auto &entity : this->_wal.scene->getEntities()) {
if (!entity.hasComponent<Drawable2DComponent>()
|| !entity.hasComponent<PositionComponent>())
continue;
auto &drawable = entity.getComponent<Drawable2DComponent>();
auto &pos = entity.getComponent<PositionComponent>();
drawable.drawable->setPosition(Vector2f(pos.position.x, pos.position.y));
drawable.drawable->drawOn(this->_window);
}
this->_window.endDrawing();
}
void RenderSystem::onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime)
{
const auto &pos = entity.getComponent<PositionComponent>();
const auto &cam = entity.getComponent<CameraComponent>();
_camera.setPosition(pos.position);
_camera.setTarget(cam.target);
}
}
@@ -7,11 +7,15 @@
#include "System/System.hpp"
#include "Camera/Camera2D.hpp"
#include "Window.hpp"
#include "Wal.hpp"
namespace BBM
{
class RenderScreenSystem : public WAL::System
class RenderSystem : public WAL::System
{
//! @brief The ECS to update.
WAL::Wal &_wal;
//! @brief The window to render on
RAY::Window &_window;
@@ -26,12 +30,12 @@ namespace BBM
void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds dtime) override;
//! @brief ctor
explicit RenderScreenSystem(RAY::Window &window);
RenderSystem(WAL::Wal &wal, RAY::Window &window);
//! @brief Default copy ctor
RenderScreenSystem(const RenderScreenSystem &) = default;
RenderSystem(const RenderSystem &) = default;
//! @brief Default dtor
~RenderScreenSystem() override = default;
~RenderSystem() override = default;
//! @brief A render screen system can't be assigned.
RenderScreenSystem &operator=(const RenderScreenSystem &) = delete;
RenderSystem &operator=(const RenderSystem &) = delete;
};
}
@@ -1,48 +0,0 @@
//
// Created by cbihan on 24/05/2021.
//
#pragma once
#include <type_traits>
#include "System/System.hpp"
#include "Entity/Entity.hpp"
#include "Component/Position/PositionComponent.hpp"
#include "Component/Renderer/Drawable2DComponent.hpp"
#include "Window.hpp"
namespace BBM
{
template <class T>
class Renderer2DSystem : public WAL::System
{
private:
//! @brief The class to render
RAY::Window &_window;
public:
explicit Renderer2DSystem()
: WAL::System({typeid(PositionComponent), typeid(Drawable2DComponent<T>)}),
_window(RAY::Window::getInstance())
{
}
//! @brief Update the corresponding component of the given entity
//! @param entity The entity to update.
//! @param dtime The delta time.
void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) override
{
auto &comp = entity.getComponent<Drawable2DComponent<T>>();
auto &pos = entity.getComponent<PositionComponent>();
comp.member.setPosition({pos.getX(), pos.getY()});
comp.member.drawOn(this->_window);
}
//! @brief default copy ctor
Renderer2DSystem(const Renderer2DSystem &) = default;
//! @brief default dtor
~Renderer2DSystem() override = default;
//! @brief Default assignment operator
Renderer2DSystem &operator=(const Renderer2DSystem &) = delete;
};
}
@@ -1,48 +0,0 @@
//
// Created by cbihan on 24/05/2021.
//
#pragma once
#include <type_traits>
#include "System/System.hpp"
#include "Entity/Entity.hpp"
#include "Component/Position/PositionComponent.hpp"
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "Window.hpp"
namespace BBM
{
template <class T>
class Renderer3DSystem : public WAL::System
{
private:
//! @brief The class to render
RAY::Window &_window;
public:
//! @brief ctor
explicit Renderer3DSystem()
: WAL::System({typeid(PositionComponent), typeid(Drawable3DComponent<T>)}),
_window(RAY::Window::getInstance())
{}
//! @brief Update the corresponding component of the given entity
//! @param entity The entity to update.
//! @param dtime The delta time.
void onUpdate(WAL::Entity &entity, std::chrono::nanoseconds) override
{
auto &comp = entity.getComponent<Drawable3DComponent<T>>();
auto &pos = entity.getComponent<PositionComponent>();
comp.member.setPosition(static_cast<RAY::Vector3>(pos.position));
comp.member.drawOn(this->_window);
}
//! @brief Default copy ctor
Renderer3DSystem(const Renderer3DSystem &) = default;
//! @brief Default dtor
~Renderer3DSystem() override = default;
//! @brief Default assignment operator
Renderer3DSystem &operator=(const Renderer3DSystem &) = delete;
};
}
-45
View File
@@ -9,50 +9,6 @@
#include <iostream>
#include "Runner/Runner.hpp"
// Dependencies of the demo
#include "Camera/Camera3D.hpp"
#include "Controllers/Keyboard.hpp"
#include "Drawables/2D/Text.hpp"
#include "Drawables/Image.hpp"
#include "Drawables/3D/Grid.hpp"
#include "Drawables/Texture.hpp"
#include "Drawables/3D/Circle.hpp"
#include "Drawables/2D/Circle.hpp"
#include "Drawables/3D/Cube.hpp"
#include "Drawables/3D/Sphere.hpp"
#include "Model/Model.hpp"
#include "Model/ModelAnimations.hpp"
#include <System/Renderer/RenderScreenSystem.hpp>
#include <System/Renderer/Render2DScreenSystem.hpp>
#include <System/Renderer/Renderer2DSystem.hpp>
#include <System/Renderer/Renderer3DSystem.hpp>
#include "Component/Renderer/Drawable3DComponent.hpp"
#include "Component/Renderer/Drawable2DComponent.hpp"
#include "System/Renderer/RenderScreenSystem.hpp"
#include "Vector/Vector3.hpp"
#include "Window.hpp"
#include "TraceLog.hpp"
#include "Wal.hpp"
const std::vector<std::string>textures = {
"blue", "cyan", "green", "purple", "red", "yellow"
};
std::string get_full_path(const std::string &color)
{
std::string path = "assets/player/";
path += color;
path += ".png";
return path;
}
int demo(void)
{
return (0);
}
void usage(const std::string &bin)
{
std::cout << "Bomberman." << std::endl
@@ -67,6 +23,5 @@ int main(int argc, char **argv)
usage(argv[0]);
return 1;
}
//return demo();
return BBM::run();
}
+147
View File
@@ -0,0 +1,147 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Emscripten-Generated Code</title>
<style>
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
textarea.emscripten { font-family: monospace; width: 80%; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
width: 50px;
margin: 0px auto;
-webkit-animation: rotation .8s linear infinite;
-moz-animation: rotation .8s linear infinite;
-o-animation: rotation .8s linear infinite;
animation: rotation 0.8s linear infinite;
border-left: 10px solid rgb(0,150,240);
border-right: 10px solid rgb(0,150,240);
border-bottom: 10px solid rgb(0,150,240);
border-top: 10px solid rgb(100,0,200);
border-radius: 100%;
background-color: rgb(200,100,250);
}
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
@-moz-keyframes rotation {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(360deg);}
}
@-o-keyframes rotation {
from {-o-transform: rotate(0deg);}
to {-o-transform: rotate(360deg);}
}
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
</style>
</head>
<body>
<hr/>
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
<div class="emscripten" id="status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="progress" hidden=1></progress>
</div>
<div class="emscripten">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
</div>
<hr/>
<div class="emscripten">
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</div>
<hr/>
<script type='text/javascript'>
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&amp;");
//text = text.replace(/</g, "&lt;");
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
printErr: function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.error(text);
},
canvas: (function() {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.last.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
Module.setStatus.last.time = now;
Module.setStatus.last.text = text;
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.hidden = true;
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = function() {
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
</script>
{{{ SCRIPT }}}
</body>
</html>