From ecb0cd17e6c63add6dde3be6dd0fbd52765a5138 Mon Sep 17 00:00:00 2001 From: KosmX <kosmx.mc@gmail.com> Date: Mon, 10 May 2021 23:32:26 +0200 Subject: [PATCH] some functor :D --- 2d-game.vcxproj | 7 +++++++ 2d-game.vcxproj.filters | 21 ++++++++++++++++++++ Entity.cpp | 5 +++++ Entity.h | 1 + MeleeWeapon.cpp | 35 +++++++++++++++++++++++++++++++++ MeleeWeapon.h | 31 +++++++++++++++++++++++++++++ SimpleSprite.h | 2 +- TypicalMeleeWeapon.cpp | 8 ++++++++ TypicalMeleeWeapon.h | 14 ++++++++++++++ Weapon.cpp | 25 ++++++++++++++++++++++++ Weapon.h | 43 +++++++++++++++++++++++++++++++++++++++++ WeaponTextures.cpp | 1 + WeaponTextures.h | 18 +++++++++++++++++ mainGame.cpp | 3 +-- 14 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 MeleeWeapon.cpp create mode 100644 MeleeWeapon.h create mode 100644 TypicalMeleeWeapon.cpp create mode 100644 TypicalMeleeWeapon.h create mode 100644 Weapon.cpp create mode 100644 Weapon.h create mode 100644 WeaponTextures.cpp create mode 100644 WeaponTextures.h diff --git a/2d-game.vcxproj b/2d-game.vcxproj index 41591cd..d7f0cac 100644 --- a/2d-game.vcxproj +++ b/2d-game.vcxproj @@ -151,12 +151,15 @@ <ClCompile Include="LazySprite.cpp" /> <ClCompile Include="LivingEntity.cpp" /> <ClCompile Include="mainGame.cpp" /> + <ClCompile Include="MeleeWeapon.cpp" /> <ClCompile Include="PlayerEntity.cpp" /> <ClCompile Include="ResourceManager.cpp" /> <ClCompile Include="SimpleSprite.cpp" /> <ClCompile Include="TestGenerator.cpp" /> + <ClCompile Include="TypicalMeleeWeapon.cpp" /> <ClCompile Include="WallEntity.cpp" /> <ClCompile Include="WallTexture.cpp" /> + <ClCompile Include="Weapon.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="CharacterTexture.h" /> @@ -165,6 +168,7 @@ <ClInclude Include="GameException.h" /> <ClInclude Include="LivingEntity.h" /> <ClInclude Include="mainGame.h" /> + <ClInclude Include="MeleeWeapon.h" /> <ClInclude Include="olc.h" /> <ClInclude Include="ITexture.h" /> <ClInclude Include="Entity.h" /> @@ -177,8 +181,11 @@ <ClInclude Include="ResourceManager.h" /> <ClInclude Include="SimpleSprite.h" /> <ClInclude Include="TestGenerator.h" /> + <ClInclude Include="TypicalMeleeWeapon.h" /> <ClInclude Include="WallEntity.h" /> <ClInclude Include="WallTexture.h" /> + <ClInclude Include="Weapon.h" /> + <ClInclude Include="WeaponTextures.h" /> </ItemGroup> <ItemGroup> <None Include="ClassDiagram.cd" /> diff --git a/2d-game.vcxproj.filters b/2d-game.vcxproj.filters index cbfe8f8..f679b0b 100644 --- a/2d-game.vcxproj.filters +++ b/2d-game.vcxproj.filters @@ -74,6 +74,15 @@ <ClCompile Include="PlayerEntity.cpp"> <Filter>Source Files\gameObj\entities</Filter> </ClCompile> + <ClCompile Include="Weapon.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MeleeWeapon.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TypicalMeleeWeapon.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="interfaces.h"> @@ -136,6 +145,18 @@ <ClInclude Include="PlayerEntity.h"> <Filter>Header Files\gameObj\entities</Filter> </ClInclude> + <ClInclude Include="Weapon.h"> + <Filter>Header Files\gameObj\entities</Filter> + </ClInclude> + <ClInclude Include="MeleeWeapon.h"> + <Filter>Header Files\gameObj\entities</Filter> + </ClInclude> + <ClInclude Include="WeaponTextures.h"> + <Filter>Header Files\gameObj</Filter> + </ClInclude> + <ClInclude Include="TypicalMeleeWeapon.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="README.md"> diff --git a/Entity.cpp b/Entity.cpp index 8f54a5c..e3c5da5 100644 --- a/Entity.cpp +++ b/Entity.cpp @@ -72,6 +72,11 @@ namespace entities { return this->is_alive; } + bool Entity::canBeRemoved() const + { + return this->isAlive(); //most times + } + } TransformedView& operator+=(TransformedView& scene, entities::Entity& entity) { diff --git a/Entity.h b/Entity.h index d35ed8f..fb76b98 100644 --- a/Entity.h +++ b/Entity.h @@ -31,6 +31,7 @@ namespace entities { [[nodiscard]] virtual olc::vf2d getPos() const; [[nodiscard]] virtual olc::vf2d getSize() const; [[nodiscard]] virtual bool isAlive() const; + [[nodiscard]] virtual bool canBeRemoved() const; virtual void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this){} diff --git a/MeleeWeapon.cpp b/MeleeWeapon.cpp new file mode 100644 index 0000000..a5dac50 --- /dev/null +++ b/MeleeWeapon.cpp @@ -0,0 +1,35 @@ +#include "MeleeWeapon.h" +#include "mainGame.h" + +namespace weapons { + int MeleeWeapon::getDamage() const + { + return this->baseDamage; + } + bool MeleeWeapon::damageEntity(std::shared_ptr<LivingEntity> user, std::shared_ptr<Entity>& victim) + { + return victim->damage(this->getDamage(), *victim); + } + bool MeleeWeapon::damageIf(std::shared_ptr<LivingEntity>& user, bool(*predicate)(std::shared_ptr<Entity> self, std::shared_ptr<Entity> other)) + { + bool bl = false; + for(auto& entity : GameClient::getInstance().getEntities()){ + if(entity != user && predicate(user, entity)){ + bl = damageEntity(user, entity) || bl; + } + } + return bl; + } + + bool MeleeWeapon::use(std::shared_ptr<LivingEntity> user) + { + if (this->cooldown != 0) return false; + this->cooldown = this->cooldownTime; + + } + bool MeleeWeapon::predicateDistance::operator()(std::shared_ptr<Entity> entity, std::shared_ptr<Entity> other) const + { + float d = (entity->getPos() - other->getPos()).mag(); + return d > minDistance && d <= maxDistance; + } +} \ No newline at end of file diff --git a/MeleeWeapon.h b/MeleeWeapon.h new file mode 100644 index 0000000..4e05fe2 --- /dev/null +++ b/MeleeWeapon.h @@ -0,0 +1,31 @@ +#pragma once +#include "Weapon.h" +#include <functional> + +namespace weapons { + class MeleeWeapon : + public Weapon + { + protected: + virtual int getDamage() const; + virtual bool damageEntity(std::shared_ptr<LivingEntity> user, std::shared_ptr<Entity>& victim); + virtual bool damageIf(std::shared_ptr<LivingEntity>& user, bool(*predicate)(std::shared_ptr<Entity> self, std::shared_ptr<Entity> other)); + //virtual bool(*getPredicator())(std::shared_ptr<Entity>, std::shared_ptr<Entity>) = 0; + virtual std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> getPredicator() = 0; + + /** + * Functor to predicate entity distance. + * You can also use lambda, if you want + */ + class predicateDistance + { + public: + float minDistance = 0; + float maxDistance = 5; + bool operator()(std::shared_ptr<Entity> entity, std::shared_ptr<Entity> other) const; + }; + + public: + bool use(std::shared_ptr<LivingEntity> user) override; + }; +} diff --git a/SimpleSprite.h b/SimpleSprite.h index ff6a816..4d50d4e 100644 --- a/SimpleSprite.h +++ b/SimpleSprite.h @@ -13,7 +13,7 @@ namespace render { const olc::vf2d uv, size; public: - SimpleSprite(const std::string& name, const olc::vi2d& pos, const olc::vf2d& size); + SimpleSprite(const std::string& name, const olc::vi2d& pos, const olc::vf2d& size = {16, 16}); void render(olc::TransformedView& scene, entities::Entity& entity) override; }; diff --git a/TypicalMeleeWeapon.cpp b/TypicalMeleeWeapon.cpp new file mode 100644 index 0000000..a17da52 --- /dev/null +++ b/TypicalMeleeWeapon.cpp @@ -0,0 +1,8 @@ +#include "TypicalMeleeWeapon.h" + +std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> weapons::TypicalMeleeWeapon::getPredicator() +{ + predicateDistance p; + p.maxDistance = this->maxRange; + return p; +} diff --git a/TypicalMeleeWeapon.h b/TypicalMeleeWeapon.h new file mode 100644 index 0000000..58fcbca --- /dev/null +++ b/TypicalMeleeWeapon.h @@ -0,0 +1,14 @@ +#pragma once +#include "MeleeWeapon.h" +namespace weapons { + class TypicalMeleeWeapon : + public MeleeWeapon + { + public: + static TypicalMeleeWeapon sword; + + protected: + float maxRange; + std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> getPredicator() override; + }; +} diff --git a/Weapon.cpp b/Weapon.cpp new file mode 100644 index 0000000..6bd82de --- /dev/null +++ b/Weapon.cpp @@ -0,0 +1,25 @@ +#include "Weapon.h" + +namespace weapons +{ + render::ITexture& Weapon::getTexture() + { + return this->texture; + } + + Weapon::Weapon(render::ITexture& texture, float cooldownTime, int damage, olc::vf2d pos) + : Entity(pos), texture(texture), cooldown(0), cooldownTime(cooldownTime), baseDamage(damage) {} + + bool Weapon::update(float dTick) + { + this->cooldown = std::max(this->cooldown - dTick, 0.f); + + return this->cooldown == 0.f; + } + + float Weapon::getCooldownBar() + { + return this->cooldown / this->cooldownTime; + } + +} \ No newline at end of file diff --git a/Weapon.h b/Weapon.h new file mode 100644 index 0000000..2a6d03b --- /dev/null +++ b/Weapon.h @@ -0,0 +1,43 @@ +#pragma once +#include "Entity.h" + +using namespace entities; //yes, I know, I'm using `using namespace` in a header + +namespace weapons { + /** + * You can throw it to the ground, this is why it's an entity. But it will be possible to use it. and shoot enemies. + * or projectiles. + */ + class Weapon : + public Entity + { + private: + render::ITexture& texture; + render::ITexture& getTexture() override; + protected: + float cooldown; + float cooldownTime; + int baseDamage; + public: + + Weapon(render::ITexture& texture, float cooldownTime, int damage = 10, olc::vf2d pos = { 0, 0 }); + + /** + * @return true, if can use + */ + virtual bool use(std::shared_ptr<LivingEntity> user) = 0; + + virtual bool update(float dTick); + + /** + * 0 - 1 cooldown, 1 is ready to use, more than one makes sense, + * like 2 charges + */ + virtual float getCooldownBar(); + + /** + * Secondary charge bar. for some purpose + */ + virtual float getSecondaryBar() { return 0; } + }; +} \ No newline at end of file diff --git a/WeaponTextures.cpp b/WeaponTextures.cpp new file mode 100644 index 0000000..97aebae --- /dev/null +++ b/WeaponTextures.cpp @@ -0,0 +1 @@ +#include "WeaponTextures.h" \ No newline at end of file diff --git a/WeaponTextures.h b/WeaponTextures.h new file mode 100644 index 0000000..cc62346 --- /dev/null +++ b/WeaponTextures.h @@ -0,0 +1,18 @@ +#include "SimpleSprite.h" + +namespace weapons +{ + namespace textures + { + render::SimpleSprite sword1("Items/LongWep.png", { 0, 16 }); + render::SimpleSprite sword2("Items/LongWep.png", { 32, 16 }); + render::SimpleSprite spear("Items/LongWep.png", { 0, 32 }); + render::SimpleSprite scythe("Items/LongWep.png", { 16 * 3, 16 * 4 }); + render::SimpleSprite shovel("Items/LongWep.png", { 16 * 4, 16 * 4 }); //spoon + render::SimpleSprite pickaxe("Items/ShortWep.png", { 16 * 2, 16 * 3 }); + render::SimpleSprite bow("Items/Ammo.png", { 0, 16 }); + render::SimpleSprite crystalBow("Items/Ammo.png", { 48, 16 }); + render::SimpleSprite rifle("Items/Ammo.png", { 16, 64 }); + render::SimpleSprite photoMachine("Items/Light.png", { 16 * 6, 0 });//flash + } +} diff --git a/mainGame.cpp b/mainGame.cpp index 5c3678d..87c9dcc 100644 --- a/mainGame.cpp +++ b/mainGame.cpp @@ -57,7 +57,6 @@ bool GameClient::OnUserCreate() bool GameClient::OnUserUpdate(float fElapsedTime) { - fElapsedTime = std::min(maxTimeDelta, fElapsedTime); //return false if it want to exit. @@ -75,7 +74,7 @@ bool GameClient::OnUserUpdate(float fElapsedTime) //lambda remove condition. because why not? entities.removeIf([](const shared_ptr<Entity>& entity)->bool { - return !entity->isAlive(); + return !entity->canBeRemoved(); }); this->updateWorldOffset(fElapsedTime); -- GitLab