Initial Commit
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/cmake-build-debug
|
||||||
|
/.idea
|
||||||
|
|
||||||
|
/assets/test_files
|
38
CMakeLists.txt
Normal file
38
CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.28)
|
||||||
|
project(DemoGame
|
||||||
|
VERSION 1.0
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
|
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||||
|
message(FATAL_ERROR "In-source builds are not allowed")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
include (cmake/CPM.cmake)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME JGL
|
||||||
|
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-44.zip
|
||||||
|
)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME ReWindow
|
||||||
|
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-26.zip
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
|
||||||
|
|
||||||
|
file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp")
|
||||||
|
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp")
|
||||||
|
file(COPY "assets" DESTINATION "${PROJECT_BINARY_DIR}")
|
||||||
|
|
||||||
|
add_executable(DemoGame ${SOURCES} main.cpp)
|
||||||
|
target_include_directories(DemoGame PUBLIC
|
||||||
|
${JGL_SOURCE_DIR}/include
|
||||||
|
${ReWindow_SOURCE_DIR}/include
|
||||||
|
${PROJECT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(DemoGame PUBLIC JGL ReWindowLibrary)
|
BIN
assets/sprites/Re3D.png
Normal file
BIN
assets/sprites/Re3D.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
1161
cmake/CPM.cmake
Normal file
1161
cmake/CPM.cmake
Normal file
File diff suppressed because it is too large
Load Diff
23
include/Engine/Animation.h
Normal file
23
include/Engine/Animation.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "JGL/types/Texture.h"
|
||||||
|
|
||||||
|
using JGL::Texture;
|
||||||
|
|
||||||
|
class Animation {
|
||||||
|
protected:
|
||||||
|
std::string name{};
|
||||||
|
float ms_between_frames = 1.0f;
|
||||||
|
std::vector<Texture> textures{};
|
||||||
|
public:
|
||||||
|
[[nodiscard]] std::string GetName() const;
|
||||||
|
[[nodiscard]] float GetMsBetweenFrames() const;
|
||||||
|
|
||||||
|
/// @param animation_time a float from 0 to 1. 0 being the beginning of the animation and 1 being the end.
|
||||||
|
[[nodiscard]] const JGL::Texture* GetTexture(float animation_time) const;
|
||||||
|
public:
|
||||||
|
void SetMsBetweenFrames(float new_ms_between_frames);
|
||||||
|
public:
|
||||||
|
Animation(const std::string& name, float ms_between_frames, std::vector<Texture>& textures) : name(name), ms_between_frames(ms_between_frames), textures(textures) {};
|
||||||
|
~Animation() = default;
|
||||||
|
};
|
7
include/Engine/Entity/Camera.h
Normal file
7
include/Engine/Entity/Camera.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include "J3ML/LinearAlgebra/Vector2.hpp"
|
||||||
|
#include "Entity.h"
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Camera : public Entity {
|
||||||
|
|
||||||
|
};
|
37
include/Engine/Entity/Entity.h
Normal file
37
include/Engine/Entity/Entity.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "J3ML/LinearAlgebra/Vector2.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Entity {
|
||||||
|
protected:
|
||||||
|
std::vector<Entity*> children{};
|
||||||
|
Vector2 position = {0, 0};
|
||||||
|
// Assuming 0 radians is up.
|
||||||
|
float face_angle = 0.0f;
|
||||||
|
void UpdateChildren();
|
||||||
|
public:
|
||||||
|
// Movements independent of the rotation.
|
||||||
|
void MoveX(float speed);
|
||||||
|
void MoveY(float speed);
|
||||||
|
|
||||||
|
// Movements dependent on face angle.
|
||||||
|
void MoveForward(float speed);
|
||||||
|
void MoveBackward(float speed);
|
||||||
|
void MoveLeft(float speed);
|
||||||
|
void MoveRight(float speed);
|
||||||
|
|
||||||
|
void Rotate(float speed);
|
||||||
|
void SetRotation(float new_rotation);
|
||||||
|
|
||||||
|
[[nodiscard]] bool AppendChild(Entity* entity);
|
||||||
|
void DestroyChild(Entity* entity);
|
||||||
|
void RemoveChild(Entity* entity);
|
||||||
|
public:
|
||||||
|
[[nodiscard]] float GetRotation() const;
|
||||||
|
[[nodiscard]] Vector2 GetPosition() const;
|
||||||
|
public:
|
||||||
|
virtual void Update() {}
|
||||||
|
public:
|
||||||
|
explicit Entity(const Vector2& position, float rotation = 0.0f) : position(position), face_angle(rotation) {}
|
||||||
|
virtual ~Entity();
|
||||||
|
};
|
7
include/Engine/Entity/Hud.h
Normal file
7
include/Engine/Entity/Hud.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Renderable.h"
|
||||||
|
|
||||||
|
class Hud : public Renderable {
|
||||||
|
public:
|
||||||
|
Hud() : Renderable({0, 0}, 0) {};
|
||||||
|
};
|
11
include/Engine/Entity/Renderable.h
Normal file
11
include/Engine/Entity/Renderable.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "JGL/JGL.h"
|
||||||
|
|
||||||
|
class Renderable : public Entity {
|
||||||
|
public:
|
||||||
|
virtual void Render() {}
|
||||||
|
public:
|
||||||
|
explicit Renderable(const Vector2& position, float rotation = 0.0f) : Entity(position, rotation) {}
|
||||||
|
};
|
15
include/Engine/GameWindow.h
Normal file
15
include/Engine/GameWindow.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <rewindow/types/window.h>
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
class DemoGameWindow : public ReWindow::RWindow {
|
||||||
|
public:
|
||||||
|
void InitGL();
|
||||||
|
void Display();
|
||||||
|
public:
|
||||||
|
void OnRefresh(float elapsed) override;
|
||||||
|
public:
|
||||||
|
DemoGameWindow() : ReWindow::RWindow() {}
|
||||||
|
DemoGameWindow(const std::string& title, int width, int height) : ReWindow::RWindow(title, width, height) {}
|
||||||
|
|
||||||
|
};
|
13
include/Engine/Globals.h
Normal file
13
include/Engine/Globals.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Engine/Level/Scene.h>
|
||||||
|
#include <Engine/GameWindow.h>
|
||||||
|
|
||||||
|
namespace Globals {
|
||||||
|
inline Scene* CurrentScene = nullptr;
|
||||||
|
inline DemoGameWindow* Window = nullptr;
|
||||||
|
|
||||||
|
inline float DeltaTime() { return Window->GetDeltaTime(); }
|
||||||
|
inline void RemoveScene() { delete CurrentScene; CurrentScene = nullptr; }
|
||||||
|
inline void ChangeScene(Scene* scene) { delete CurrentScene; CurrentScene = scene; CurrentScene->Init(); }
|
||||||
|
}
|
36
include/Engine/Level/Fixed.h
Normal file
36
include/Engine/Level/Fixed.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "J3ML/LinearAlgebra/Vector2i.hpp"
|
||||||
|
#include "J3ML/Geometry/AABB2D.hpp"
|
||||||
|
#include "JGL/types/Texture.h"
|
||||||
|
|
||||||
|
using J3ML::LinearAlgebra::Vector2i;
|
||||||
|
using JGL::Texture;
|
||||||
|
|
||||||
|
// Things that are considered non-movable parts of the level.
|
||||||
|
// TODO instanced textures.
|
||||||
|
class Fixed {
|
||||||
|
private:
|
||||||
|
void GenerateCollision();
|
||||||
|
protected:
|
||||||
|
std::vector<Vector2i> collision{};
|
||||||
|
bool enabled = false;
|
||||||
|
bool collidable = false;
|
||||||
|
Vector2i position = {0, 0};
|
||||||
|
const Texture* texture = nullptr;
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool Collidable() const;
|
||||||
|
[[nodiscard]] Vector2i GetPosition() const;
|
||||||
|
[[nodiscard]] AABB2D GetBounds() const;
|
||||||
|
[[nodiscard]] bool Enabled() const;
|
||||||
|
[[nodiscard]] std::vector<Vector2i> GetCollision();
|
||||||
|
[[nodiscard]] const Texture* GetTexture();
|
||||||
|
public:
|
||||||
|
void Enable();
|
||||||
|
void Disable();
|
||||||
|
virtual void Render() {};
|
||||||
|
public:
|
||||||
|
Fixed(const Vector2i& position, bool enabled, bool collidable, const Texture* texture) : position(position), enabled(enabled), collidable(collidable), texture(texture)
|
||||||
|
{ if (collidable) GenerateCollision(); }
|
||||||
|
virtual ~Fixed();
|
||||||
|
};
|
37
include/Engine/Level/Scene.h
Normal file
37
include/Engine/Level/Scene.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <Engine/Entity/Renderable.h>
|
||||||
|
#include <Engine/Entity/Hud.h>
|
||||||
|
#include <Engine/Level/Fixed.h>
|
||||||
|
|
||||||
|
class Scene {
|
||||||
|
protected:
|
||||||
|
bool Paused = false;
|
||||||
|
Hud* HeadsUpDisplay = nullptr;
|
||||||
|
std::vector<Fixed*> FixedList{};
|
||||||
|
std::vector<Entity*> EntityList{};
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool EntityListContains(const Entity* entity) const;
|
||||||
|
[[nodiscard]] bool FixedListContains(const Fixed* fixed) const;
|
||||||
|
[[nodiscard]] size_t FixedCount() const;
|
||||||
|
[[nodiscard]] size_t EntityCount() const;
|
||||||
|
public:
|
||||||
|
void AppendEntity(Entity* entity);
|
||||||
|
void AppendFixed(Fixed* fixed);
|
||||||
|
|
||||||
|
// Removes and deallocates.
|
||||||
|
void DestroyEntity(Entity* entity);
|
||||||
|
void DestroyFixed(Fixed* fixed);
|
||||||
|
|
||||||
|
// Only removes from the list.
|
||||||
|
void RemoveEntity(Entity* entity);
|
||||||
|
void RemoveFixed(Fixed* fixed);
|
||||||
|
|
||||||
|
virtual void Init() {}
|
||||||
|
virtual void Update();
|
||||||
|
virtual void Render();
|
||||||
|
public:
|
||||||
|
Scene() = default;
|
||||||
|
virtual ~Scene();
|
||||||
|
};
|
11
include/Game/Entity/Box.h
Normal file
11
include/Game/Entity/Box.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Engine/Entity/Renderable.h>
|
||||||
|
#include "Engine/Globals.h"
|
||||||
|
class Box final : public Renderable {
|
||||||
|
public:
|
||||||
|
void Render() final;
|
||||||
|
void Update() final;
|
||||||
|
public:
|
||||||
|
explicit Box(const Vector2& position, float rotation = 0.0f) : Renderable(position, rotation) {}
|
||||||
|
};
|
10
include/Game/Entity/DemoGameHud.h
Normal file
10
include/Game/Entity/DemoGameHud.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include <Engine/Entity/Hud.h>
|
||||||
|
|
||||||
|
class DemoGameHud : public Hud {
|
||||||
|
public:
|
||||||
|
void Render() override;
|
||||||
|
public:
|
||||||
|
DemoGameHud() : Hud() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
12
include/Game/Scene/DemoGameScene.h
Normal file
12
include/Game/Scene/DemoGameScene.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Engine/Level/Scene.h"
|
||||||
|
|
||||||
|
class DemoGameScene final : public Scene {
|
||||||
|
public:
|
||||||
|
void Init() final;
|
||||||
|
public:
|
||||||
|
DemoGameScene() = default;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
16
include/Game/Scene/Splash.h
Normal file
16
include/Game/Scene/Splash.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Engine/Level/Scene.h"
|
||||||
|
|
||||||
|
class DemoGameSplash final : public Scene {
|
||||||
|
protected:
|
||||||
|
float elapsed = 0.0f;
|
||||||
|
float angle = 0.0f;
|
||||||
|
Texture* RedactedSoftware = nullptr;
|
||||||
|
public:
|
||||||
|
DemoGameSplash() : Scene() {}
|
||||||
|
|
||||||
|
void Init() final;
|
||||||
|
void Update() final;
|
||||||
|
void Render() final;
|
||||||
|
~DemoGameSplash() final;
|
||||||
|
};
|
26
main.cpp
Normal file
26
main.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "Engine/Globals.h"
|
||||||
|
#include <Engine/Level/Scene.h>
|
||||||
|
#include <rewindow/logger/logger.h>
|
||||||
|
#include "Game/Scene/Splash.h"
|
||||||
|
|
||||||
|
Scene* scene = nullptr;
|
||||||
|
|
||||||
|
using namespace JGL;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Globals::Window = new DemoGameWindow("Demo Game", 1024, 896);
|
||||||
|
Globals::Window->SetRenderer(RenderingAPI::OPENGL);
|
||||||
|
Globals::Window->Open();
|
||||||
|
Globals::Window->InitGL();
|
||||||
|
Globals::Window->SetResizable(false);
|
||||||
|
Globals::Window->SetVsyncEnabled(false);
|
||||||
|
ReWindow::Logger::Error.EnableConsole(false);
|
||||||
|
ReWindow::Logger::Warning.EnableConsole(false);
|
||||||
|
ReWindow::Logger::Debug.EnableConsole(false);
|
||||||
|
|
||||||
|
auto* splash = new DemoGameSplash();
|
||||||
|
Globals::ChangeScene(splash);
|
||||||
|
|
||||||
|
while (Globals::Window->IsAlive())
|
||||||
|
Globals::Window->ManagedRefresh();
|
||||||
|
}
|
27
src/Engine/Animation.cpp
Normal file
27
src/Engine/Animation.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "Engine/Animation.h"
|
||||||
|
#include "jlog/Logger.hpp"
|
||||||
|
|
||||||
|
float Animation::GetMsBetweenFrames() const {
|
||||||
|
return ms_between_frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::SetMsBetweenFrames(float new_ms_between_frames) {
|
||||||
|
ms_between_frames = new_ms_between_frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Animation::GetName() const {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const JGL::Texture* Animation::GetTexture(float animation_time) const {
|
||||||
|
if (textures.empty())
|
||||||
|
jlog::Fatal("Getting an animation frame but the animation is empty?");
|
||||||
|
|
||||||
|
animation_time = std::max(0.0f, std::min(animation_time, 1.0f));
|
||||||
|
float animation_ms = ms_between_frames * textures.size();
|
||||||
|
float animation_length_ms = animation_time * animation_ms;
|
||||||
|
auto frame_index = (size_t) std::floor(animation_length_ms / ms_between_frames);
|
||||||
|
frame_index = std::min(frame_index, textures.size() - 1);
|
||||||
|
|
||||||
|
return &textures[frame_index];
|
||||||
|
}
|
0
src/Engine/Entity/Camera.cpp
Normal file
0
src/Engine/Entity/Camera.cpp
Normal file
88
src/Engine/Entity/Entity.cpp
Normal file
88
src/Engine/Entity/Entity.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include "J3ML/J3ML.hpp"
|
||||||
|
#include "Engine/Entity/Entity.h"
|
||||||
|
#include "Engine/Globals.h"
|
||||||
|
|
||||||
|
using namespace J3ML;
|
||||||
|
void Entity::MoveX(float speed) {
|
||||||
|
position.x = position.x + (speed * Globals::Window->GetDeltaTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::MoveY(float speed) {
|
||||||
|
position.y = position.y + (speed * Globals::DeltaTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::MoveForward(float speed) {
|
||||||
|
position.x = position.x + (speed * Globals::DeltaTime()) * Math::Cos(face_angle);
|
||||||
|
position.y = position.y + (speed * Globals::DeltaTime()) * Math::Sin(face_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::MoveBackward(float speed) {
|
||||||
|
speed = -speed;
|
||||||
|
position.x = position.x + (speed * Globals::DeltaTime()) * Math::Cos(face_angle);
|
||||||
|
position.y = position.y + (speed * Globals::DeltaTime()) * Math::Sin(face_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::MoveLeft(float speed) {
|
||||||
|
position.x = position.x + (speed * Globals::DeltaTime()) * -Math::Sin(face_angle);
|
||||||
|
position.y = position.y + (speed * Globals::DeltaTime()) * Math::Cos(face_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::MoveRight(float speed) {
|
||||||
|
position.x = position.x + (speed * Globals::DeltaTime()) * Math::Sin(face_angle);
|
||||||
|
position.y = position.y + (speed * Globals::DeltaTime()) * -Math::Cos(face_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::SetRotation(float new_face_angle) {
|
||||||
|
face_angle = new_face_angle;
|
||||||
|
|
||||||
|
if (face_angle < 0)
|
||||||
|
face_angle = fmod(face_angle + Math::Pi * 2, Math::Pi * 2);
|
||||||
|
else if (face_angle >= 2 * M_PI)
|
||||||
|
face_angle = fmod(face_angle, Math::Pi * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::Rotate(float speed) {
|
||||||
|
SetRotation(face_angle + speed * Globals::DeltaTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
float Entity::GetRotation() const {
|
||||||
|
return face_angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Entity::GetPosition() const {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::AppendChild(Entity* entity) {
|
||||||
|
bool success = false;
|
||||||
|
if (!Globals::CurrentScene->EntityListContains(entity))
|
||||||
|
children.push_back(entity), success = true;
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::~Entity() {
|
||||||
|
for (auto* e : children)
|
||||||
|
delete e;
|
||||||
|
|
||||||
|
children = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::UpdateChildren() {
|
||||||
|
for (auto& e : children) {
|
||||||
|
e->Update();
|
||||||
|
if (!e->children.empty())
|
||||||
|
e->UpdateChildren();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::DestroyChild(Entity* entity) {
|
||||||
|
auto it = std::find(children.begin(), children.end(), entity);
|
||||||
|
if (it != children.end())
|
||||||
|
delete *it, children.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::RemoveChild(Entity* entity) {
|
||||||
|
auto it = std::find(children.begin(), children.end(), entity);
|
||||||
|
if (it != children.end())
|
||||||
|
children.erase(it);
|
||||||
|
}
|
1
src/Engine/Entity/Renderable.cpp
Normal file
1
src/Engine/Entity/Renderable.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
32
src/Engine/GameWindow.cpp
Normal file
32
src/Engine/GameWindow.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "Engine/GameWindow.h"
|
||||||
|
#include "Engine/Globals.h"
|
||||||
|
#include "Engine/Entity/Camera.h"
|
||||||
|
#include "JGL/JGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
void DemoGameWindow::InitGL() {
|
||||||
|
if (!JGL::Init(GetSize(), 0, 0))
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoGameWindow::Display() {
|
||||||
|
JGL::Update(GetSize());
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
// These are checked separately so that if Update() changes the scene we don't crash.
|
||||||
|
if (Globals::CurrentScene)
|
||||||
|
Globals::CurrentScene->Update();
|
||||||
|
if (Globals::CurrentScene)
|
||||||
|
Globals::CurrentScene->Render();
|
||||||
|
|
||||||
|
DemoGameWindow::GLSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoGameWindow::OnRefresh(float elapsed) {
|
||||||
|
Display();
|
||||||
|
}
|
52
src/Engine/Level/Fixed.cpp
Normal file
52
src/Engine/Level/Fixed.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "Engine/Level/Fixed.h"
|
||||||
|
|
||||||
|
bool Fixed::Collidable() const {
|
||||||
|
return collidable;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2i Fixed::GetPosition() const {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
AABB2D Fixed::GetBounds() const {
|
||||||
|
auto maximum = Vector2(position.x + texture->GetDimensions().x, position.y + texture->GetDimensions().y);
|
||||||
|
return { Vector2(position), maximum };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Fixed::Enabled() const {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fixed::Enable() {
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fixed::Disable() {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fixed::~Fixed() {
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fixed::GenerateCollision() {
|
||||||
|
if (!Collidable() || !Enabled() || !texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<Vector2i> result{};
|
||||||
|
auto pixel_data = texture->GetPixelData();
|
||||||
|
|
||||||
|
for (int y = 0; y < texture->GetDimensions().y; y++)
|
||||||
|
for (int x = 0; x < texture->GetDimensions().x; x++)
|
||||||
|
if (pixel_data[y * texture->GetDimensions().x + x].A() != 0)
|
||||||
|
result.emplace_back((int) x + position.x, (int) y + position.y);
|
||||||
|
collision = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vector2i> Fixed::GetCollision() {
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Texture* Fixed::GetTexture() {
|
||||||
|
return texture;
|
||||||
|
}
|
86
src/Engine/Level/Scene.cpp
Normal file
86
src/Engine/Level/Scene.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include "Engine/Level/Scene.h"
|
||||||
|
|
||||||
|
bool Scene::EntityListContains(const Entity* entity) const {
|
||||||
|
for (auto* e : EntityList)
|
||||||
|
if (e == entity)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::FixedListContains(const Fixed* fixed) const {
|
||||||
|
for (auto* f : FixedList)
|
||||||
|
if (f == fixed)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Scene::FixedCount() const {
|
||||||
|
return FixedList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Scene::EntityCount() const {
|
||||||
|
return EntityList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::Update() {
|
||||||
|
for (auto& e : EntityList)
|
||||||
|
e->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::Render() {
|
||||||
|
for (auto& f : FixedList)
|
||||||
|
if (f->Enabled())
|
||||||
|
f->Render();
|
||||||
|
|
||||||
|
// TODO Render order. In this system it's not possible for child entities to be rendered before the parent.
|
||||||
|
for (auto& e : EntityList)
|
||||||
|
if (auto* r = dynamic_cast<Renderable*>(e))
|
||||||
|
r->Render();
|
||||||
|
|
||||||
|
if (HeadsUpDisplay)
|
||||||
|
HeadsUpDisplay->Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene::~Scene() {
|
||||||
|
for (auto* f : FixedList)
|
||||||
|
delete f;
|
||||||
|
|
||||||
|
for (auto* e : EntityList)
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::AppendEntity(Entity* entity) {
|
||||||
|
if (!EntityListContains(entity))
|
||||||
|
EntityList.push_back(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::AppendFixed(Fixed* fixed) {
|
||||||
|
if (!FixedListContains(fixed))
|
||||||
|
FixedList.push_back(fixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::DestroyEntity(Entity *entity) {
|
||||||
|
auto it = std::find(EntityList.begin(), EntityList.end(), entity);
|
||||||
|
if (it != EntityList.end())
|
||||||
|
delete *it, EntityList.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::DestroyFixed(Fixed* fixed) {
|
||||||
|
auto it = std::find(FixedList.begin(), FixedList.end(), fixed);
|
||||||
|
if (it != FixedList.end())
|
||||||
|
delete *it, FixedList.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::RemoveEntity(Entity* entity) {
|
||||||
|
auto it = std::find(EntityList.begin(), EntityList.end(), entity);
|
||||||
|
if (it != EntityList.end())
|
||||||
|
EntityList.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Scene::RemoveFixed(Fixed* fixed) {
|
||||||
|
auto it = std::find(FixedList.begin(), FixedList.end(), fixed);
|
||||||
|
if (it != FixedList.end())
|
||||||
|
FixedList.erase(it);
|
||||||
|
}
|
||||||
|
|
11
src/Game/DemoGameScene.cpp
Normal file
11
src/Game/DemoGameScene.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <Game/Scene/DemoGameScene.h>
|
||||||
|
#include <Game/Entity/DemoGameHud.h>
|
||||||
|
#include <Game/Entity/Box.h>
|
||||||
|
|
||||||
|
void DemoGameScene::Init() {
|
||||||
|
auto* hud = new DemoGameHud();
|
||||||
|
auto* b = new Box({0, 0});
|
||||||
|
|
||||||
|
HeadsUpDisplay = hud;
|
||||||
|
AppendEntity(b);
|
||||||
|
}
|
18
src/Game/Entities/Box.cpp
Normal file
18
src/Game/Entities/Box.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <Game/Entity/Box.h>
|
||||||
|
|
||||||
|
void Box::Render() {
|
||||||
|
J2D::Begin(nullptr, true);
|
||||||
|
J2D::FillRect(Colors::Red, Vector2(position), {20, 20});
|
||||||
|
J2D::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Box::Update() {
|
||||||
|
if (Globals::Window->IsKeyDown(Keys::W))
|
||||||
|
MoveY(-500);
|
||||||
|
if (Globals::Window->IsKeyDown(Keys::S))
|
||||||
|
MoveY(500);
|
||||||
|
if (Globals::Window->IsKeyDown(Keys::A))
|
||||||
|
MoveX(-500);
|
||||||
|
if (Globals::Window->IsKeyDown(Keys::D))
|
||||||
|
MoveX(500);
|
||||||
|
}
|
9
src/Game/Entities/DemoGameHud.cpp
Normal file
9
src/Game/Entities/DemoGameHud.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <Game/Entity/DemoGameHud.h>
|
||||||
|
#include <Engine/Globals.h>
|
||||||
|
|
||||||
|
void DemoGameHud::Render() {
|
||||||
|
float framerate = Globals::Window->GetRefreshRate();
|
||||||
|
J2D::Begin(nullptr, true);
|
||||||
|
J2D::DrawString(Colors::Whites::Ivory, "Framerate: " + std::to_string((int) framerate), 0, 0, 1, 16);
|
||||||
|
J2D::End();
|
||||||
|
}
|
38
src/Game/Splash.cpp
Normal file
38
src/Game/Splash.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include "Game/Scene/Splash.h"
|
||||||
|
#include "Engine/Globals.h"
|
||||||
|
#include "Game/Scene/DemoGameScene.h"
|
||||||
|
|
||||||
|
void DemoGameSplash::Init() {
|
||||||
|
RedactedSoftware = new JGL::Texture("assets/sprites/Re3D.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoGameSplash::Update() {
|
||||||
|
angle += (elapsed * 4) * Globals::DeltaTime();
|
||||||
|
elapsed += Globals::DeltaTime();
|
||||||
|
|
||||||
|
// Pretend we're actually loading something idk.
|
||||||
|
if (elapsed >= 2.75) {
|
||||||
|
auto* dgs = new DemoGameScene();
|
||||||
|
Globals::ChangeScene(dgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoGameSplash::Render() {
|
||||||
|
auto text_length = JGL::Fonts::Jupiteroid.MeasureString("Loading ....", 24);
|
||||||
|
std::string text = "Loading";
|
||||||
|
int dots = static_cast<int>(floor(elapsed / 0.35)) % 4;
|
||||||
|
for (int i = 0; i < dots; ++i)
|
||||||
|
text += ".";
|
||||||
|
|
||||||
|
J2D::Begin(nullptr, true);
|
||||||
|
J2D::DrawSprite(RedactedSoftware, {Globals::Window->GetSize().x - RedactedSoftware->GetDimensions().x, Globals::Window->GetSize().y - RedactedSoftware->GetDimensions().y}, angle, {0.5, 0.5});
|
||||||
|
J2D::DrawString(Colors::Whites::Ivory, text, (Globals::Window->GetSize().x - text_length.x) - RedactedSoftware->GetDimensions().x , Globals::Window->GetSize().y - text_length.y * 1.125, 1, 24);
|
||||||
|
J2D::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DemoGameSplash::~DemoGameSplash() {
|
||||||
|
delete RedactedSoftware;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user