From d2499a67f833a21d4a398c162ddfa33dbce13536 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Fri, 24 Feb 2023 23:46:34 -0500 Subject: [PATCH] Porting in old gamejam code. Removed SOME cruft, more likely remains. Sound + sprite test. --- .gitignore | 1 + assets/boom.wav | Bin 0 -> 31088 bytes assets/kenney_tinydungeon.png | Bin 0 -> 5294 bytes build_linux.sh | 44 ++++- run_linux.sh | 2 +- src/ActionCode.h | 34 ++++ src/Button.cpp | 24 +++ src/Button.h | 28 ++++ src/Common.h | 10 ++ src/Components.h | 79 +++++++++ src/Entity.cpp | 25 +++ src/Entity.h | 32 ++++ src/EntityManager.cpp | 65 ++++++++ src/EntityManager.h | 25 +++ src/GameEngine.cpp | 96 +++++++++++ src/GameEngine.h | 31 ++++ src/MenuScene.cpp | 45 ++++++ src/MenuScene.h | 17 ++ src/Scene.cpp | 25 +++ src/Scene.h | 35 ++++ src/UIMenu.cpp | 48 ++++++ src/UIMenu.h | 32 ++++ src/UITestScene.cpp | 293 ++++++++++++++++++++++++++++++++++ src/UITestScene.h | 31 ++++ src/VectorShape.cpp | 48 ++++++ src/VectorShape.h | 16 ++ src/main.cpp | 8 + 27 files changed, 1090 insertions(+), 4 deletions(-) create mode 100644 assets/boom.wav create mode 100644 assets/kenney_tinydungeon.png create mode 100644 src/ActionCode.h create mode 100644 src/Button.cpp create mode 100644 src/Button.h create mode 100644 src/Common.h create mode 100644 src/Components.h create mode 100644 src/Entity.cpp create mode 100644 src/Entity.h create mode 100644 src/EntityManager.cpp create mode 100644 src/EntityManager.h create mode 100644 src/GameEngine.cpp create mode 100644 src/GameEngine.h create mode 100644 src/MenuScene.cpp create mode 100644 src/MenuScene.h create mode 100644 src/Scene.cpp create mode 100644 src/Scene.h create mode 100644 src/UIMenu.cpp create mode 100644 src/UIMenu.h create mode 100644 src/UITestScene.cpp create mode 100644 src/UITestScene.h create mode 100644 src/VectorShape.cpp create mode 100644 src/VectorShape.h create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore index 9bb5b95..20f0baf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ bin *.bak* PCbuild .vs +obj diff --git a/assets/boom.wav b/assets/boom.wav new file mode 100644 index 0000000000000000000000000000000000000000..b5ace4cba27548db088eb8f25e672b2b56621d8b GIT binary patch literal 31088 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 + +class ActionCode +{ +public: + enum CodeType { Key = 0, Mousebutton, Mousewheel }; + const static int KEY = 4096; + const static int MOUSEBUTTON = 8192; + const static int MOUSEWHEEL = 16384; + + const static int WHEEL_NUM = 4; + const static int WHEEL_NEG = 2; + const static int WHEEL_DEL = 1; + static int keycode(sf::Keyboard::Key& k) { return KEY + (int)k; } + static int keycode(sf::Mouse::Button& b) { return MOUSEBUTTON + (int)b; } + //static int keycode(sf::Mouse::Wheel& w, float d) { return MOUSEWHEEL + (((int)w)<<12) + int(d*16) + 512; } + static int keycode(sf::Mouse::Wheel& w, float d) { + int neg = 0; + if (d < 0) { neg = 1; } + return MOUSEWHEEL + (w * WHEEL_NUM) + (neg * WHEEL_NEG) + 1; + } + + static int key(int a) { return a & KEY; } + static int mouseButton(int a) { return a & MOUSEBUTTON; } + static bool isMouseWheel(int a) { return a & MOUSEWHEEL; } + //static int wheel(int a) { return a || MOUSEWHEEL >> 12; } + static int wheel(int a) { return (a & WHEEL_NUM) / WHEEL_NUM; } + //static float delta(int a) { return (a || MOUSEWHEEL || 2047) / 16.0f - 512; } + static int delta(int a) { + int factor = 1; + if (a & WHEEL_NEG) factor = -1; + return (a & WHEEL_DEL) * factor; + } +}; diff --git a/src/Button.cpp b/src/Button.cpp new file mode 100644 index 0000000..bb40fe5 --- /dev/null +++ b/src/Button.cpp @@ -0,0 +1,24 @@ +#include "Button.h" + +void Button::render(sf::RenderWindow & window) +{ + window.draw(rect); + window.draw(caption); +} + +Button::Button(int x, int y, int w, int h, + sf::Color _background, sf::Color _textcolor, + const char * _caption, sf::Font & font, + const char * _action) +{ + rect.setPosition(sf::Vector2f(x, y)); + rect.setSize(sf::Vector2f(w, h)); + rect.setFillColor(_background); + + caption.setFillColor(_textcolor); + caption.setPosition(sf::Vector2f(x, y)); + caption.setString(_caption); + caption.setFont(font); + + action = _action; +} diff --git a/src/Button.h b/src/Button.h new file mode 100644 index 0000000..c72bc08 --- /dev/null +++ b/src/Button.h @@ -0,0 +1,28 @@ +#pragma once + +#include "Common.h" + +class Button +{ + +protected: + sf::RectangleShape rect; + sf::Text caption; + std::string action; + +public: + Button() {}; + Button(int x, int y, int w, int h, + sf::Color _background, sf::Color _textcolor, + const char * _caption, sf::Font & font, + const char * _action); + void setPosition(sf::Vector2f v) { rect.setPosition(v); caption.setPosition(v); } + void setSize(sf::Vector2f & v) { rect.setSize(v); } + void setBackground(sf::Color c) { rect.setFillColor(c); } + void setCaption(std::string & s) { caption.setString(s); } + void setTextColor(sf::Color c) { caption.setFillColor(c); } + void render(sf::RenderWindow & window); + auto contains(sf::Vector2i p) { return rect.getGlobalBounds().contains(p.x, p.y); } + auto getAction() { return action; } +private: +}; diff --git a/src/Common.h b/src/Common.h new file mode 100644 index 0000000..91c777a --- /dev/null +++ b/src/Common.h @@ -0,0 +1,10 @@ +# pragma once +#include +#include + +#include +#include +#include +#include +#include +#include diff --git a/src/Components.h b/src/Components.h new file mode 100644 index 0000000..4f0603f --- /dev/null +++ b/src/Components.h @@ -0,0 +1,79 @@ +#pragma once + +#include "Common.h" + +/* +class CTransform +{ +public: + Vec2 pos = { 0.0, 0.0 }; + Vec2 velocity = { 0.0, 0.0 }; + float angle = 0; + + CTransform(const Vec2 & p, const Vec2 & v, float a) + : pos(p), velocity(v), angle(a) {} +}; +*/ + +class CShape +{ +public: + sf::CircleShape circle; + + CShape(float radius, int points, const sf::Color & fill, const sf::Color & outline, float thickness) + : circle(radius, points) + { + circle.setFillColor(fill); + circle.setOutlineColor(outline); + circle.setOutlineThickness(thickness); + circle.setOrigin(radius, radius); + } +}; + +class CCollision +{ +public: + float radius = 0; + CCollision(float r) + : radius(r) {} +}; + +class CScore +{ +public: + int score = 0; + CScore(int s) + : score(s) {} +}; + +class CLifespan +{ +public: + int remaining = 0; + int total = 0; + CLifespan(int t) + : remaining(t), total(t) {} +}; + +class CInput +{ +public: + bool up = false; + bool left = false; + bool right = false; + bool down = false; + bool fire = false; + + CInput() {} +}; + +class CSteer +{ +public: + sf::Vector2f position; + sf::Vector2f velocity; + float v_max; + float dv_max; + float theta_max; + float dtheta_max; +}; diff --git a/src/Entity.cpp b/src/Entity.cpp new file mode 100644 index 0000000..38ac1b7 --- /dev/null +++ b/src/Entity.cpp @@ -0,0 +1,25 @@ +#include "Entity.h" + +Entity::Entity(const size_t i, const std::string & t) + : m_id(i), m_tag(t) {} + +bool Entity::isActive() const +{ + return m_active; +} + +const std::string & Entity::tag() const +{ + return m_tag; +} + +const size_t Entity::id() const +{ + return m_id; +} + +void Entity::destroy() +{ + m_active = false; +} + diff --git a/src/Entity.h b/src/Entity.h new file mode 100644 index 0000000..d6b3c8f --- /dev/null +++ b/src/Entity.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Common.h" + +#include "Components.h" + +class Entity +{ + friend class EntityManager; + + bool m_active = true; + size_t m_id = 0; + std::string m_tag = "default"; + + //constructor and destructor + Entity(const size_t id, const std::string & t); + +public: + // component pointers + //std::shared_ptr cTransform; + std::shared_ptr cShape; + std::shared_ptr cCollision; + std::shared_ptr cInput; + std::shared_ptr cScore; + std::shared_ptr cLifespan; + + //private member access functions + bool isActive() const; + const std::string & tag() const; + const size_t id() const; + void destroy(); +}; diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp new file mode 100644 index 0000000..0a2eb01 --- /dev/null +++ b/src/EntityManager.cpp @@ -0,0 +1,65 @@ +#include "EntityManager.h" + +EntityManager::EntityManager() + :m_totalEntities(0) {} + +void EntityManager::update() +{ + //TODO: add entities from m_entitiesToAdd to all vector / tag map + removeDeadEntities(m_entities); + + // C++17 way of iterating! + for (auto& [tag, entityVec] : m_entityMap) + { + removeDeadEntities(entityVec); + } + + for (auto& e : m_entitiesToAdd) + { + m_entities.push_back(e); + m_entityMap[e->tag()].push_back(e); + } + //if (m_entitiesToAdd.size()) + // m_entitiesToAdd.erase(m_entitiesToAdd.begin(), m_entitiesToAdd.end()); + m_entitiesToAdd = EntityVec(); +} + +void EntityManager::removeDeadEntities(EntityVec & vec) +{ + EntityVec survivors; // New vector + for (auto& e : m_entities) + { + if (e->isActive()) survivors.push_back(e); // populate new vector + } + //std::cout << "All entities: " << m_entities.size() << " Survivors: " << survivors.size() << std::endl; + m_entities = survivors; // point to new vector + for (auto& [tag, entityVec] : m_entityMap) + { + EntityVec tag_survivors; // New vector + for (auto& e : m_entityMap[tag]) + { + if (e->isActive()) tag_survivors.push_back(e); // populate new vector + } + m_entityMap[tag] = tag_survivors; // point to new vector + //std::cout << tag << " entities: " << m_entityMap[tag].size() << " Survivors: " << tag_survivors.size() << std::endl; + } +} + +std::shared_ptr EntityManager::addEntity(const std::string & tag) +{ + // create the entity shared pointer + auto entity = std::shared_ptr(new Entity(m_totalEntities++, tag)); + m_entitiesToAdd.push_back(entity); + return entity; +} + +const EntityVec & EntityManager::getEntities() +{ + return m_entities; +} + +const EntityVec & EntityManager::getEntities(const std::string & tag) +{ + return m_entityMap[tag]; +} + diff --git a/src/EntityManager.h b/src/EntityManager.h new file mode 100644 index 0000000..744089e --- /dev/null +++ b/src/EntityManager.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Common.h" +#include "Entity.h" + +typedef std::vector> EntityVec; +typedef std::map EntityMap; + +class EntityManager +{ + EntityVec m_entities; + EntityVec m_entitiesToAdd; + EntityMap m_entityMap; + size_t m_totalEntities; + + void removeDeadEntities(EntityVec & vec); + +public: + EntityManager(); + void update(); + std::shared_ptr addEntity(const std::string & tag); + const EntityVec & getEntities(); + const EntityVec & getEntities(const std::string & tag); +}; + diff --git a/src/GameEngine.cpp b/src/GameEngine.cpp new file mode 100644 index 0000000..8c5db53 --- /dev/null +++ b/src/GameEngine.cpp @@ -0,0 +1,96 @@ +#include "GameEngine.h" +#include "MenuScene.h" +#include "UITestScene.h" +#include "ActionCode.h" + +GameEngine::GameEngine() +{ + font.loadFromFile("./assets/JetbrainsMono.ttf"); + window.create(sf::VideoMode(640, 480), "McRogueFace Engine by John McCardle"); + visible = window.getDefaultView(); + window.setFramerateLimit(30); + scene = "menu"; + //std::cout << "Constructing MenuScene" << std::endl; + scenes["menu"] = new MenuScene(this); + //std::cout << "Constructed MenuScene" <update(); + sUserInput(); + if (!paused) + { + } + currentScene()->sRender(); + currentFrame++; + } +} + +void GameEngine::sUserInput() +{ + sf::Event event; + while (window.pollEvent(event)) + { + std::string actionType; + int actionCode = 0; + + if (event.type == sf::Event::Closed) { running = false; continue; } + else if (event.type == sf::Event::Resized) { + sf::FloatRect area(0.f, 0.f, event.size.width, event.size.height); + visible = sf::View(area); + window.setView(visible); + std::cout << "Visible area set to (0, 0, " << event.size.width << ", " << event.size.height <<")"< " << (actionCode && ActionCode::WHEEL_NEG) << "; actionCode && WHEEL_DEL -> " << (actionCode && ActionCode::WHEEL_DEL) << ";" << std::endl; + */ + } + // float d = event.MouseWheelScrollEvent.delta; + // actionCode = ActionCode::keycode(0, d); + } + else + continue; + + //std::cout << "Event produced action code " << actionCode << ": " << actionType << std::endl; + + if (currentScene()->hasAction(actionCode)) + { + std::string name = currentScene()->action(actionCode); + currentScene()->doAction(name, actionType); + } + else + { + std::cout << "[GameEngine] Action not registered for input: " << actionCode << ": " << actionType << std::endl; + } + } +} diff --git a/src/GameEngine.h b/src/GameEngine.h new file mode 100644 index 0000000..11f6f64 --- /dev/null +++ b/src/GameEngine.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Common.h" +#include "Entity.h" +#include "EntityManager.h" +#include "Scene.h" + +class GameEngine +{ + sf::RenderWindow window; + sf::Font font; + std::string scene; + std::map scenes; + bool running = true; + bool paused = false; + int currentFrame = 0; + sf::View visible; + +public: + GameEngine(); + Scene* currentScene(); + void changeScene(std::string); + void quit(); + void setPause(bool); + sf::Font & getFont(); + sf::RenderWindow & getWindow(); + void run(); + void sUserInput(); + int getFrame() { return currentFrame; } + sf::View getView() { return visible; } +}; diff --git a/src/MenuScene.cpp b/src/MenuScene.cpp new file mode 100644 index 0000000..998b054 --- /dev/null +++ b/src/MenuScene.cpp @@ -0,0 +1,45 @@ +#include "MenuScene.h" +#include "ActionCode.h" + +MenuScene::MenuScene(GameEngine* g) : Scene(g) +{ + text.setFont(game->getFont()); + text.setString("McRogueFace Engine - Testing & Early Access"); + text.setCharacterSize(24); + //std::cout << "MenuScene Initialized. " << game << std::endl; + //std::cout << "Font: " << game->getFont().getInfo().family << std::endl; + + text2.setFont(game->getFont()); + text2.setString("Press 'Spacebar' to begin; 'Up' and 'Down' switch Resolution"); + text2.setCharacterSize(16); + text2.setPosition(0.0f, 50.0f); + + registerAction(ActionCode::KEY + sf::Keyboard::Space, "start_game"); + registerAction(ActionCode::KEY + sf::Keyboard::Up, "up"); + registerAction(ActionCode::KEY + sf::Keyboard::Down, "down"); +} + +void MenuScene::update() +{ + //std::cout << "MenuScene update" << std::endl; +} + +void MenuScene::doAction(std::string name, std::string type) +{ + //std::cout << "MenuScene doAction: " << name << ", " << type << std::endl; + //if (name.compare("start_game") == 0 and type.compare("start") == 0) + if(ACTION("start_game", "start")) + game->changeScene("play"); + else if(ACTIONONCE("up")) + game->getWindow().setSize(sf::Vector2u(1024, 768)); + else if(ACTIONONCE("down")) + game->getWindow().setSize(sf::Vector2u(640, 480)); +} + +void MenuScene::sRender() +{ + game->getWindow().clear(); + game->getWindow().draw(text); + game->getWindow().draw(text2); + game->getWindow().display(); +} diff --git a/src/MenuScene.h b/src/MenuScene.h new file mode 100644 index 0000000..70ec13f --- /dev/null +++ b/src/MenuScene.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Common.h" +#include "Scene.h" +#include "GameEngine.h" + +class MenuScene: public Scene +{ + sf::Text text; + sf::Text text2; + +public: + MenuScene(GameEngine*); + void update() override final; + void doAction(std::string, std::string) override final; + void sRender() override final; +}; diff --git a/src/Scene.cpp b/src/Scene.cpp new file mode 100644 index 0000000..a6e32ae --- /dev/null +++ b/src/Scene.cpp @@ -0,0 +1,25 @@ +#include "Scene.h" + +//Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;}; +Scene::Scene(GameEngine* g) { game = g; } +void Scene::registerAction(int code, std::string name) +{ + actions[code] = name; + actionState[name] = false; +} +bool Scene::hasAction(std::string name) +{ + for (auto& item : actions) + if (item.second == name) return true; + return false; +} + +bool Scene::hasAction(int code) +{ + return (actions.find(code) != actions.end()); +} + +std::string Scene::action(int code) +{ + return actions[code]; +} diff --git a/src/Scene.h b/src/Scene.h new file mode 100644 index 0000000..0eec797 --- /dev/null +++ b/src/Scene.h @@ -0,0 +1,35 @@ +#pragma once + +// macros for scene input +#define ACTION(X, Y) (name.compare(X) == 0 && type.compare(Y) == 0) +#define ACTIONONCE(X) ((name.compare(X) == 0 && type.compare("start") == 0 && !actionState[name])) + +#include "Common.h" +//#include "GameEngine.h" + +class GameEngine; // forward declare + +class Scene +{ +protected: + bool hasEnded = false; + bool paused = false; + std::map actions; + std::map actionState; + GameEngine* game; + + void simulate(int); + void registerAction(int, std::string); + + +public: + //Scene(); + Scene(GameEngine*); + virtual void update() = 0; + virtual void sRender() = 0; + virtual void doAction(std::string, std::string) = 0; + bool hasAction(std::string); + bool hasAction(int); + std::string action(int); + +}; diff --git a/src/UIMenu.cpp b/src/UIMenu.cpp new file mode 100644 index 0000000..c16452a --- /dev/null +++ b/src/UIMenu.cpp @@ -0,0 +1,48 @@ +#include "UIMenu.h" + +UIMenu::UIMenu(sf::Font & _font) +: font(_font) +{ + //font = _font; + box.setSize(sf::Vector2f(300, 400)); + box.setPosition(sf::Vector2f(300, 250)); + box.setFillColor(sf::Color(0,0,255)); +} + +void UIMenu::render(sf::RenderWindow & window) +{ + window.draw(box); + for (auto& c : captions) { + //auto s = std::string(c.getString()); + //std::cout << s << std::flush << std::endl; + window.draw(c); + } + for (auto& b : buttons) { b.render(window); } +} + +void UIMenu::refresh() +{ + +} + +void UIMenu::add_caption(const char* text, int tsize, sf::Color color) +{ + auto c = sf::Text(); + auto bpos = box.getPosition(); + + c.setFillColor(color); + c.setPosition(bpos.x + 10, bpos.y + next_text); + next_text += 50; + c.setCharacterSize(tsize); + c.setString(text); + c.setFont(font); + captions.push_back(c); + +} + +void UIMenu::add_button(Button b) +{ + b.setPosition(box.getPosition() + sf::Vector2f(box.getSize().x / 2.0f, next_button)); + next_button += 50; + buttons.push_back(b); +} diff --git a/src/UIMenu.h b/src/UIMenu.h new file mode 100644 index 0000000..1b2b0b1 --- /dev/null +++ b/src/UIMenu.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Common.h" +#include "Button.h" + +class UIMenu +{ +public: + //UIMenu() {}; + sf::Font & font; + UIMenu(sf::Font & _font); + std::vector captions; + std::vector