-
Notifications
You must be signed in to change notification settings - Fork 27
Simple game engine #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Simple game engine #119
Changes from 6 commits
12f357f
7e419d5
4644950
2edbd75
b476bd1
f1d10cf
2a350b2
2d46280
3b3dc05
6cf03fc
50d78a7
9b2c781
ddd1177
5ec2035
31ded49
659ecb1
bd98b2d
8b83ead
9b2343a
7734f21
b8a9b39
e773353
6256f77
e6b8583
e3f6fc6
4a3b450
0833166
9513597
86c396a
a62e4a9
14fc6b1
b998a13
8be59f4
be45542
8bdf3d1
e80fd23
20a9ade
d834c39
ea39e65
858b792
815aa79
bdc1845
04c8b38
cdb01db
16019ca
4b8198d
14dcb35
dd9713a
27715c0
067ea74
a5edf28
adf461e
e57bc3d
e1d7059
1f17074
acfbd6e
5e38540
a58b884
4b4a243
6ec7321
8ecae4e
345b137
11e9a65
5e6209c
25e66d5
5849fa5
f1df3d2
7eaa47e
92c7f7d
625eb71
60ee95d
23952bc
65e5db3
e564b29
7b3e016
7bf9dab
47a6baa
44e7f38
dd51a38
f713e9c
9705b60
921eed4
2a22079
41e336e
b78f8b2
5c7a132
560b9f3
6db6b9d
02baf4d
0b0dddb
ccb5c15
aa321c0
5c4ec27
b4d6226
a8d11c6
b167c70
276d1cb
6e8adb4
e1ac508
bbbae41
03d05cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
#include <vector> | ||
#include <memory> | ||
#include <unordered_map> | ||
#include <chrono> | ||
|
||
#include "platform.h" | ||
#include "renderer.h" | ||
|
@@ -23,6 +24,7 @@ | |
*/ | ||
class Engine { | ||
public: | ||
using TimeDelta = std::chrono::milliseconds; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Throughout the code, you're sometimes using |
||
/** | ||
* @brief Default constructor. | ||
*/ | ||
|
@@ -167,7 +169,11 @@ class Engine { | |
* @param enableValidationLayers Whether to enable Vulkan validation layers. | ||
* @return True if initialization was successful, false otherwise. | ||
*/ | ||
#if defined(NDEBUG) | ||
bool InitializeAndroid(android_app* app, const std::string& appName, bool enableValidationLayers = false); | ||
#else | ||
bool InitializeAndroid(android_app* app, const std::string& appName, bool enableValidationLayers = true); | ||
#endif | ||
|
||
/** | ||
* @brief Run the engine on Android. | ||
|
@@ -197,8 +203,9 @@ class Engine { | |
bool running = false; | ||
|
||
// Delta time calculation | ||
float deltaTime = 0.0f; | ||
uint64_t lastFrameTime = 0; | ||
// deltaTimeMs: time since last frame in milliseconds (for clarity) | ||
std::chrono::milliseconds deltaTimeMs{0}; | ||
uint64_t lastFrameTimeMs = 0; | ||
|
||
// Frame counter and FPS calculation | ||
uint64_t frameCount = 0; | ||
|
@@ -254,7 +261,7 @@ class Engine { | |
|
||
PhysicsScaling physicsScaling; | ||
|
||
// Pending ball creation data (to avoid memory pool constraints during rendering) | ||
// Pending ball creation data | ||
struct PendingBall { | ||
glm::vec3 spawnPosition; | ||
glm::vec3 throwDirection; | ||
|
@@ -269,18 +276,19 @@ class Engine { | |
* @brief Update the engine state. | ||
* @param deltaTime The time elapsed since the last update. | ||
*/ | ||
void Update(float deltaTime); | ||
// Accepts a time delta in milliseconds for clarity | ||
void Update(TimeDelta deltaTime); | ||
|
||
/** | ||
* @brief Render the scene. | ||
*/ | ||
void Render(); | ||
|
||
/** | ||
* @brief Calculate the delta time between frames. | ||
* @return The delta time in seconds. | ||
* @brief Calculate the time delta between frames. | ||
* @return The delta time in milliseconds (steady_clock based). | ||
*/ | ||
float CalculateDeltaTime(); | ||
std::chrono::milliseconds CalculateDeltaTimeMs(); | ||
|
||
/** | ||
* @brief Handle window resize events. | ||
|
@@ -293,7 +301,7 @@ class Engine { | |
* @brief Update camera controls based on input state. | ||
* @param deltaTime The time elapsed since the last update. | ||
*/ | ||
void UpdateCameraControls(float deltaTime) const; | ||
void UpdateCameraControls(TimeDelta deltaTime) const; | ||
|
||
/** | ||
* @brief Generate random PBR material properties for the ball. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,7 @@ | |
#include <memory> | ||
#include <string> | ||
#include <algorithm> | ||
#include <typeindex> | ||
#include <unordered_map> | ||
#include <chrono> | ||
#include <type_traits> | ||
|
||
#include "component.h" | ||
|
@@ -21,7 +20,6 @@ class Entity { | |
std::string name; | ||
bool active = true; | ||
std::vector<std::unique_ptr<Component>> components; | ||
std::unordered_map<std::type_index, Component*> componentMap; | ||
|
||
public: | ||
/** | ||
|
@@ -62,7 +60,7 @@ class Entity { | |
* @brief Update all components of the entity. | ||
* @param deltaTime The time elapsed since the last frame. | ||
*/ | ||
void Update(float deltaTime); | ||
void Update(std::chrono::milliseconds deltaTime); | ||
|
||
/** | ||
* @brief Render all components of the entity. | ||
|
@@ -87,10 +85,7 @@ class Entity { | |
// Set the owner | ||
componentPtr->SetOwner(this); | ||
|
||
// Add to the map for quick lookup | ||
componentMap[std::type_index(typeid(T))] = componentPtr; | ||
|
||
// Add to the vector for ownership | ||
// Add to the vector for ownership and iteration | ||
components.push_back(std::move(component)); | ||
|
||
// Initialize the component | ||
|
@@ -108,11 +103,12 @@ class Entity { | |
T* GetComponent() const { | ||
static_assert(std::is_base_of<Component, T>::value, "T must derive from Component"); | ||
|
||
auto it = componentMap.find(std::type_index(typeid(T))); | ||
if (it != componentMap.end()) { | ||
return static_cast<T*>(it->second); | ||
// Search from the back to preserve previous behavior of returning the last-added component of type T | ||
for (auto it = components.rbegin(); it != components.rend(); ++it) { | ||
if (auto* casted = dynamic_cast<T*>(it->get())) { | ||
return casted; | ||
} | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
|
@@ -125,21 +121,9 @@ class Entity { | |
bool RemoveComponent() { | ||
static_assert(std::is_base_of<Component, T>::value, "T must derive from Component"); | ||
|
||
auto it = componentMap.find(std::type_index(typeid(T))); | ||
if (it != componentMap.end()) { | ||
Component* componentPtr = it->second; | ||
|
||
// Remove from the map | ||
componentMap.erase(it); | ||
|
||
// Find and remove from the vector | ||
auto vecIt = std::find_if(components.begin(), components.end(), | ||
[componentPtr](const std::unique_ptr<Component>& comp) { | ||
return comp.get() == componentPtr; | ||
}); | ||
|
||
if (vecIt != components.end()) { | ||
components.erase(vecIt); | ||
for (auto it = components.rbegin(); it != components.rend(); ++it) { | ||
if (dynamic_cast<T*>(it->get()) != nullptr) { | ||
components.erase(std::next(it).base()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you erase |
||
return true; | ||
} | ||
} | ||
|
@@ -155,6 +139,6 @@ class Entity { | |
template<typename T> | ||
bool HasComponent() const { | ||
static_assert(std::is_base_of<Component, T>::value, "T must derive from Component"); | ||
return componentMap.contains(std::type_index(typeid(T))); | ||
return GetComponent<T>() != nullptr; | ||
} | ||
}; |
Uh oh!
There was an error while loading. Please reload this page.