Porting in old gamejam code. Removed SOME cruft, more likely remains. Sound + sprite test.

This commit is contained in:
John McCardle 2023-02-24 23:46:34 -05:00
parent 1784489dfb
commit d2499a67f8
27 changed files with 1090 additions and 4 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@ bin
*.bak* *.bak*
PCbuild PCbuild
.vs .vs
obj

BIN
assets/boom.wav Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -2,6 +2,8 @@
#rm -R bin/linux #rm -R bin/linux
mkdir -p bin/linux/lib mkdir -p bin/linux/lib
mkdir -p obj
rm obj/*
# copy shared objects, squish "linux" subdirectory in bin/linux/lib # copy shared objects, squish "linux" subdirectory in bin/linux/lib
#cp -R lib/linux/* bin/linux/lib #cp -R lib/linux/* bin/linux/lib
@ -15,13 +17,48 @@ cp -R src/scripts bin/linux/scripts
# work from output directory and change every g++ path to relative D:< # work from output directory and change every g++ path to relative D:<
cd bin/linux cd bin/linux
# prepare object files of engine classes
abort_compile()
{
echo "Compilation failed on $fn.cpp"
exit 1
}
# Precompile engine classes. Get errors in their file, not where they're included
for fn in $(ls ../../src/*.cpp -1 | cut -d/ -f4 | cut -d. -f1)
do
# Skip combined_poc.cpp, it has a duplicate main
if [ "$fn" = "combined_poc" ]; then continue; fi
echo "Compile $fn.cpp"
g++ \
-I../../deps_linux \
-I../../deps_linux/Python-3.11.1 \
-I../../platform/linux \
--std=c++17 \
-c ../../src/$fn.cpp \
-o ../../obj/$fn.o \
-lm \
-ldl \
-lutil \
-lpthread \
-lpython3.11 \
-lsfml-graphics \
-lsfml-window \
-lsfml-system \
-lsfml-audio \
-ltcod \
|| abort_compile $fn
done
# Final executable
g++ \ g++ \
--std=c++17 \ --std=c++17 \
-I../../deps_linux \ -I../../deps_linux \
-I../../deps_linux/Python-3.11.1 \ -I../../deps_linux/Python-3.11.1 \
-I../../platform/linux \ -I../../platform/linux \
../../src/combined_poc.cpp \ ../../obj/*.o \
-o poc \ -o mcrogueface \
-Wl,-rpath lib \ -Wl,-rpath lib \
-L../../deps_linux \ -L../../deps_linux \
-lm \ -lm \
@ -32,5 +69,6 @@ g++ \
-lsfml-graphics \ -lsfml-graphics \
-lsfml-window \ -lsfml-window \
-lsfml-system \ -lsfml-system \
-ltcod -lsfml-audio \
-ltcod \

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
cd bin/linux cd bin/linux
./poc ./mcrogueface

34
src/ActionCode.h Normal file
View File

@ -0,0 +1,34 @@
#include <SFML/Window/Keyboard.hpp>
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;
}
};

24
src/Button.cpp Normal file
View File

@ -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;
}

28
src/Button.h Normal file
View File

@ -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:
};

10
src/Common.h Normal file
View File

@ -0,0 +1,10 @@
# pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
#include <memory>
#include <fstream>
#include <sstream>
#include <algorithm>

79
src/Components.h Normal file
View File

@ -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;
};

25
src/Entity.cpp Normal file
View File

@ -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;
}

32
src/Entity.h Normal file
View File

@ -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> cTransform;
std::shared_ptr<CShape> cShape;
std::shared_ptr<CCollision> cCollision;
std::shared_ptr<CInput> cInput;
std::shared_ptr<CScore> cScore;
std::shared_ptr<CLifespan> cLifespan;
//private member access functions
bool isActive() const;
const std::string & tag() const;
const size_t id() const;
void destroy();
};

65
src/EntityManager.cpp Normal file
View File

@ -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<Entity> EntityManager::addEntity(const std::string & tag)
{
// create the entity shared pointer
auto entity = std::shared_ptr<Entity>(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];
}

25
src/EntityManager.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include "Common.h"
#include "Entity.h"
typedef std::vector<std::shared_ptr<Entity>> EntityVec;
typedef std::map<std::string, EntityVec> 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<Entity> addEntity(const std::string & tag);
const EntityVec & getEntities();
const EntityVec & getEntities(const std::string & tag);
};

96
src/GameEngine.cpp Normal file
View File

@ -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" <<std::endl;
scenes["play"] = new UITestScene(this);
}
Scene* GameEngine::currentScene() { return scenes[scene]; }
void GameEngine::changeScene(std::string s) { scene = s; }
void GameEngine::quit() { running = false; }
void GameEngine::setPause(bool p) { paused = p; }
sf::Font & GameEngine::getFont() { return font; }
sf::RenderWindow & GameEngine::getWindow() { return window; }
void GameEngine::run()
{
while (running)
{
currentScene()->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 <<")"<<std::endl;
actionType = "resize";
}
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseWheelScrolled) actionType = "start";
else if (event.type == sf::Event::KeyReleased || event.type == sf::Event::MouseButtonReleased) actionType = "end";
if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
actionCode = ActionCode::keycode(event.mouseButton.button);
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
actionCode = ActionCode::keycode(event.key.code);
else if (event.type == sf::Event::MouseWheelScrolled)
{
// //sf::Mouse::Wheel w = event.MouseWheelScrollEvent.wheel;
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
{
int delta = 1;
if (event.mouseWheelScroll.delta < 0) delta = -1;
actionCode = ActionCode::keycode(event.mouseWheelScroll.wheel, delta );
/*
std::cout << "[GameEngine] Generated MouseWheel code w(" << (int)event.mouseWheelScroll.wheel << ") d(" << event.mouseWheelScroll.delta << ") D(" << delta << ") = " << actionCode << std::endl;
std::cout << " test decode: isMouseWheel=" << ActionCode::isMouseWheel(actionCode) << ", wheel=" << ActionCode::wheel(actionCode) << ", delta=" << ActionCode::delta(actionCode) << std::endl;
std::cout << " math test: actionCode && WHEEL_NEG -> " << (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;
}
}
}

31
src/GameEngine.h Normal file
View File

@ -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<std::string, Scene*> 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; }
};

45
src/MenuScene.cpp Normal file
View File

@ -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();
}

17
src/MenuScene.h Normal file
View File

@ -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;
};

25
src/Scene.cpp Normal file
View File

@ -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];
}

35
src/Scene.h Normal file
View File

@ -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<int, std::string> actions;
std::map<std::string, bool> 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);
};

48
src/UIMenu.cpp Normal file
View File

@ -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);
}

32
src/UIMenu.h Normal file
View File

@ -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<sf::Text> captions;
std::vector<Button> buttons;
sf::RectangleShape box;
bool visible = false;
int next_text = 10;
int next_button = 10;
void render(sf::RenderWindow & window);
void refresh();
void add_caption(const char* text, int size, sf::Color color);
void add_button(Button b);
protected:
private:
};

293
src/UITestScene.cpp Normal file
View File

@ -0,0 +1,293 @@
#include "UITestScene.h"
#include "ActionCode.h"
#include <math.h>
sf::Texture texture;
int texture_index = 0;
const int texture_size = 16, texture_width = 12, texture_height = 11;
const int texture_sprite_count = texture_width * texture_height;
sf::Sprite test_sprite;
sf::SoundBuffer buffer;
sf::Sound sound;
void setSpriteTexture(int ti)
{
int tx = ti % texture_width, ty = ti / texture_width;
test_sprite.setTextureRect(sf::IntRect(tx * texture_size, ty * texture_size, texture_size, texture_size));
}
UITestScene::UITestScene(GameEngine* g)
: Scene(g)
{
// demo sprites from texture file
texture.loadFromFile("./assets/kenney_tinydungeon.png");
texture.setSmooth(false);
// Show one texture at a time
test_sprite.setTexture(texture);
test_sprite.setPosition(sf::Vector2f(50.0f, 50.0f));
test_sprite.setScale(sf::Vector2f(4.0f, 4.0f));
setSpriteTexture(0);
// Load sound
buffer.loadFromFile("./assets/boom.wav");
sound.setBuffer(buffer);
viewport = game->getView(); // scrolling view is identical to start
resolution = viewport.getSize();
text.setFont(game->getFont());
text.setString("Test");
text.setCharacterSize(16);
registerAction(ActionCode::KEY + sf::Keyboard::Num1, "show1");
registerAction(ActionCode::KEY + sf::Keyboard::Num2, "show2");
registerAction(ActionCode::KEY + sf::Keyboard::Num3, "show3");
registerAction(ActionCode::MOUSEBUTTON + sf::Mouse::Left, "click");
registerAction(ActionCode::KEY + sf::Keyboard::Left, "left");
registerAction(ActionCode::KEY + sf::Keyboard::Right, "right");
registerAction(ActionCode::KEY + sf::Keyboard::Up, "up");
registerAction(ActionCode::KEY + sf::Keyboard::Down, "down");
registerAction(ActionCode::KEY + sf::Keyboard::Comma, "zoom_down");
registerAction(ActionCode::KEY + sf::Keyboard::Period, "zoom_up");
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_DEL, "wheel_up");
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_NEG + ActionCode::WHEEL_DEL, "wheel_down");
registerAction(ActionCode::KEY + sf::Keyboard::Num4, "sound_test");
registerAction(0, "event");
UIMenu test_menu(game->getFont());
UIMenu test_menu2(game->getFont());
test_menu.visible = false;
test_menu.box.setSize(sf::Vector2f(350, 200));
test_menu.add_caption("debug to stdout", 16, sf::Color(255, 255, 0));
test_menu.add_button(Button(0, 0, 130, 40, sf::Color(0, 0, 192), sf::Color(0,0,0), "view", game->getFont(), "showviewport"));
test_menu2.visible = true;
test_menu2.box.setPosition(150, 180);
test_menu2.box.setFillColor(sf::Color(255, 0, 0));
test_menu2.add_caption("1: show UI 1 (this)", 18, sf::Color(255, 255, 0));
test_menu2.add_caption("2: show UI 2", 18, sf::Color(255, 255, 0));
test_menu2.add_caption("3: hide UIs", 18, sf::Color(255, 255, 0));
test_menu2.add_caption("> and <: zoom", 18, sf::Color(255, 255, 0));
test_menu2.add_caption("arrows: pan", 18, sf::Color(255, 255, 0));
test_menu2.add_caption("click: turn (buggy)", 18, sf::Color(255, 255, 0));
test_menu2.next_button += 100;
menus.push_back(test_menu);
menus.push_back(test_menu2);
test_ship.miner();
test_ship.angle = 180.0;
test_ship.position.x = 250;
test_ship.position.y = 120;
//std::cout << menus.size() << std::endl;
}
void UITestScene::update()
{
if (abs(desired_angle - test_ship.angle) < 1)
{
test_ship.angle = desired_angle;
} else if (test_ship.angle < desired_angle)
{
test_ship.angle += 1;
} else if (test_ship.angle > desired_angle){
test_ship.angle -= 1;
}
entities.update();
// All fixed vector movement
for (auto e : entities.getEntities())
{
//if(e->cPython) e->cPython->update();
//e->cTransform->pos += e->cTransform->velocity;
//e->cShape->circle.setPosition(e->cTransform->pos.x, e->cTransform->pos.y);
}
}
void UITestScene::doButton(std::string b_action)
{
if (!b_action.compare("showviewport"))
{
std::cout << viewport.getSize().x << ", " << viewport.getSize().y << ": "
<< viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl;
}
}
void UITestScene::doAction(std::string name, std::string type)
{
if (ACTIONONCE("show1"))
{
menus[0].visible = false;
menus[1].visible = true;
}
if (ACTIONONCE("show2"))
{
menus[0].visible = true;
menus[1].visible = false;
}
if (ACTIONONCE("show3"))
{
menus[0].visible = false;
menus[1].visible = false;
}
if (ACTIONONCE("click"))
{
auto mousepos = sf::Mouse::getPosition(game->getWindow());
bool ui_clicked = false;
for ( auto ui : menus)
{
if (!ui.visible) continue;
for (auto b : ui.buttons)
{
if (b.contains(mousepos)) {
std::cout << b.getAction() << std::endl;
doButton(b.getAction());
ui_clicked = true;
}
}
}
if (!ui_clicked) {
auto mousepos = sf::Mouse::getPosition(game->getWindow());
auto worldpos = game->getWindow().mapPixelToCoords(mousepos, viewport);
desired_angle = atan((1.0f * worldpos.y) / worldpos.x) * 180 / 3.14159 + 90.0f;
//std::cout << (1.0f * worldpos.y) / worldpos.x << " -> " << desired_angle << std::endl;
}
}
if (ACTION("wheel_up", "start")) {
texture_index++;
if (texture_index >= texture_sprite_count) texture_index = 0;
setSpriteTexture(texture_index);
std::string caption = "Texture index: ";
caption += std::to_string(texture_index);
text.setString(caption);
}
if (ACTION("wheel_down", "start")) {
texture_index--;
if (texture_index < 0) texture_index = texture_sprite_count - 1;
setSpriteTexture(texture_index);
std::string caption = "Texture index: ";
caption += std::to_string(texture_index);
text.setString(caption);
}
if (ACTION("sound_test", "start")) { sound.play(); }
if (ACTION("left", "start")) { viewport.move(-10, 0); }
if (ACTION("right", "start")) { viewport.move(10, 0); }
if (ACTION("up", "start")) { viewport.move(0, -10); }
if (ACTION("down", "start")) { viewport.move(0, 10); }
if (ACTION("down", "start")) { viewport.move(0, 10); }
if (ACTION("zoom_down", "start")) { if (zoom > 0.2f) zoom -= 0.1f; viewport.zoom(zoom); }
if (ACTION("zoom_up", "start")) { if (zoom < 10.0f) zoom += 0.1f; viewport.zoom(zoom); }
//std::cout << "viewport: " << viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl;
if (type.compare("resize")) // get center coordinate from game coordinate viewport, apply to new window viewport, restore zoom level
{
auto center = viewport.getCenter();
//auto w = viewport.getSize().x;
//auto h = viewport.getSize().y;
viewport = game->getView();
viewport.setCenter(center);
viewport.zoom(zoom);
}
// after processing: set actionState
if (type.compare("start") == 0 && !actionState[name]) { actionState[name] = true; }
else if (type.compare("end") == 0 && actionState[name]) { actionState[name] = false; }
}
void UITestScene::sRender()
{
game->getWindow().clear();
// Scrolling Viewport Objects (under the UI) --- entities, etc.
game->getWindow().setView(viewport);
int width = viewport.getSize().x;
int height = viewport.getSize().y;
int top = viewport.getCenter().y - (height/2);
int left = viewport.getCenter().x - (width/2);
int vline_count = height / grid_spacing * 2;
sf::VertexArray v_lines(sf::Lines, vline_count*2);
int index = 0;
for (int x = left - (left % grid_spacing); index < vline_count*2; x += grid_spacing)
{
v_lines[index] = sf::Vector2f(x, top);
v_lines[index + 1] = sf::Vector2f(x, top+height);
v_lines[index].color = sf::Color(0, 40, 0);
v_lines[index + 1].color = sf::Color(0, 40, 0);
index += 2;
}
game->getWindow().draw(v_lines);
int hline_count = width / grid_spacing * 2;
sf::VertexArray h_lines(sf::Lines, hline_count*2);
//std::cout << "Width: " << v.width << " Lines:" << vline_count <<
// " Point array length: " << vline_count * 2 << std::endl;
index = 0;
for (int y = top - (top % grid_spacing); index < hline_count * 2; y += grid_spacing)
{
//std::cout << "(" << v.left << ", " << y << ") -> " << "(" << v.left + v.width << ", " << y << ")" << std::endl;
h_lines[index] = sf::Vector2f(left, y);
h_lines[index + 1] = sf::Vector2f(left+width, y);
h_lines[index].color = sf::Color(0, 40, 0);
h_lines[index + 1].color = sf::Color(0, 40, 0);
index += 2;
}
game->getWindow().draw(h_lines);
/*for (int i = 0; i < total_lines; i++)
{
sf::Vertex p = lines[i];
std::cout << p.position.x << ", " << p.position.y << std::endl;
}*/
for (auto e : entities.getEntities())
{
//game->getWindow().draw(e->cShape->circle);
}
test_ship.render(game->getWindow());
// Fixed position objects
game->getWindow().setView(game->getView());
game->getWindow().draw(text);
//test_button.render(game->getWindow());
//if (test_menu.visible) test_menu.render(game->getWindow());
//if (test_menu2.visible) test_menu2.render(game->getWindow());
for ( auto ui : menus)
{
//std::cout << ui.buttons[0].getAction() << std::endl;
if (!ui.visible) continue;
ui.render(game->getWindow());
}
// draw test sprite on top of everything
game->getWindow().draw(test_sprite);
game->getWindow().display();
}

31
src/UITestScene.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include "Common.h"
#include "Scene.h"
#include "GameEngine.h"
#include "Button.h"
#include "UIMenu.h"
#include "VectorShape.h"
class UITestScene: public Scene
{
sf::Text text;
EntityManager entities;
//Button test_button;
//UIMenu test_menu;
//UIMenu test_menu2;
std::vector<UIMenu> menus;
VectorShape test_ship;
float desired_angle = 0;
sf::View viewport;
float zoom = 1;
sf::Vector2f resolution;
int grid_spacing = 500;
public:
UITestScene(GameEngine*);
void update() override final;
void doAction(std::string, std::string) override final;
void doButton(std::string);
void sRender() override final;
};

48
src/VectorShape.cpp Normal file
View File

@ -0,0 +1,48 @@
#include "VectorShape.h"
VectorShape::VectorShape()
{
sf::Vector2f p(0, 0);
points.push_back(sf::Vector2f(0, 40));
points.push_back(sf::Vector2f(-30, -30));
points.push_back(sf::Vector2f(0, -20));
points.push_back(sf::Vector2f(30, -30));
}
void VectorShape::render(sf::RenderWindow & window)
{
sf::Transform t;
//t.scale(sf::Vector2f(0.5, 0.5));
//t.scale(sf::Vector2f(3, 3));
t.translate(position);
t.rotate(angle);
sf::VertexArray lines(sf::LineStrip, int(points.size())+1);
for ( int i = 0; i < points.size(); i++)
{
lines[i] = points[i];
}
lines[points.size()] = points[0];
window.draw(lines, t);
}
void VectorShape::miner()
{
points.clear();
points.push_back(sf::Vector2f(0, -40));
float mirror_x[12] = {-1, -1, -.5, -.5, -2, -2, -3, -3, -2, -2, -1.5, -0.5};
float fixed_y[12] = {-3, -2, -1.5, -1, -1, -.5, 0, 1, 1.5, 2, 3, 3};
for (int i = 0; i < 12; i++)
{
points.push_back(sf::Vector2f(mirror_x[i] * 10, fixed_y[i] * 10));
}
points.push_back(sf::Vector2f(0, 20));
for (int i = 11; i >= 0; i--)
{
points.push_back(sf::Vector2f(mirror_x[i] * -10, fixed_y[i] * 10));
}
}

16
src/VectorShape.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "Common.h"
class VectorShape
{
public:
VectorShape();
std::vector<sf::Vector2f> points;
void render(sf::RenderWindow & window);
float angle;
sf::Vector2f position;
void miner();
protected:
private:
};

8
src/main.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <SFML/Graphics.hpp>
#include "GameEngine.h"
int main()
{
GameEngine g;
g.run();
}