GameState loads python scripts, anything but main.py is loaded as module
This commit is contained in:
parent
581ed013f3
commit
12ed3d3cb1
36
python/ball.py
Normal file
36
python/ball.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
class ball:
|
||||||
|
def __init__(self):
|
||||||
|
self.x = rnd(10, 100)
|
||||||
|
self.y = rnd(10, 100)
|
||||||
|
self.velX = rnd(-5,5)
|
||||||
|
self.velY = rnd(-5,5)
|
||||||
|
self.color = rnd(0,64)
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
|
||||||
|
self.x += self.velX;
|
||||||
|
self.y += self.velY;
|
||||||
|
|
||||||
|
if self.x < 0:
|
||||||
|
self.velX = -self.velX;
|
||||||
|
self.x = 0
|
||||||
|
linecol = rnd(0,64)
|
||||||
|
if self.y < 0:
|
||||||
|
self.velY = -self.velY;
|
||||||
|
self.y = 0
|
||||||
|
linecol = rnd(0,64)
|
||||||
|
|
||||||
|
if self.x > 360:
|
||||||
|
self.velX = -self.velX;
|
||||||
|
self.x = 360
|
||||||
|
linecol = rnd(0,64)
|
||||||
|
|
||||||
|
if self.y > 203:
|
||||||
|
self.velY = -self.velY;
|
||||||
|
self.y = 203
|
||||||
|
linecol = rnd(0,64)
|
||||||
|
|
||||||
|
|
||||||
|
circle(self.x, self.y, 3, self.color)
|
||||||
|
|
||||||
|
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import ball
|
||||||
|
|
||||||
linecol = 15
|
linecol = 15
|
||||||
def draw_line(x0, y0, x1, y1, c):
|
def draw_line(x0, y0, x1, y1, c):
|
||||||
dx = abs(x1 - x0)
|
dx = abs(x1 - x0)
|
||||||
@ -17,58 +19,10 @@ def draw_line(x0, y0, x1, y1, c):
|
|||||||
y0 += sy
|
y0 += sy
|
||||||
|
|
||||||
|
|
||||||
class ball:
|
|
||||||
def __init__(self):
|
|
||||||
self.x = rnd(10, 100)
|
|
||||||
self.y = rnd(10, 100)
|
|
||||||
self.velX = rnd(-5,5)
|
|
||||||
self.velY = rnd(-5,5)
|
|
||||||
self.color = rnd(0,64)
|
|
||||||
|
|
||||||
def draw(self):
|
|
||||||
global linecol
|
|
||||||
self.x += self.velX;
|
|
||||||
self.y += self.velY;
|
|
||||||
|
|
||||||
if self.x < 0:
|
|
||||||
self.velX = -self.velX;
|
|
||||||
self.x = 0
|
|
||||||
linecol = rnd(0,64)
|
|
||||||
if self.y < 0:
|
|
||||||
self.velY = -self.velY;
|
|
||||||
self.y = 0
|
|
||||||
linecol = rnd(0,64)
|
|
||||||
|
|
||||||
if self.x > 360:
|
|
||||||
self.velX = -self.velX;
|
|
||||||
self.x = 360
|
|
||||||
linecol = rnd(0,64)
|
|
||||||
|
|
||||||
if self.y > 203:
|
|
||||||
self.velY = -self.velY;
|
|
||||||
self.y = 203
|
|
||||||
linecol = rnd(0,64)
|
|
||||||
|
|
||||||
|
|
||||||
circle(self.x, self.y, 3, self.color)
|
|
||||||
|
|
||||||
# i = 0
|
|
||||||
# def update():
|
|
||||||
# global i
|
|
||||||
# i += 1
|
|
||||||
# #clear(43)
|
|
||||||
# x = sin(i * 0.071234) * 50 + (360 / 2)
|
|
||||||
# y = sin(i * 0.0236) * 20 + (203 / 2)
|
|
||||||
# circle(x + sin(i * 0.05) * 30, y + cos(i * 0.05) * 30, 5, 15)
|
|
||||||
# circle(x + sin(i * 0.05) * 30, y + cos(i * 0.05) * 30, 3, 11)
|
|
||||||
# circle(x + -sin(i * 0.05) * 30, y + -cos(i * 0.05) * 30, 5, 17)
|
|
||||||
# circle(x + -sin(i * 0.05) * 30, y + -cos(i * 0.05) * 30, 3, 19)
|
|
||||||
|
|
||||||
|
|
||||||
balls = []
|
balls = []
|
||||||
|
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
balls.append(ball())
|
balls.append(ball.ball())
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
|
|
||||||
@ -101,3 +55,5 @@ def update():
|
|||||||
circle(mouseX, mouseY, 10, counter % 64)
|
circle(mouseX, mouseY, 10, counter % 64)
|
||||||
|
|
||||||
|
|
||||||
|
clear(0)
|
||||||
|
text("test", 2,2, 32)
|
||||||
@ -22,15 +22,11 @@ Graphics::Graphics(int screenWidth, int screenHeight, int startupScale) : m_scre
|
|||||||
|
|
||||||
m_virtualScreenLocalBounds = {0.0f, 0.0f, (float)m_virtualScreen.texture.width, -(float)m_virtualScreen.texture.height };
|
m_virtualScreenLocalBounds = {0.0f, 0.0f, (float)m_virtualScreen.texture.width, -(float)m_virtualScreen.texture.height };
|
||||||
m_virtualScreenWindowBounds = {0.0f, 0.0f, (float)m_windowWidth, (float)m_windowHeight};
|
m_virtualScreenWindowBounds = {0.0f, 0.0f, (float)m_windowWidth, (float)m_windowHeight};
|
||||||
updateFunction = nullptr;
|
|
||||||
calculateScreenPositionInWindow();
|
calculateScreenPositionInWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::draw(StateManager* stateManager) {
|
void Graphics::draw(StateManager* stateManager) {
|
||||||
|
|
||||||
// vm->builtins->attr().set("mouseX", pkpy::py_var(vm, mouseX()));
|
|
||||||
// vm->builtins->attr().set("mouseY", pkpy::py_var(vm, mouseY()));
|
|
||||||
|
|
||||||
m_windowShouldClose = WindowShouldClose();
|
m_windowShouldClose = WindowShouldClose();
|
||||||
|
|
||||||
if (IsWindowResized()) {
|
if (IsWindowResized()) {
|
||||||
@ -179,13 +175,6 @@ void Graphics::Text(std::string s, int x, int y, int paletteIndex) {
|
|||||||
DrawText(s.c_str(), x, y, 5, Palette[paletteIndex]);
|
DrawText(s.c_str(), x, y, 5, Palette[paletteIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::searchForDrawFunc(pkpy::VM* vm) {
|
|
||||||
updateFunction = vm->eval("update");
|
|
||||||
if(updateFunction == nullptr){
|
|
||||||
std::cout << "Can't find update function" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::beginDraw() {
|
void Graphics::beginDraw() {
|
||||||
BeginTextureMode(m_virtualScreen);
|
BeginTextureMode(m_virtualScreen);
|
||||||
}
|
}
|
||||||
@ -194,6 +183,11 @@ void Graphics::endDraw() {
|
|||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::updateVMMouse(pkpy::VM* vm) {
|
||||||
|
vm->builtins->attr().set("mouseX", pkpy::py_var(vm, mouseX()));
|
||||||
|
vm->builtins->attr().set("mouseY", pkpy::py_var(vm, mouseY()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,6 @@ private:
|
|||||||
Vector2 m_origin; // position of rect texture on window
|
Vector2 m_origin; // position of rect texture on window
|
||||||
Rectangle m_virtualScreenLocalBounds; // virtual screen bounds
|
Rectangle m_virtualScreenLocalBounds; // virtual screen bounds
|
||||||
RenderTexture2D m_virtualScreen; // actual pixel screen
|
RenderTexture2D m_virtualScreen; // actual pixel screen
|
||||||
pkpy::PyObject* updateFunction;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -47,6 +46,8 @@ public:
|
|||||||
void beginDraw();
|
void beginDraw();
|
||||||
void endDraw();
|
void endDraw();
|
||||||
|
|
||||||
|
void updateVMMouse(pkpy::VM* vm);
|
||||||
|
|
||||||
void loadPalette(std::string path);
|
void loadPalette(std::string path);
|
||||||
int mouseX();
|
int mouseX();
|
||||||
int mouseY();
|
int mouseY();
|
||||||
@ -54,9 +55,6 @@ public:
|
|||||||
|
|
||||||
void bindMethods(pkpy::VM* vm);
|
void bindMethods(pkpy::VM* vm);
|
||||||
|
|
||||||
void searchForDrawFunc(pkpy::VM* vm);
|
|
||||||
|
|
||||||
|
|
||||||
void Clear(int paletteIndex);
|
void Clear(int paletteIndex);
|
||||||
void Pixel(int x, int y, int paletteIndex);
|
void Pixel(int x, int y, int paletteIndex);
|
||||||
void Circle(int x, int y, int radius, int paletteIndex);
|
void Circle(int x, int y, int radius, int paletteIndex);
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
|
||||||
|
std::string Pycron::PythonDirectory = "./python";
|
||||||
|
|
||||||
std::string loadFileToString(const std::string& filename) {
|
std::string loadFileToString(const std::string& filename) {
|
||||||
std::ifstream file(filename); // Open the file
|
std::ifstream file(filename); // Open the file
|
||||||
@ -24,30 +25,19 @@ std::string loadFileToString(const std::string& filename) {
|
|||||||
|
|
||||||
Pycron::Pycron() {
|
Pycron::Pycron() {
|
||||||
SetTraceLogLevel(LOG_ERROR);
|
SetTraceLogLevel(LOG_ERROR);
|
||||||
|
|
||||||
m_graphics = new Graphics{virtualScreenWidth, virtualScreenHeight, initialScale};
|
|
||||||
m_graphics->loadPalette("../resources/palette2.hex");
|
|
||||||
|
|
||||||
m_stateManager = new StateManager(this);
|
|
||||||
|
|
||||||
m_vm = new pkpy::VM();
|
m_vm = new pkpy::VM();
|
||||||
bindMethods();
|
bindMethods();
|
||||||
|
|
||||||
|
m_graphics = new Graphics{virtualScreenWidth, virtualScreenHeight, initialScale};
|
||||||
|
m_graphics->loadPalette("../resources/palette2.hex");
|
||||||
m_graphics->bindMethods(m_vm);
|
m_graphics->bindMethods(m_vm);
|
||||||
|
m_graphics->updateVMMouse(m_vm);
|
||||||
|
m_stateManager = new StateManager(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string python = loadFileToString("../python/main.py");
|
std::string python = loadFileToString("../python/main.py");
|
||||||
|
|
||||||
m_graphics->beginDraw();
|
|
||||||
m_graphics->Clear(0);
|
|
||||||
try {
|
|
||||||
pkpy::CodeObject_ code = m_vm->compile(python, "main.py", pkpy::EXEC_MODE, false);
|
|
||||||
m_vm->_exec(code, m_vm->_main);
|
|
||||||
m_graphics->searchForDrawFunc(m_vm);
|
|
||||||
}catch (pkpy::Exception e) {
|
|
||||||
std::cout << e.summary() << std::endl;
|
|
||||||
}
|
|
||||||
m_graphics->endDraw();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pycron::~Pycron(){
|
Pycron::~Pycron(){
|
||||||
@ -64,6 +54,7 @@ void Pycron::StartGameLoop() {
|
|||||||
if (IsKeyPressed(KEY_F)) {
|
if (IsKeyPressed(KEY_F)) {
|
||||||
m_graphics->toggleFullScreen();
|
m_graphics->toggleFullScreen();
|
||||||
}
|
}
|
||||||
|
m_graphics->updateVMMouse(m_vm);
|
||||||
m_graphics->draw(this->m_stateManager);
|
m_graphics->draw(this->m_stateManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,16 +8,21 @@ class Graphics;
|
|||||||
class StateManager;
|
class StateManager;
|
||||||
|
|
||||||
class Pycron {
|
class Pycron {
|
||||||
|
public:
|
||||||
|
static std::string PythonDirectory;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int virtualScreenWidth = 360;
|
const int virtualScreenWidth = 360;
|
||||||
const int virtualScreenHeight = 203;
|
const int virtualScreenHeight = 203;
|
||||||
const int initialScale = 3;
|
const int initialScale = 3;
|
||||||
Graphics* m_graphics;
|
|
||||||
StateManager* m_stateManager;
|
StateManager* m_stateManager;
|
||||||
pkpy::VM* m_vm;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
pkpy::VM* m_vm;
|
||||||
|
Graphics* m_graphics;
|
||||||
|
|
||||||
|
|
||||||
Pycron();
|
Pycron();
|
||||||
~Pycron();
|
~Pycron();
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include "StateManager.h"
|
#include "StateManager.h"
|
||||||
|
|
||||||
StateManager::StateManager(Pycron *pycron) : m_pycron(pycron){
|
StateManager::StateManager(Pycron *pycron) : m_pycron(pycron){
|
||||||
m_gameState = new GameState(this);
|
m_gameState = new GameState(this, m_pycron->m_vm);
|
||||||
RequestStateChange(GAME);
|
RequestStateChange(GAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,9 +19,15 @@ void StateManager::RequestStateChange(StateManager::StateType state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_currentState){
|
if(m_currentState){
|
||||||
|
// Game state needs ability to draw during code loading
|
||||||
|
if(state == GAME){
|
||||||
|
m_pycron->m_graphics->beginDraw();
|
||||||
|
m_currentState->OnEnter();
|
||||||
|
m_pycron->m_graphics->endDraw();
|
||||||
|
}else{
|
||||||
m_currentState->OnEnter();
|
m_currentState->OnEnter();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateManager::Draw(Graphics *graphics) {
|
void StateManager::Draw(Graphics *graphics) {
|
||||||
|
|||||||
@ -3,18 +3,28 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
GameState::GameState(StateManager *stateManager) : State(stateManager) {
|
GameState::GameState(StateManager *stateManager, pkpy::VM* vm) : State(stateManager), m_vm(vm){
|
||||||
|
m_updateFunction = nullptr;
|
||||||
|
m_previousError = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GameState::Draw(Graphics *graphics) {
|
void GameState::Draw(Graphics *graphics) {
|
||||||
graphics->Text("Test", 10, 10, 10);
|
try{
|
||||||
|
if(m_updateFunction != nullptr){
|
||||||
|
m_vm->call(m_updateFunction);
|
||||||
|
}
|
||||||
|
} catch(pkpy::Exception e){
|
||||||
|
m_previousError = e.summary();
|
||||||
|
std::cout << e.summary() << "\n";
|
||||||
|
m_errorThrown = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::OnEnter() {
|
void GameState::OnEnter() {
|
||||||
//TODO: Python preprocess scripts
|
PreProcessScripts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::OnExit() {
|
void GameState::OnExit() {
|
||||||
@ -25,3 +35,63 @@ void GameState::onKeyPressed(int key) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameState::PreProcessScripts() {
|
||||||
|
m_previousError = "";
|
||||||
|
m_errorThrown = false;
|
||||||
|
std::unordered_map<std::string, std::string> pythonSources = readPythonFiles(Pycron::PythonDirectory);
|
||||||
|
loadPythonModules(pythonSources);
|
||||||
|
std::string main = pythonSources[MAIN_FILE];
|
||||||
|
|
||||||
|
pkpy::CodeObject_ code = m_vm->compile(main, MAIN_FILE, pkpy::EXEC_MODE, false);
|
||||||
|
try{
|
||||||
|
m_vm->_exec(code, m_vm->_main);
|
||||||
|
m_updateFunction = m_vm->eval("update");
|
||||||
|
// if(m_updateFunction == nullptr){
|
||||||
|
// m_previousError = "";
|
||||||
|
// }
|
||||||
|
}catch(pkpy::Exception e){
|
||||||
|
m_previousError = e.summary();
|
||||||
|
std::cout << e.summary() << "\n";
|
||||||
|
m_errorThrown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> GameState::readPythonFiles(const std::string &dir) {
|
||||||
|
std::unordered_map<std::string, std::string> fileContents;
|
||||||
|
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(dir)) {
|
||||||
|
if (entry.is_regular_file()) {
|
||||||
|
std::ifstream file(entry.path());
|
||||||
|
std::filesystem::path path(entry.path());
|
||||||
|
std::string fileName = path.filename().string();
|
||||||
|
if (file.is_open()) {
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << file.rdbuf();
|
||||||
|
fileContents[fileName] = buffer.str();
|
||||||
|
file.close();
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error opening file: " << entry.path() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameState::loadPythonModules(std::unordered_map<std::string, std::string> &fileContents) {
|
||||||
|
for(const auto& pair : fileContents){
|
||||||
|
try{
|
||||||
|
if(pair.first != MAIN_FILE){
|
||||||
|
size_t pos = pair.first.find_last_of(".");
|
||||||
|
if(pos == std::string::npos || pos == 0){
|
||||||
|
throw pkpy::Exception("Invalid file name");
|
||||||
|
}
|
||||||
|
std::string moduleName = pair.first.substr(0, pos);
|
||||||
|
m_vm->_lazy_modules[moduleName.c_str()] = pair.second;
|
||||||
|
}
|
||||||
|
}catch(pkpy::Exception e){
|
||||||
|
std::cout << e.summary() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,27 @@
|
|||||||
class GameState : public State {
|
class GameState : public State {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameState(StateManager* stateManager);
|
|
||||||
|
const std::string MAIN_FILE = "main.py";
|
||||||
|
std::string m_previousError;
|
||||||
|
bool m_errorThrown = false;
|
||||||
|
|
||||||
|
GameState(StateManager* stateManager, pkpy::VM* vm);
|
||||||
|
|
||||||
void Draw(Graphics* graphics) override;
|
void Draw(Graphics* graphics) override;
|
||||||
void OnEnter() override;
|
void OnEnter() override;
|
||||||
void OnExit() override;
|
void OnExit() override;
|
||||||
void onKeyPressed(int key) override;
|
void onKeyPressed(int key) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
pkpy::VM* m_vm;
|
||||||
|
pkpy::PyObject* m_updateFunction;
|
||||||
|
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> readPythonFiles(const std::string& dir);
|
||||||
|
void loadPythonModules(std::unordered_map<std::string, std::string>& fileContents);
|
||||||
|
void PreProcessScripts();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user