Fully python-driven scene. Lots of interaction needs testing but the broad strokes are there for mouse pan/zoom on multiple grids and any number of UIs
This commit is contained in:
parent
a4b6c2c428
commit
257aa3c3d2
|
@ -3,6 +3,7 @@
|
||||||
#include "UITestScene.h"
|
#include "UITestScene.h"
|
||||||
#include "ActionCode.h"
|
#include "ActionCode.h"
|
||||||
#include "McRFPy_API.h"
|
#include "McRFPy_API.h"
|
||||||
|
#include "PythonScene.h"
|
||||||
|
|
||||||
GameEngine::GameEngine()
|
GameEngine::GameEngine()
|
||||||
{
|
{
|
||||||
|
@ -10,18 +11,21 @@ GameEngine::GameEngine()
|
||||||
window.create(sf::VideoMode(1024, 768), "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 = "py";
|
||||||
//std::cout << "Constructing MenuScene" << std::endl;
|
//std::cout << "Constructing MenuScene" << std::endl;
|
||||||
scenes["menu"] = new MenuScene(this);
|
scenes["menu"] = new MenuScene(this);
|
||||||
//std::cout << "Constructed MenuScene" <<std::endl;
|
//std::cout << "Constructed MenuScene" <<std::endl;
|
||||||
scenes["play"] = new UITestScene(this);
|
scenes["play"] = new UITestScene(this);
|
||||||
//api = new McRFPy_API(this);
|
//api = new McRFPy_API(this);
|
||||||
|
|
||||||
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 *");
|
McRFPy_API::executePyString("from UIMenu import *");
|
||||||
McRFPy_API::executePyString("from Grid import *");
|
McRFPy_API::executePyString("from Grid import *");
|
||||||
|
|
||||||
|
scenes["py"] = new PythonScene(this, "TestScene");
|
||||||
|
|
||||||
IndexSprite::game = this;
|
IndexSprite::game = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ Grid::Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h):
|
||||||
grid_size(gs),
|
grid_size(gs),
|
||||||
grid_x(gx), grid_y(gy),
|
grid_x(gx), grid_y(gy),
|
||||||
zoom(1.0f), center_x((gx/2) * gs), center_y((gy/2) * gs),
|
zoom(1.0f), center_x((gx/2) * gs), center_y((gy/2) * gs),
|
||||||
texture_width(12), texture_height(11)
|
texture_width(12), texture_height(11), visible(false)
|
||||||
{
|
{
|
||||||
//grid_size = gs;
|
//grid_size = gs;
|
||||||
//zoom = 1.0f;
|
//zoom = 1.0f;
|
||||||
|
|
|
@ -20,11 +20,13 @@ private:
|
||||||
public:
|
public:
|
||||||
Grid();
|
Grid();
|
||||||
sf::RectangleShape box; // view on window
|
sf::RectangleShape box; // view on window
|
||||||
|
bool visible;
|
||||||
sf::Texture texture;
|
sf::Texture texture;
|
||||||
sf::Sprite sprite, output;
|
sf::Sprite sprite, output;
|
||||||
sf::RenderTexture renderTexture;
|
sf::RenderTexture renderTexture;
|
||||||
void setSprite(int);
|
void setSprite(int);
|
||||||
const int texture_width, texture_height;
|
const int texture_width, texture_height;
|
||||||
|
auto contains(sf::Vector2i p) { return box.getGlobalBounds().contains(p.x, p.y); }
|
||||||
|
|
||||||
Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h);
|
Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h);
|
||||||
int grid_x, grid_y; // rectangle map size (integer - sprites)
|
int grid_x, grid_y; // rectangle map size (integer - sprites)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
std::map<std::string, UIMenu*> McRFPy_API::menus;
|
std::map<std::string, UIMenu*> McRFPy_API::menus;
|
||||||
std::map<std::string, Grid*> McRFPy_API::grids;
|
std::map<std::string, Grid*> McRFPy_API::grids;
|
||||||
std::map<std::string, PyObject*> McRFPy_API::callbacks;
|
std::map<std::string, PyObject*> McRFPy_API::callbacks;
|
||||||
|
EntityManager McRFPy_API::entities;
|
||||||
|
|
||||||
static PyMethodDef mcrfpyMethods[] = {
|
static PyMethodDef mcrfpyMethods[] = {
|
||||||
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
|
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
|
|
||||||
// Jank mode engage: let the API hold data for Python to hack on
|
// Jank mode engage: let the API hold data for Python to hack on
|
||||||
static std::map<std::string, UIMenu*> menus;
|
static std::map<std::string, UIMenu*> menus;
|
||||||
EntityManager entities; // this is also kinda good, entities not on the current grid can still act (like monsters following you through doors??)
|
static EntityManager entities; // this is also kinda good, entities not on the current grid can still act (like monsters following you through doors??)
|
||||||
static std::map<std::string, Grid*> grids;
|
static std::map<std::string, Grid*> grids;
|
||||||
|
|
||||||
static std::map<std::string, PyObject*> callbacks;
|
static std::map<std::string, PyObject*> callbacks;
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
#include "PythonScene.h"
|
||||||
|
#include "ActionCode.h"
|
||||||
|
#include "McRFPy_API.h"
|
||||||
|
|
||||||
|
PythonScene::PythonScene(GameEngine* g, std::string pymodule)
|
||||||
|
: Scene(g) {
|
||||||
|
// mouse events
|
||||||
|
registerAction(ActionCode::MOUSEBUTTON + sf::Mouse::Left, "click");
|
||||||
|
registerAction(ActionCode::MOUSEBUTTON + sf::Mouse::Left, "rclick");
|
||||||
|
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_DEL, "wheel_up");
|
||||||
|
registerAction(ActionCode::MOUSEWHEEL + ActionCode::WHEEL_NEG + ActionCode::WHEEL_DEL, "wheel_down");
|
||||||
|
|
||||||
|
// keyboard events
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Q, "upleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::W, "up");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::E, "upright");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::A, "left");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::S, "down");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::D, "right");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Z, "downleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::X, "wait");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::C, "downright");
|
||||||
|
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad7, "upleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad8, "up");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad9, "upright");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad4, "left");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad5, "wait");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad6, "right");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad1, "downleft");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad2, "down");
|
||||||
|
registerAction(ActionCode::KEY + sf::Keyboard::Numpad3, "downright");
|
||||||
|
|
||||||
|
// window resize
|
||||||
|
registerAction(0, "event");
|
||||||
|
|
||||||
|
dragging = false;
|
||||||
|
|
||||||
|
// import pymodule and call start()
|
||||||
|
McRFPy_API::executePyString("import " + pymodule);
|
||||||
|
McRFPy_API::executePyString(pymodule + ".start()");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::update() {
|
||||||
|
McRFPy_API::entities.update();
|
||||||
|
|
||||||
|
// check if left click is still down & mouse has moved
|
||||||
|
// continue the drag motion
|
||||||
|
if (dragging && drag_grid) {
|
||||||
|
auto mousepos = sf::Mouse::getPosition(game->getWindow());
|
||||||
|
auto dx = mousepos.x - mouseprev.x,
|
||||||
|
dy = mousepos.y - mouseprev.y;
|
||||||
|
drag_grid->center_x += (dx / drag_grid->zoom);
|
||||||
|
drag_grid->center_y += (dy / drag_grid->zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doLClick(sf::Vector2i mousepos) {
|
||||||
|
// UI buttons get first chance
|
||||||
|
for (auto pair : McRFPy_API::menus) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
for (auto b : pair.second->buttons) {
|
||||||
|
if (b.contains(mousepos)) {
|
||||||
|
McRFPy_API::doAction(b.getAction());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// left clicking a grid to select a square
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doRClick(sf::Vector2i mousepos) {
|
||||||
|
// just grids for right click
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doZoom(sf::Vector2i mousepos, int value) {
|
||||||
|
// just grids for right click
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was zoomed
|
||||||
|
float new_zoom = pair.second->zoom + (value * 0.25);
|
||||||
|
if (new_zoom >= 0.5 && new_zoom <= 5.0) {
|
||||||
|
pair.second->zoom = new_zoom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::doAction(std::string name, std::string type) {
|
||||||
|
auto mousepos = sf::Mouse::getPosition(game->getWindow());
|
||||||
|
if (ACTIONONCE("click")) {
|
||||||
|
// left click start
|
||||||
|
dragstart = mousepos;
|
||||||
|
mouseprev = mousepos;
|
||||||
|
dragging = true;
|
||||||
|
// determine the grid that contains the cursor
|
||||||
|
for (auto pair : McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
if (pair.second->contains(mousepos)) {
|
||||||
|
// grid was clicked
|
||||||
|
drag_grid = pair.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ACTIONAFTER("click")) {
|
||||||
|
// left click end
|
||||||
|
// if click ended without starting a drag event, try lclick?
|
||||||
|
if (dragstart == mousepos) {
|
||||||
|
// mouse did not move, do click
|
||||||
|
doLClick(mousepos);
|
||||||
|
}
|
||||||
|
dragging = false;
|
||||||
|
drag_grid = NULL;
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("rclick")) {
|
||||||
|
// not going to test for right click drag - just rclick
|
||||||
|
doRClick(mousepos);
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("wheel_up")) {
|
||||||
|
// try zoom in
|
||||||
|
doZoom(mousepos, 1);
|
||||||
|
}
|
||||||
|
else if (ACTIONONCE("wheel_down")) {
|
||||||
|
// try zoom out
|
||||||
|
doZoom(mousepos, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PythonScene::sRender() {
|
||||||
|
game->getWindow().clear();
|
||||||
|
|
||||||
|
for (auto pair: McRFPy_API::grids) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
pair.second->render(game->getWindow());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto pair: McRFPy_API::menus) {
|
||||||
|
if (!pair.second->visible) continue;
|
||||||
|
pair.second->render(game->getWindow());
|
||||||
|
}
|
||||||
|
|
||||||
|
game->getWindow().display();
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "GameEngine.h"
|
||||||
|
#include "Grid.h"
|
||||||
|
|
||||||
|
class PythonScene: public Scene
|
||||||
|
{
|
||||||
|
sf::Vector2i dragstart, mouseprev;
|
||||||
|
bool dragging;
|
||||||
|
Grid* drag_grid;
|
||||||
|
void doLClick(sf::Vector2i);
|
||||||
|
void doRClick(sf::Vector2i);
|
||||||
|
void doZoom(sf::Vector2i, int);
|
||||||
|
public:
|
||||||
|
PythonScene(GameEngine*, std::string);
|
||||||
|
void update() override final;
|
||||||
|
void doAction(std::string, std::string) override final;
|
||||||
|
void sRender() override final;
|
||||||
|
};
|
|
@ -3,6 +3,7 @@
|
||||||
// macros for scene input
|
// macros for scene input
|
||||||
#define ACTION(X, Y) (name.compare(X) == 0 && type.compare(Y) == 0)
|
#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]))
|
#define ACTIONONCE(X) ((name.compare(X) == 0 && type.compare("start") == 0 && !actionState[name]))
|
||||||
|
#define ACTIONAFTER(X) ((name.compare(X) == 0 && type.compare("end") == 0 && actionState[name]))
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
//#include "GameEngine.h"
|
//#include "GameEngine.h"
|
||||||
|
|
Loading…
Reference in New Issue