From 5e5161bc4847741105fd1b4e69c94b98eca25142 Mon Sep 17 00:00:00 2001
From: KosmX <kosmx.mc@gmail.com>
Date: Sun, 2 May 2021 13:38:16 +0200
Subject: [PATCH] hitbox???

---
 DynamicArray.hpp     | 29 ++++++++++++++++++++++---
 Entity.cpp           | 51 ++++++++++++++++++++++++++++++++++----------
 Entity.h             | 17 +++++++++------
 EntityCollection.hpp |  1 +
 game.cpp             |  4 +++-
 mainGame.cpp         | 33 ++++++++++++++++++++++------
 mainGame.h           | 16 ++++++++++++--
 7 files changed, 122 insertions(+), 29 deletions(-)
 create mode 100644 EntityCollection.hpp

diff --git a/DynamicArray.hpp b/DynamicArray.hpp
index 4d7988a..55d82af 100644
--- a/DynamicArray.hpp
+++ b/DynamicArray.hpp
@@ -1,7 +1,6 @@
 #pragma once
 
 #include <list>
-#include <vector>
 
 //I won't be able to do an enhanced (Range-based) for with this...
 
@@ -12,14 +11,38 @@ template<typename T>
 class DynamicArray
 {
 private:
-	std::vector<T> entries;
+	//I won't be very efficient
+	std::list<T> entries;
 	std::list<T> newEntries;
 
 public:
+	DynamicArray() : entries(), newEntries(){}
+
+	DynamicArray<T>& operator+=(T& entry)
+	{
+		newEntries.push_back(entry);
+		return *this;
+	}
+
+	void finalizeAdd()
+	{
+		//this moves every entry form newEntries to entries.
+		//makes the newEntries empty.
+		entries.merge(newEntries);
+	}
+
+	void removeIf(bool (*l)(const T&))
+	{
+		entries.remove_if(l);
+	}
 	
+	//It will mainly iterate, not search
 	auto begin()
 	{
 		return entries.begin();
 	}
+	auto end()
+	{
+		return entries.end();
+	}
 };
-
diff --git a/Entity.cpp b/Entity.cpp
index 32356be..7893c98 100644
--- a/Entity.cpp
+++ b/Entity.cpp
@@ -1,28 +1,57 @@
 #include "Entity.h"
 
+#include <utility>
+
+using namespace std;
+using namespace olc;
+
+// fine tuning the collision engine, the edges of a box won't collide
+const float ignoreDistance = 0.01f;
+
 namespace entities {
-	Entity::Entity(render::ITexture& texture, const olc::vf2d& pos)
-		:pos(pos), texture(texture)
+	/*
+	 * hitBox calc
+	 * @parameter other the other entity
+	 * @return to move to avoid collision
+	 */
+	vf2d Entity::getCollision(const Entity& other)
 	{
-		
+		const vf2d delta = this->getPos() - other.getPos();
+		//pair<bool, bool> dir(delta.x < 0, delta.y < 0);
+		vf2d dir(delta.x < 0 ? 1 : -1, delta.y < 0 ? 1 : -1);
+		vf2d offset(abs(delta.x), abs(delta.y));
+		vf2d hitSize = this->getHitBoxSize() + other.getHitBoxSize();
+		offset -= hitSize;
+		offset = vf2d(offset.x < 0 ? offset.x : 0, offset.y < 0 ? offset.y : 0);
+		offset *= dir;
+		hitSize -= vf2d(ignoreDistance, ignoreDistance);
+		if (delta.x > hitSize.x) {
+			offset.x = 0;
+		}
+		if (delta.y > hitSize.y) {
+			offset.y = 0;
+		}
+		return offset;
 	}
-	olc::vf2d Entity::getPos() const
+
+	
+	Entity::Entity(const olc::vf2d& pos)
+		: pos(pos)
 	{
-		return this->pos;
+		
 	}
-	void Entity::render(olc::TransformedView& scene) const
+	vf2d Entity::getPos() const
 	{
-		this->texture.render(scene, *this);
+		return this->pos;
 	}
-	Entity::~Entity()
+	void Entity::render(olc::TransformedView& scene)
 	{
-		delete &texture;
+		getTexture().render(scene, *this);
 	}
 
-
 }
 
-olc::TransformedView& operator+=(olc::TransformedView& scene, entities::Entity& entity) {
+TransformedView& operator+=(olc::TransformedView& scene, entities::Entity& entity) {
 	entity.render(scene);
 	return scene;
 }
\ No newline at end of file
diff --git a/Entity.h b/Entity.h
index 561c207..76ecd85 100644
--- a/Entity.h
+++ b/Entity.h
@@ -2,6 +2,7 @@
 
 #include "olc.h"
 #include "ITexture.h"
+#include "mainGame.h"
 
 namespace entities {
 
@@ -10,18 +11,22 @@ namespace entities {
 	protected:
 		olc::vf2d pos; //I can store these safely directly
 		virtual render::ITexture& getTexture() = 0;
+
+		virtual olc::vf2d getHitBoxSize() const = 0;
+		virtual olc::vf2d getCollision(const Entity& other);
 	public:
 
-		Entity(render::ITexture& texture, const olc::vf2d& pos);
-		
-		virtual olc::vf2d getPos() const;
+		Entity(const olc::vf2d& pos);
+
+		//nodiscard???
+		[[nodiscard]] virtual olc::vf2d getPos() const;
 
-		virtual void tick(float deltaT){}
+		virtual void tick(GameClient& client, float deltaT){}
 
 		//this shouldn't change it's state
-		virtual void render(olc::TransformedView& scene) const;
+		virtual void render(olc::TransformedView& scene);
 
-		virtual ~Entity();
+		virtual ~Entity() = default;
 
 		//TODO getAs*** stuff, all virtual
 	};
diff --git a/EntityCollection.hpp b/EntityCollection.hpp
new file mode 100644
index 0000000..6f70f09
--- /dev/null
+++ b/EntityCollection.hpp
@@ -0,0 +1 @@
+#pragma once
diff --git a/game.cpp b/game.cpp
index c6fc277..0cad066 100644
--- a/game.cpp
+++ b/game.cpp
@@ -29,8 +29,10 @@ int main(int argc, char* argv[])
 		//TODO write something meaningful
 	}
 
-	GameClient client;
+	GameClient::createInstance();
 
+	GameClient& client = GameClient::createInstance();
+	
 	if(client.Construct(256, 240, 4, 4)){
 		client.Start();
 	}
diff --git a/mainGame.cpp b/mainGame.cpp
index d88e626..ea3b542 100644
--- a/mainGame.cpp
+++ b/mainGame.cpp
@@ -1,11 +1,32 @@
 #include "mainGame.h"
 #include "ResourceManager.h"
+#include <algorithm>
+
+const float maxTimeDelta = 0.05f;
+using namespace std;
+using namespace entities;
+
+GameClient& GameClient::createInstance()
+{
+	instance = new GameClient();
+	return *instance;
+}
 
 GameClient::GameClient()
 {
 	this->sAppName = "KosmX's game";
 }
 
+DynamicArray<std::shared_ptr<entities::Entity>>& GameClient::getEntities()
+{
+	return this->entities;
+}
+
+GameClient& GameClient::getInstance()
+{
+	return *instance;
+}
+
 bool GameClient::OnUserCreate()
 {
 
@@ -19,12 +40,12 @@ bool GameClient::OnUserCreate()
 
 bool GameClient::OnUserUpdate(float fElapsedTime)
 {
-
+	fElapsedTime = std::min(maxTimeDelta, fElapsedTime);
 	//return false if it want to exit.
-	return true;
-}
 
-GameClient::~GameClient()
-{
-	//TODO free anything
+	for(std::shared_ptr<Entity> entity : this->getEntities()){
+		entity->tick(*this, fElapsedTime);
+	}
+	
+	return true;
 }
diff --git a/mainGame.h b/mainGame.h
index 23ef574..dd138ab 100644
--- a/mainGame.h
+++ b/mainGame.h
@@ -9,15 +9,27 @@ class GameClient :
     public olc::PixelGameEngine
 {
 private:
-	DynamicArray<std::shared_ptr<entities::Entity>> basicEntities;
+	static GameClient* instance;
+	static GameClient& createInstance();
+	//I want it to me a singleton, but I don't want to let anything init this
+	friend int main(int, char* []);
+public:
+	static GameClient& getInstance();
+
+// real class stuff
+private:
+	DynamicArray<std::shared_ptr<entities::Entity>> entities;
+
+	
 public:
 	GameClient();
 
+	DynamicArray<std::shared_ptr<entities::Entity>>& getEntities();
+	
 	bool OnUserCreate() override;
 
 	bool OnUserUpdate(float fElapsedTime) override;
 
-	~GameClient();
 	
 	//for some reason, probably I won't need it
 	//bool OnUserDestroy() override;
-- 
GitLab