splitted skilltree

master
nihonium 2 years ago
parent 611dca5dcc
commit 06377bd12a
No known key found for this signature in database
GPG Key ID: 0251623741027CFC

@ -5,7 +5,7 @@ project(skilltree)
find_package(SFML 2.5 REQUIRED graphics window system)
# Создадим исполняемый файл по имени player_movement из исходных файлов
add_executable(skilltree src/skilltree.cpp)
add_executable(skilltree src/skilltree.cpp src/node.cpp)
# Укажем, что нужно использовать стандарт C++20
target_compile_features(skilltree PRIVATE cxx_std_20)

@ -0,0 +1,241 @@
#include "node.hpp"
Node::Node(sf::Vector2f& position) : mPosition{position} {}
void Node::addChild(const std::shared_ptr<Node>& child)
{
mChildren.push_back(child);
}
sf::Vector2f Node::getPosition()
{
return mPosition;
}
void Node::unblock()
{
mState = State::Unblocked;
}
void Node::block()
{
mState = State::Blocked;
for (const auto& child : mChildren)
child->block();
}
void Node::onMousePressed(sf::Vector2f mouseCoords)
{
if (mState == State::Blocked)
return;
if (collisionTest(mouseCoords))
{
if (mState == State::Unblocked)
{
mState = State::Activated;
for (const auto& child : mChildren)
child->unblock();
}
else if (mState == State::Activated)
{
mState = State::Unblocked;
for (const auto& child : mChildren)
child->block();
}
}
for (const auto& child : mChildren)
{
child->onMousePressed(mouseCoords);
}
}
/* HitNode */
HitNode::HitNode(sf::Vector2f position) : Node{position} {}
void HitNode::loadTexture()
{
sf::String texturePath = getIconPath();
if (!mTexture.loadFromFile(texturePath))
{
cout << "Error! Can't load file " << texturePath.toAnsiString() << endl;
std::exit(1);
}
mSprite.setTexture(mTexture);
mSprite.setOrigin({mRadius, mRadius});
mSprite.setPosition(mPosition);
}
sf::Color HitNode::getCurrentColor() const
{
if (mState == State::Unblocked)
return sUnlockedColor;
else if (mState == State::Activated)
return sActivatedColor;
return sBlockedColor;
}
void HitNode::draw(sf::RenderWindow& window) const
{
for (const auto& el : mChildren)
{
sfLine connectionLine {mPosition, el->getPosition(), getCurrentColor(), 2};
connectionLine.draw(window);
el->draw(window);
}
static sf::CircleShape shape(mRadius);
shape.setOrigin({mRadius, mRadius});
shape.setFillColor(getCurrentColor());
shape.setPosition(mPosition);
window.draw(shape);
window.draw(mSprite);
}
bool HitNode::collisionTest(sf::Vector2f mouseCoords)
{
sf::Vector2f d = mPosition - mouseCoords;
return d.x * d.x + d.y * d.y < mRadius * mRadius;
}
/* BombSkillNode */
BombSkillNode::BombSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String BombSkillNode::getIconPath()
{
return sf::String{"icons/icon_bomb.png"};
}
/* SpikesSkillNode */
SpikesSkillNode::SpikesSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String SpikesSkillNode::getIconPath()
{
return sf::String{"icons/icon_spikes.png"};
}
/* LightningSkillNode */
LightningSkillNode::LightningSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String LightningSkillNode::getIconPath()
{
return sf::String{"icons/icon_lightning.png"};
}
/* EyeSkillNode */
EyeSkillNode::EyeSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String EyeSkillNode::getIconPath()
{
return sf::String{"icons/icon_eye.png"};
}
/* ClawsSkillNode */
ClawsSkillNode::ClawsSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String ClawsSkillNode::getIconPath()
{
return sf::String{"icons/icon_claws.png"};
}
/* ShieldSkillNode */
ShieldSkillNode::ShieldSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String ShieldSkillNode::getIconPath()
{
return sf::String{"icons/icon_shield.png"};
}
/* SwordSkillNode */
SwordSkillNode::SwordSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String SwordSkillNode::getIconPath()
{
return sf::String{"icons/icon_sword.png"};
}
/* ShurikenSkillNode */
ShurikenSkillNode::ShurikenSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String ShurikenSkillNode::getIconPath()
{
return sf::String{"icons/icon_shuriken.png"};
}
/* WindSkillNode */
WindSkillNode::WindSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String WindSkillNode::getIconPath()
{
return sf::String{"icons/icon_shuriken.png"};
}
/* MeteoriteSkillNode */
MeteoriteSkillNode::MeteoriteSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String MeteoriteSkillNode::getIconPath()
{
return sf::String{"icons/icon_meteorite.png"};
}
/* HandSkillNode */
HandSkillNode::HandSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String HandSkillNode::getIconPath()
{
return sf::String{"icons/icon_hand.png"};
}
/* EarthquakeSkillNode */
EarthquakeSkillNode::EarthquakeSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String EarthquakeSkillNode::getIconPath()
{
return sf::String{"icons/icon_earthquake.png"};
}

@ -0,0 +1,165 @@
#include <SFML/Graphics.hpp>
#include <cmath>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include "sfline.hpp"
using std::cout, std::endl;
class Node
{
public:
Node(sf::Vector2f& position);
enum class State
{
Blocked,
Unblocked,
Activated
};
void addChild(const std::shared_ptr<Node>& child);
sf::Vector2f getPosition();
void unblock();
void block();
virtual bool collisionTest(sf::Vector2f mouseCoords) = 0;
void onMousePressed(sf::Vector2f mouseCoords);
virtual void draw(sf::RenderWindow& window) const = 0;
protected:
sf::Vector2f mPosition {0, 0};
State mState = State::Blocked;
std::vector<std::shared_ptr<Node>> mChildren {};
inline static sf::Color sBlockedColor {40, 40, 40};
inline static sf::Color sUnlockedColor {80, 80, 40};
inline static sf::Color sActivatedColor {160, 160, 40};
};
class HitNode : public Node
{
public:
HitNode(sf::Vector2f position);
virtual sf::String getIconPath() = 0;
void loadTexture();
sf::Color getCurrentColor() const;
void draw(sf::RenderWindow& window) const;
bool collisionTest(sf::Vector2f mouseCoords) override;
private:
sf::Texture mTexture;
sf::Sprite mSprite;
float mRadius = 24;
bool mIsActivated = false;
};
class BombSkillNode : public HitNode
{
public:
BombSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class SpikesSkillNode : public HitNode
{
public:
SpikesSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class LightningSkillNode : public HitNode
{
public:
LightningSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class EyeSkillNode : public HitNode
{
public:
EyeSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class ClawsSkillNode : public HitNode
{
public:
ClawsSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class ShieldSkillNode : public HitNode
{
public:
ShieldSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class SwordSkillNode : public HitNode
{
public:
SwordSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class ShurikenSkillNode : public HitNode
{
public:
ShurikenSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class WindSkillNode : public HitNode
{
public:
WindSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class MeteoriteSkillNode : public HitNode
{
public:
MeteoriteSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class HandSkillNode : public HitNode
{
public:
HandSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};
class EarthquakeSkillNode : public HitNode
{
public:
EarthquakeSkillNode(sf::Vector2f position);
sf::String getIconPath() override;
};

@ -4,345 +4,11 @@
#include <string>
#include <memory>
#include "sfline.hpp"
#include "node.hpp"
#include <iostream>
using std::cout, std::endl;
/*
Icons from Ken111
https://www.flaticon.com/ru/packs/game-skill?k=1650700359068
*/
class Node
{
public:
Node(sf::Vector2f& position)
: mPosition{position}
{
}
enum class State
{
Blocked,
Unblocked,
Activated
};
void addChild(const std::shared_ptr<Node>& child)
{
mChildren.push_back(child);
}
sf::Vector2f getPosition()
{
return mPosition;
}
void unblock()
{
mState = State::Unblocked;
}
void block()
{
mState = State::Blocked;
for (const auto& child : mChildren)
child->block();
}
virtual bool collisionTest(sf::Vector2f mouseCoords) = 0;
void onMousePressed(sf::Vector2f mouseCoords)
{
if (mState == State::Blocked)
return;
if (collisionTest(mouseCoords))
{
if (mState == State::Unblocked)
{
mState = State::Activated;
for (const auto& child : mChildren)
child->unblock();
}
else if (mState == State::Activated)
{
mState = State::Unblocked;
for (const auto& child : mChildren)
child->block();
}
}
for (const auto& child : mChildren)
{
child->onMousePressed(mouseCoords);
}
}
virtual void draw(sf::RenderWindow& window) const = 0;
protected:
sf::Vector2f mPosition {0, 0};
State mState = State::Blocked;
std::vector<std::shared_ptr<Node>> mChildren {};
inline static sf::Color sBlockedColor {40, 40, 40};
inline static sf::Color sUnlockedColor {80, 80, 40};
inline static sf::Color sActivatedColor {160, 160, 40};
};
class HitNode : public Node
{
public:
HitNode(sf::Vector2f position)
: Node{position}
{
}
virtual sf::String getIconPath() = 0;
void loadTexture()
{
sf::String texturePath = getIconPath();
if (!mTexture.loadFromFile(texturePath))
{
cout << "Error! Can't load file " << texturePath.toAnsiString() << endl;
std::exit(1);
}
mSprite.setTexture(mTexture);
mSprite.setOrigin({mRadius, mRadius});
mSprite.setPosition(mPosition);
}
sf::Color getCurrentColor() const
{
if (mState == State::Unblocked)
return sUnlockedColor;
else if (mState == State::Activated)
return sActivatedColor;
return sBlockedColor;
}
void draw(sf::RenderWindow& window) const
{
for (const auto& el : mChildren)
{
sfLine connectionLine {mPosition, el->getPosition(), getCurrentColor(), 2};
connectionLine.draw(window);
el->draw(window);
}
static sf::CircleShape shape(mRadius);
shape.setOrigin({mRadius, mRadius});
shape.setFillColor(getCurrentColor());
shape.setPosition(mPosition);
window.draw(shape);
window.draw(mSprite);
}
bool collisionTest(sf::Vector2f mouseCoords) override
{
sf::Vector2f d = mPosition - mouseCoords;
return d.x * d.x + d.y * d.y < mRadius * mRadius;
}
private:
sf::Texture mTexture;
sf::Sprite mSprite;
float mRadius = 24;
bool mIsActivated = false;
};
class BombSkillNode : public HitNode
{
public:
BombSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_bomb.png"};
}
};
class SpikesSkillNode : public HitNode
{
public:
SpikesSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_spikes.png"};
}
};
class LightningSkillNode : public HitNode
{
public:
LightningSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_lightning.png"};
}
};
class EyeSkillNode : public HitNode
{
public:
EyeSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_eye.png"};
}
};
class ClawsSkillNode : public HitNode
{
public:
ClawsSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_claws.png"};
}
};
class ShieldSkillNode : public HitNode
{
public:
ShieldSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_shield.png"};
}
};
class SwordSkillNode : public HitNode
{
public:
SwordSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_sword.png"};
}
};
class ShurikenSkillNode : public HitNode
{
public:
ShurikenSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_shuriken.png"};
}
};
class WindSkillNode : public HitNode
{
public:
WindSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_shuriken.png"};
}
};
class MeteoriteSkillNode : public HitNode
{
public:
MeteoriteSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_meteorite.png"};
}
};
class HandSkillNode : public HitNode
{
public:
HandSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_hand.png"};
}
};
class EarthquakeSkillNode : public HitNode
{
public:
EarthquakeSkillNode(sf::Vector2f position) : HitNode{position}
{
loadTexture();
}
sf::String getIconPath() override
{
return sf::String{"icons/icon_earthquake.png"};
}
};
std::shared_ptr<Node> createSkillTree()
{
std::shared_ptr<Node> root {new LightningSkillNode({400, 500})};