JANK MODE: Messy / broken commit - in progress

Needed to make a checkpoint, gods forgive me for committing known broken code straight to master. The jam has in a sense already begun.

I tested a smaller solution in the xplat_concept repo earlier today.
In short, I'm going to build a janky method to add new + report existing UI elements. After that's done, the UI building should be done from python modules, hastening the UI design.

This is ugly and bad, I am truly sorry. We just need to get through 7DRL, so I can't make it pretty today.
This commit is contained in:
John McCardle 2023-02-28 23:19:43 -05:00
parent 2c1946c29b
commit 1e9fd77a13
7 changed files with 147 additions and 101 deletions

View File

@ -7,7 +7,7 @@
GameEngine::GameEngine() GameEngine::GameEngine()
{ {
font.loadFromFile("./assets/JetbrainsMono.ttf"); font.loadFromFile("./assets/JetbrainsMono.ttf");
window.create(sf::VideoMode(640, 480), "McRogueFace Engine by John McCardle"); window.create(sf::VideoMode(1024, 768), "McRogueFace Engine by John McCardle");
visible = window.getDefaultView(); visible = window.getDefaultView();
window.setFramerateLimit(30); window.setFramerateLimit(30);
scene = "menu"; scene = "menu";
@ -19,6 +19,7 @@ GameEngine::GameEngine()
McRFPy_API::game = this; McRFPy_API::game = this;
McRFPy_API::api_init(); McRFPy_API::api_init();
McRFPy_API::executePyString("import mcrfpy"); McRFPy_API::executePyString("import mcrfpy");
McRFPy_API::executePyString("from UIMenu import *");
} }
Scene* GameEngine::currentScene() { return scenes[scene]; } Scene* GameEngine::currentScene() { return scenes[scene]; }

View File

@ -1,6 +1,7 @@
#include "McRFPy_API.h" #include "McRFPy_API.h"
#include "platform.h" #include "platform.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "Grid.h"
static PyMethodDef mcrfpyMethods[] = { static PyMethodDef mcrfpyMethods[] = {
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS, {"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
@ -79,6 +80,9 @@ void McRFPy_API::setSpriteTexture(int ti)
texture_size, texture_size)); texture_size, texture_size));
} }
// functionality
//void McRFPy_API::
// functionality // functionality
void McRFPy_API::drawSprite(int tex_index, int grid_x, int grid_y) void McRFPy_API::drawSprite(int tex_index, int grid_x, int grid_y)
{ {
@ -104,23 +108,31 @@ PyObject* McRFPy_API::_drawSprite(PyObject *self, PyObject *args)
void McRFPy_API::api_init() { void McRFPy_API::api_init() {
// initialization time build of Py API elements
/*
mcrfpyMethodsVector.push_back(
{"drawSprite", _drawSprite, METH_VARARGS,
"Draw a sprite (index, x, y)"}
);
mcrfpyMethodsVector.push_back(
{NULL, NULL, 0, NULL}
);
mcrfpyMethods = &mcrfpyMethodsVector[0];
*/
// build API exposure before python initialization // build API exposure before python initialization
PyImport_AppendInittab("mcrfpy", PyInit_mcrfpy); PyImport_AppendInittab("mcrfpy", PyInit_mcrfpy);
// use full path version of argv[0] from OS to init python // use full path version of argv[0] from OS to init python
init_python(narrow_string(executable_filename()).c_str()); init_python(narrow_string(executable_filename()).c_str());
/*
// Create Python translations of types
PyTypeObject * gridpoint_pytype = new PyTypeObject;
gridpoint_pytype->tp_name = "GridPoint";
gridpoint_pytype->tp_basicsize = sizeof(GridPoint);
gridpoint_pytype->tp_dealloc = [](PyObject* obj) {
delete ((GridPoint*) obj);
};
gridpoint_pytype->tp_flags = Py_TPFLAGS_DEFAULT;
gridpoint_pytype->tp_doc = "GridPoint";
gridpoint_pytype->tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) {
return (PyObject*) new GridPoint();
};
PyType_Ready(gridpoint_pytype);
PyModule_AddObject(
PyImport_AddModule("__main__"), "GridPoint", (PyObject*) gridpoint_pytype);
*/
texture.loadFromFile("./assets/kenney_tinydungeon.png"); texture.loadFromFile("./assets/kenney_tinydungeon.png");
//texture_size = 16, texture_width = 12, texture_height= 11; //texture_size = 16, texture_width = 12, texture_height= 11;
//texture_sprite_count = texture_width * texture_height; //texture_sprite_count = texture_width * texture_height;
@ -140,7 +152,70 @@ void McRFPy_API::executeScript(std::string filename)
} }
} }
void McRFPy_API::api_shutdown()
{
Py_Finalize();
}
void McRFPy_API::executePyString(std::string pycode) void McRFPy_API::executePyString(std::string pycode)
{ {
PyRun_SimpleString(pycode.c_str()); PyRun_SimpleString(pycode.c_str());
} }
void McRFPy_API::REPL()
{
PyRun_InteractiveLoop(stdin, "<stdin>");
}
void McRFPy_API::REPL_device(FILE * fp, const char *filename)
{
PyRun_InteractiveLoop(fp, filename);
}
PyObject* _createMenu(PyObject *self, PyObject *args) {
int sizex, sizey;
if (!PyArg_ParseTuple(args, "ii", &sizex, &sizey)) return NULL;
menus.push_back(createMenu(sizex, sizey));
Py_INCREF(Py_None);
return Py_None;
}
PyObject* _listMenus(PyObject*, PyObject*); {
// todo - get the (Py) classes UIMenu, Button, Caption, Sprite
// and call BuildValue (tuples) -> their constructors
PyObject* menulist = PyList_New(menus.size());
for (int i = 0; i < menus.size(); i++) {
auto p = menus[i].box.getPosition();
auto s = menus[i].box.getSize();
PyObject* menu_args = Py_BuildValue("(iiii)", p.x, p.y, s.x, s.y);
// * need uimenu_type (imported already to __main__)
PyObject* menuobj = PyObject_CallObject((PyObject*) uimenu_type, menu_args);
PyObject* button_list = PyObject_GetAttrString(menuobj, "buttons");
for(auto& b : menus[i].buttons) {
auto bp = b.rect.getPosition();
auto bs = b.rect.getSize();
auto bg = b.rect.getFillColor();
auto bf = b.caption.getFillColor();
PyObject* btn_args = Py_BuildValue("(iiii(iii)(iii)ss)",
bp.x, bp.y, bs.x, bs.y,
bg.r, bg.g, bg.b,
bf.r, bf.g, bf.b,
b.caption.getString.toAnsiString().c_str(),
b.action.c_str());
// * need btn_type
PyObject buttonobj = PyObject_CallObject((PyObject*) btn_type, btn_args);
PyList_Append(button_list, buttonobj);
}
PyObject* caption_list = PyObject_GetAttrString(menuobj, "captions");
for () { }
PyObject* sprite_list = PyObject_GetAttrString(menuobj, "sprites");
for () { }
PyList_SET_ITEM(menulist, i, menuobj);
}
return menulist;
}

View File

@ -30,8 +30,37 @@ public:
static void setSpriteTexture(int); static void setSpriteTexture(int);
inline static GameEngine* game; inline static GameEngine* game;
static void api_init(); static void api_init();
static void api_shutdown();
// Python API functionality - use mcrfpy.* in scripts // Python API functionality - use mcrfpy.* in scripts
static PyObject* _drawSprite(PyObject*, PyObject*); static PyObject* _drawSprite(PyObject*, PyObject*);
static void REPL_device(FILE * fp, const char *filename);
static void REPL();
// Jank mode engage: let the API hold data for Python to hack on
std::vector<UIMenu> menus;
EntityManager entities; // this is also kinda good, entities not on the current grid can still act (like monsters following you through doors??)
std::vector<Grid> grids;
// Jank Python Method Exposures
static PyObject* _createMenu(PyObject*, PyObject*); // creates a new menu object in McRFPy_API::menus
static PyObject* _listMenus(PyObject*, PyObject*);
//static PyObject* _createCaption(PyObject*, PyObject*); // calls menu.add_caption
//static PyObject* _listCaptions(PyObject*, PyObject*);
//static PyObject* _createButton(PyObject*, PyObject*);
//static PyObject* _listButtons(PyObject*, PyObject*);
//static PyObject* _createEntity(PyObject*, PyObject*);
//static PyObject* _listEntities(PyObject*, PyObject*);
//static PyObject* _createGrid(PyObject*, PyObject*);
//static PyObject* _listGrids(PyObject*, PyObject*);
//static PyObject* _createSprite(PyObject*, PyObject*);
// Jank Functionality
static UIMenu createMenu(int sizex, int sizey);
//static Button createButton(UIMenu & menu, int x, int y, int w, int h);
//static sf::Sprite createSprite(int tex_index, int x, int y);
//static void playSound(const char * filename);
//static void playMusic(const char * filename);
// McRFPy_API(GameEngine*); // McRFPy_API(GameEngine*);

View File

@ -31,9 +31,9 @@ void MenuScene::doAction(std::string name, std::string type)
if(ACTION("start_game", "start")) if(ACTION("start_game", "start"))
game->changeScene("play"); game->changeScene("play");
else if(ACTIONONCE("up")) else if(ACTIONONCE("up"))
game->getWindow().setSize(sf::Vector2u(1024, 768)); game->getWindow().setSize(sf::Vector2u(1280, 800));
else if(ACTIONONCE("down")) else if(ACTIONONCE("down"))
game->getWindow().setSize(sf::Vector2u(640, 480)); game->getWindow().setSize(sf::Vector2u(1024, 768));
} }
void MenuScene::sRender() void MenuScene::sRender()

View File

@ -1,4 +1,5 @@
#include "UIMenu.h" #include "UIMenu.h"
#include "Common.h"
UIMenu::UIMenu(sf::Font & _font) UIMenu::UIMenu(sf::Font & _font)
: font(_font) : font(_font)
@ -18,6 +19,7 @@ void UIMenu::render(sf::RenderWindow & window)
window.draw(c); window.draw(c);
} }
for (auto& b : buttons) { b.render(window); } for (auto& b : buttons) { b.render(window); }
for (auto& s: sprites) { window.draw(s); }
} }
void UIMenu::refresh() void UIMenu::refresh()
@ -46,3 +48,9 @@ void UIMenu::add_button(Button b)
next_button += 50; next_button += 50;
buttons.push_back(b); buttons.push_back(b);
} }
void UIMenu::add_sprite(sf::Sprite s)
{
sprites.push_back(s);
}

View File

@ -11,6 +11,7 @@ public:
UIMenu(sf::Font & _font); UIMenu(sf::Font & _font);
std::vector<sf::Text> captions; std::vector<sf::Text> captions;
std::vector<Button> buttons; std::vector<Button> buttons;
std::vector<sf::Sprite> sprites;
sf::RectangleShape box; sf::RectangleShape box;
bool visible = false; bool visible = false;
int next_text = 10; int next_text = 10;
@ -20,7 +21,7 @@ public:
void refresh(); void refresh();
void add_caption(const char* text, int size, sf::Color color); void add_caption(const char* text, int size, sf::Color color);
void add_button(Button b); void add_button(Button b);
void add_sprite(sf::Sprite s);
protected: protected:

View File

@ -20,7 +20,7 @@ void setSpriteTexture(int ti)
} }
UITestScene::UITestScene(GameEngine* g) UITestScene::UITestScene(GameEngine* g)
: Scene(g), grid(30, 10, 16, 20, 20, 400, 320) : Scene(g), grid(150, 150, 16, 20, 20, 800, 520)
{ {
// demo sprites from texture file // demo sprites from texture file
texture.loadFromFile("./assets/kenney_tinydungeon.png"); texture.loadFromFile("./assets/kenney_tinydungeon.png");
@ -33,22 +33,14 @@ UITestScene::UITestScene(GameEngine* g)
setSpriteTexture(0); setSpriteTexture(0);
// random for this test // random for this test
//std::default_random_engine generator(42);
//std::normal_distribution<double> distribution(0, 131);
std::random_device rd; // Will be used to obtain a seed for the random number engine std::random_device rd; // Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> distrib(0, 131); std::uniform_int_distribution<> distrib(84, 100);
// Use distrib to transform the random unsigned int
// generated by gen into an int in [1, 6]
//for (int n = 0; n != 10; ++n)
// std::cout << distrib(gen) << ' ';
// std::cout << '\n';
// Test grid with random sprite noise // Test grid with random sprite noise
for (int _x = 0; _x < 30; _x++) for (int _x = 0; _x < 150; _x++)
for (int _y = 0; _y < 10; _y++) for (int _y = 0; _y < 150; _y++)
//grid.at(_x, _y).tilesprite = _y*11 + _x; //grid.at(_x, _y).tilesprite = _y*11 + _x;
//if (!_x % 2 || _y == 0) grid.at(_x, _y).tilesprite = 121; //if (!_x % 2 || _y == 0) grid.at(_x, _y).tilesprite = 121;
//else //else
@ -95,7 +87,7 @@ UITestScene::UITestScene(GameEngine* g)
test_menu.visible = false; test_menu.visible = false;
test_menu.box.setSize(sf::Vector2f(350, 200)); test_menu.box.setSize(sf::Vector2f(350, 200));
test_menu.add_caption("debug to stdout", 16, sf::Color(255, 255, 0)); 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_menu.add_button(Button(0, 0, 130, 40, sf::Color(0, 0, 192), sf::Color(0,0,0), "REPL", game->getFont(), "startrepl"));
test_menu2.visible = true; test_menu2.visible = true;
test_menu2.box.setPosition(150, 180); test_menu2.box.setPosition(150, 180);
@ -112,10 +104,12 @@ UITestScene::UITestScene(GameEngine* g)
menus.push_back(test_menu); menus.push_back(test_menu);
menus.push_back(test_menu2); menus.push_back(test_menu2);
/*
test_ship.miner(); test_ship.miner();
test_ship.angle = 180.0; test_ship.angle = 180.0;
test_ship.position.x = 250; test_ship.position.x = 250;
test_ship.position.y = 120; test_ship.position.y = 120;
*/
//std::cout << menus.size() << std::endl; //std::cout << menus.size() << std::endl;
} }
@ -148,10 +142,11 @@ void UITestScene::update()
void UITestScene::doButton(std::string b_action) void UITestScene::doButton(std::string b_action)
{ {
if (!b_action.compare("showviewport")) if (!b_action.compare("startrepl"))
{ {
std::cout << viewport.getSize().x << ", " << viewport.getSize().y << ": " McRFPy_API::REPL();
<< viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl; //std::cout << viewport.getSize().x << ", " << viewport.getSize().y << ": "
// << viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl;
} }
} }
@ -218,39 +213,30 @@ void UITestScene::doAction(std::string name, std::string type)
if (ACTION("sound_test", "start")) { sound.play(); } if (ACTION("sound_test", "start")) { sound.play(); }
if (ACTION("left", "start")) { if (ACTION("left", "start")) {
//viewport.move(-10, 0);
grid.center_x -= 0.5; grid.center_x -= 0.5;
} }
if (ACTION("right", "start")) { if (ACTION("right", "start")) {
//viewport.move(10, 0);
grid.center_x += 0.5; grid.center_x += 0.5;
} }
if (ACTION("up", "start")) { if (ACTION("up", "start")) {
//viewport.move(0, -10);
grid.center_y -= 0.5; grid.center_y -= 0.5;
} }
if (ACTION("down", "start")) { if (ACTION("down", "start")) {
//viewport.move(0, 10);
grid.center_y += 0.5; grid.center_y += 0.5;
} }
//if (ACTION("down", "start")) {
// viewport.move(0, 10);
//}
if (ACTION("zoom_down", "start")) { if (ACTION("zoom_down", "start")) {
//if (zoom > 0.2f) zoom -= 0.1f; viewport.zoom(zoom);
if (grid.zoom > 0.75f) grid.zoom -= 0.25f; if (grid.zoom > 0.75f) grid.zoom -= 0.25f;
} }
if (ACTION("zoom_up", "start")) { if (ACTION("zoom_up", "start")) {
//if (zoom < 10.0f) zoom += 0.1f; viewport.zoom(zoom);
if (grid.zoom < 5.0f) grid.zoom += 0.25f; if (grid.zoom < 5.0f) grid.zoom += 0.25f;
} }
//std::cout << "viewport: " << viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl; //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 if (type.compare("resize")) // get center coordinate from game coordinate viewport, apply to new window viewport, restore zoom level
{ {
auto center = viewport.getCenter(); auto center = viewport.getCenter();
//auto w = viewport.getSize().x;
//auto h = viewport.getSize().y;
viewport = game->getView(); viewport = game->getView();
viewport.setCenter(center); viewport.setCenter(center);
viewport.zoom(zoom); viewport.zoom(zoom);
@ -268,67 +254,18 @@ void UITestScene::sRender()
// Scrolling Viewport Objects (under the UI) --- entities, etc. // Scrolling Viewport Objects (under the UI) --- entities, etc.
game->getWindow().setView(viewport); 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()) for (auto e : entities.getEntities())
{ {
//game->getWindow().draw(e->cShape->circle); //game->getWindow().draw(e->cShape->circle);
} }
test_ship.render(game->getWindow());
//draw grid
grid.render(game->getWindow());
// Fixed position objects // Fixed position objects
game->getWindow().setView(game->getView()); game->getWindow().setView(game->getView());
game->getWindow().draw(text); game->getWindow().draw(text);
//draw grid
grid.render(game->getWindow());
//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) for ( auto ui : menus)
{ {
//std::cout << ui.buttons[0].getAction() << std::endl; //std::cout << ui.buttons[0].getAction() << std::endl;
@ -338,12 +275,7 @@ void UITestScene::sRender()
} }
// test Python sprite code // test Python sprite code
McRFPy_API::executePyString("mcrfpy.drawSprite(123, 36, 10)"); //McRFPy_API::executePyString("mcrfpy.drawSprite(123, 36, 10)");
//McRFPy_API::executePyString("mcrfpy.drawSprite(121, 15, 15)");
//game->api->executePyString("mcrfpy.drawSprite(123, 10, 10)")
//game->api->executePyString("mcrfpy.drawSprite(121, 15, 15)")
// draw test sprite on top of everything // draw test sprite on top of everything
game->getWindow().draw(test_sprite); game->getWindow().draw(test_sprite);