Spawning & drawing entities from Python API
This commit is contained in:
parent
87483cc8ad
commit
6875cb5fe1
|
@ -22,7 +22,7 @@ I did the r/RoguelikeDev TCOD tutorial in Python. I loved it, but I did not want
|
||||||
* ✅ Windows / Visual Studio project
|
* ✅ Windows / Visual Studio project
|
||||||
* ✅ Draw Sprites
|
* ✅ Draw Sprites
|
||||||
* ✅ Play Sounds
|
* ✅ Play Sounds
|
||||||
* ❌ Draw UI, spawn entity from Python code
|
* ✅ Draw UI, spawn entity from Python code
|
||||||
* ❌ Python AI for entities (NPCs on set paths, enemies towards player)
|
* ❌ Python AI for entities (NPCs on set paths, enemies towards player)
|
||||||
* ❌ Walking / Collision; "Boards" (stairs / doors / walk off edge of screen)
|
* ❌ Walking / Collision; "Boards" (stairs / doors / walk off edge of screen)
|
||||||
* ❌ Cutscenes - interrupt normal controls, text scroll, character portraits
|
* ❌ Cutscenes - interrupt normal controls, text scroll, character portraits
|
||||||
|
|
|
@ -1,6 +1,63 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "IndexSprite.h"
|
||||||
|
#include "Grid.h"
|
||||||
|
#include "Item.h"
|
||||||
|
#include "Python.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class CGrid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool visible;
|
||||||
|
int x, y;
|
||||||
|
IndexSprite indexsprite;
|
||||||
|
Grid* grid;
|
||||||
|
CGrid(Grid* _g, int _ti, int _si, int _x, int _y, bool _v)
|
||||||
|
: visible(_v), x(_x), y(_y), grid(_g), indexsprite(_ti, _si, _x, _y, 1.0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInventory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//std::list<std::shared_ptr<Item>>;
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PyObject* object;
|
||||||
|
CBehavior(PyObject* p): object(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
class CCombatant
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int hp;
|
||||||
|
int maxhp;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CCaster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int mp;
|
||||||
|
int maxmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CLevel
|
||||||
|
{
|
||||||
|
int constitution; // +HP, resist effects
|
||||||
|
int strength; // +damage, block/parry
|
||||||
|
int dexterity; // +speed, dodge
|
||||||
|
int intelligence; // +MP, spell resist
|
||||||
|
int wisdom; // +damage, deflect
|
||||||
|
int luck; // crit, loot
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class CTransform
|
class CTransform
|
||||||
|
@ -15,6 +72,7 @@ public:
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
class CShape
|
class CShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -77,3 +135,4 @@ public:
|
||||||
float theta_max;
|
float theta_max;
|
||||||
float dtheta_max;
|
float dtheta_max;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
13
src/Entity.h
13
src/Entity.h
|
@ -18,11 +18,14 @@ class Entity
|
||||||
public:
|
public:
|
||||||
// component pointers
|
// component pointers
|
||||||
//std::shared_ptr<CTransform> cTransform;
|
//std::shared_ptr<CTransform> cTransform;
|
||||||
std::shared_ptr<CShape> cShape;
|
//std::shared_ptr<CShape> cShape;
|
||||||
std::shared_ptr<CCollision> cCollision;
|
//std::shared_ptr<CCollision> cCollision;
|
||||||
std::shared_ptr<CInput> cInput;
|
//std::shared_ptr<CInput> cInput;
|
||||||
std::shared_ptr<CScore> cScore;
|
//std::shared_ptr<CScore> cScore;
|
||||||
std::shared_ptr<CLifespan> cLifespan;
|
//std::shared_ptr<CLifespan> cLifespan;
|
||||||
|
std::shared_ptr<CGrid> cGrid;
|
||||||
|
std::shared_ptr<CInventory> cInventory;
|
||||||
|
std::shared_ptr<CBehavior> cBehavior;
|
||||||
|
|
||||||
//private member access functions
|
//private member access functions
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
|
|
11
src/Grid.cpp
11
src/Grid.cpp
|
@ -1,5 +1,6 @@
|
||||||
#include "Grid.h"
|
#include "Grid.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
GridPoint::GridPoint():
|
GridPoint::GridPoint():
|
||||||
color(0, 0, 0, 0), walkable(true), tilesprite(-1), transparent(true), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1)
|
color(0, 0, 0, 0), walkable(true), tilesprite(-1), transparent(true), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1)
|
||||||
|
@ -237,6 +238,16 @@ void Grid::render(sf::RenderWindow & window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto e : entities) {
|
||||||
|
auto drawent = e->cGrid->indexsprite.drawable();
|
||||||
|
drawent.setScale(zoom, zoom);
|
||||||
|
auto pixel_pos = sf::Vector2f(
|
||||||
|
(drawent.getPosition().x*grid_size - left_spritepixels) * zoom,
|
||||||
|
(drawent.getPosition().y*grid_size - top_spritepixels) * zoom );
|
||||||
|
drawent.setPosition(pixel_pos);
|
||||||
|
renderTexture.draw(drawent);
|
||||||
|
}
|
||||||
|
|
||||||
// grid lines for testing & validation
|
// grid lines for testing & validation
|
||||||
/*
|
/*
|
||||||
sf::Vertex line[] =
|
sf::Vertex line[] =
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
//#include "Entity.h"
|
||||||
|
class Entity; // forward declare
|
||||||
|
|
||||||
class GridPoint
|
class GridPoint
|
||||||
{
|
{
|
||||||
|
@ -35,6 +37,7 @@ public:
|
||||||
int center_x, center_y; // center in 1.0x Pixels
|
int center_x, center_y; // center in 1.0x Pixels
|
||||||
|
|
||||||
std::vector<GridPoint> points; // grid visible contents
|
std::vector<GridPoint> points; // grid visible contents
|
||||||
|
std::vector<std::shared_ptr<Entity>> entities;
|
||||||
void render(sf::RenderWindow&); // draw to screen
|
void render(sf::RenderWindow&); // draw to screen
|
||||||
GridPoint& at(int, int);
|
GridPoint& at(int, int);
|
||||||
bool inBounds(int, int);
|
bool inBounds(int, int);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "Item.h"
|
||||||
|
|
||||||
|
int Item::next_id;
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Components.h"
|
||||||
|
#include "Python.h"
|
||||||
|
|
||||||
|
class Item
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool stackable;
|
||||||
|
static int next_id;
|
||||||
|
std::string name;
|
||||||
|
PyObject* object;
|
||||||
|
};
|
|
@ -11,6 +11,9 @@ std::list<Animation*> McRFPy_API::animations;
|
||||||
std::vector<sf::SoundBuffer> McRFPy_API::soundbuffers;
|
std::vector<sf::SoundBuffer> McRFPy_API::soundbuffers;
|
||||||
sf::Music McRFPy_API::music;
|
sf::Music McRFPy_API::music;
|
||||||
sf::Sound McRFPy_API::sfx;
|
sf::Sound McRFPy_API::sfx;
|
||||||
|
std::string McRFPy_API::input_mode;
|
||||||
|
int McRFPy_API::turn_number;
|
||||||
|
std::string McRFPy_API::active_grid;
|
||||||
|
|
||||||
EntityManager McRFPy_API::entities;
|
EntityManager McRFPy_API::entities;
|
||||||
|
|
||||||
|
@ -80,6 +83,15 @@ static PyMethodDef mcrfpyMethods[] = {
|
||||||
{"getMusicVolume", McRFPy_API::_getMusicVolume, METH_VARARGS, ""},
|
{"getMusicVolume", McRFPy_API::_getMusicVolume, METH_VARARGS, ""},
|
||||||
{"getSoundVolume", McRFPy_API::_getSoundVolume, METH_VARARGS, ""},
|
{"getSoundVolume", McRFPy_API::_getSoundVolume, METH_VARARGS, ""},
|
||||||
|
|
||||||
|
{"unlockPlayerInput", McRFPy_API::_unlockPlayerInput, METH_VARARGS, ""},
|
||||||
|
{"lockPlayerInput", McRFPy_API::_lockPlayerInput, METH_VARARGS, ""},
|
||||||
|
{"requestGridTarget", McRFPy_API::_requestGridTarget, METH_VARARGS, ""},
|
||||||
|
{"activeGrid", McRFPy_API::_activeGrid, METH_VARARGS, ""},
|
||||||
|
{"inputMode", McRFPy_API::_inputMode, METH_VARARGS, ""},
|
||||||
|
{"turnNumber", McRFPy_API::_turnNumber, METH_VARARGS, ""},
|
||||||
|
{"createEntity", McRFPy_API::_createEntity, METH_VARARGS, ""},
|
||||||
|
{"listEntities", McRFPy_API::_listEntities, METH_VARARGS, ""},
|
||||||
|
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -851,3 +863,48 @@ PyObject* McRFPy_API::_getMusicVolume(PyObject* self, PyObject* args) {
|
||||||
PyObject* McRFPy_API::_getSoundVolume(PyObject* self, PyObject* args) {
|
PyObject* McRFPy_API::_getSoundVolume(PyObject* self, PyObject* args) {
|
||||||
return Py_BuildValue("f", McRFPy_API::sfx.getVolume());
|
return Py_BuildValue("f", McRFPy_API::sfx.getVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* McRFPy_API::_unlockPlayerInput(PyObject* self, PyObject* args) {
|
||||||
|
McRFPy_API::input_mode = "playerturn";
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_lockPlayerInput(PyObject* self, PyObject* args) {
|
||||||
|
McRFPy_API::input_mode = "computerturn";
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_requestGridTarget(PyObject* self, PyObject* args) {
|
||||||
|
const char* requestmode;
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &requestmode)) return NULL;
|
||||||
|
McRFPy_API::input_mode = requestmode;
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_activeGrid(PyObject* self, PyObject* args) {
|
||||||
|
return Py_BuildValue("s", McRFPy_API::active_grid.c_str());
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_inputMode(PyObject* self, PyObject* args) {
|
||||||
|
return Py_BuildValue("s", McRFPy_API::input_mode.c_str());
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_turnNumber(PyObject* self, PyObject* args) {
|
||||||
|
return Py_BuildValue("i", McRFPy_API::turn_number);
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_createEntity(PyObject* self, PyObject* args) {
|
||||||
|
const char * grid_cstr, *entity_tag;
|
||||||
|
int ti, si, x, y;
|
||||||
|
PyObject* behavior_obj;
|
||||||
|
if (!PyArg_ParseTuple(args, "ssiiii|O", &grid_cstr, &entity_tag, &ti, &si, &x, &y, &behavior_obj)) return NULL;
|
||||||
|
auto e = entities.addEntity(std::string(entity_tag));
|
||||||
|
Grid* grid_ptr = grids[grid_cstr];
|
||||||
|
grid_ptr->entities.push_back(e);
|
||||||
|
e->cGrid = std::make_shared<CGrid>(grid_ptr, ti, si, x, y, true);
|
||||||
|
e->cBehavior = std::make_shared<CBehavior>(behavior_obj);
|
||||||
|
Py_INCREF(behavior_obj);
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
PyObject* McRFPy_API::_listEntities(PyObject* self, PyObject* args) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
static sf::Music music;
|
static sf::Music music;
|
||||||
static sf::Sound sfx;
|
static sf::Sound sfx;
|
||||||
|
|
||||||
|
static std::shared_ptr<Entity> player;
|
||||||
|
|
||||||
static std::map<std::string, PyObject*> callbacks;
|
static std::map<std::string, PyObject*> callbacks;
|
||||||
|
|
||||||
// Jank Python Method Exposures
|
// Jank Python Method Exposures
|
||||||
|
@ -70,8 +72,8 @@ public:
|
||||||
//static PyObject* _listCaptions(PyObject*, PyObject*);
|
//static PyObject* _listCaptions(PyObject*, PyObject*);
|
||||||
//static PyObject* _listButtons(PyObject*, PyObject*);
|
//static PyObject* _listButtons(PyObject*, PyObject*);
|
||||||
|
|
||||||
//static PyObject* _createEntity(PyObject*, PyObject*);
|
static PyObject* _createEntity(PyObject*, PyObject*);
|
||||||
//static PyObject* _listEntities(PyObject*, PyObject*);
|
static PyObject* _listEntities(PyObject*, PyObject*);
|
||||||
|
|
||||||
static PyObject* _createGrid(PyObject*, PyObject*);
|
static PyObject* _createGrid(PyObject*, PyObject*);
|
||||||
static PyObject* _listGrids(PyObject*, PyObject*);
|
static PyObject* _listGrids(PyObject*, PyObject*);
|
||||||
|
@ -89,6 +91,22 @@ public:
|
||||||
static PyObject* _getMusicVolume(PyObject*, PyObject*);
|
static PyObject* _getMusicVolume(PyObject*, PyObject*);
|
||||||
static PyObject* _getSoundVolume(PyObject*, PyObject*);
|
static PyObject* _getSoundVolume(PyObject*, PyObject*);
|
||||||
|
|
||||||
|
// allow all player actions (items, menus, movement, combat)
|
||||||
|
static PyObject* _unlockPlayerInput(PyObject*, PyObject*);
|
||||||
|
// disallow player actions (animating enemy actions)
|
||||||
|
static PyObject* _lockPlayerInput(PyObject*, PyObject*);
|
||||||
|
// prompt C++/Grid Objects to callback with a target Entity or grid space
|
||||||
|
static PyObject* _requestGridTarget(PyObject*, PyObject*);
|
||||||
|
// string for labeling the map
|
||||||
|
static std::string active_grid;
|
||||||
|
static PyObject* _activeGrid(PyObject*, PyObject*);
|
||||||
|
// string for prompting input
|
||||||
|
static std::string input_mode;
|
||||||
|
static PyObject* _inputMode(PyObject*, PyObject*);
|
||||||
|
// turn cycle
|
||||||
|
static int turn_number;
|
||||||
|
static PyObject* _turnNumber(PyObject*, PyObject*);
|
||||||
|
|
||||||
// Jank Functionality
|
// Jank Functionality
|
||||||
static UIMenu* createMenu(int posx, int posy, int sizex, int sizey);
|
static UIMenu* createMenu(int posx, int posy, int sizex, int sizey);
|
||||||
static void createCaption(std::string menukey, std::string text, int fontsize, sf::Color textcolor);
|
static void createCaption(std::string menukey, std::string text, int fontsize, sf::Color textcolor);
|
||||||
|
|
|
@ -41,6 +41,7 @@ PythonScene::PythonScene(GameEngine* g, std::string pymodule)
|
||||||
// import pymodule and call start()
|
// import pymodule and call start()
|
||||||
McRFPy_API::executePyString("import " + pymodule);
|
McRFPy_API::executePyString("import " + pymodule);
|
||||||
McRFPy_API::executePyString(pymodule + ".start()");
|
McRFPy_API::executePyString(pymodule + ".start()");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonScene::animate() {
|
void PythonScene::animate() {
|
||||||
|
|
Loading…
Reference in New Issue