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
|
||||
def draw_line(x0, y0, x1, y1, c):
|
||||
dx = abs(x1 - x0)
|
||||
@ -5,7 +7,7 @@ def draw_line(x0, y0, x1, y1, c):
|
||||
sx = 1 if x0 < x1 else -1
|
||||
sy = 1 if y0 < y1 else -1
|
||||
err = dx - dy
|
||||
|
||||
|
||||
while x0 != x1 or y0 != y1:
|
||||
pixel(x0, y0, c)
|
||||
e2 = 2 * err
|
||||
@ -17,58 +19,10 @@ def draw_line(x0, y0, x1, y1, c):
|
||||
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 = []
|
||||
|
||||
for i in range(2):
|
||||
balls.append(ball())
|
||||
balls.append(ball.ball())
|
||||
|
||||
counter = 0
|
||||
|
||||
@ -81,23 +35,25 @@ def update():
|
||||
|
||||
for ball in balls:
|
||||
ball.draw()
|
||||
|
||||
|
||||
for i in range(64):
|
||||
for j in range(20):
|
||||
if(i == 0 or i == 63 or j == 0 or j == 20):
|
||||
pixel(i * 4, j, i)
|
||||
pixel(i * 4 + 1, j, i)
|
||||
pixel(i * 4 + 2, j, i)
|
||||
pixel(i * 4 + 3, j, i)
|
||||
pixel(i * 4 + 1, j, i)
|
||||
pixel(i * 4 + 2, j, i)
|
||||
pixel(i * 4 + 3, j, i)
|
||||
else:
|
||||
pixel(i * 4, j, 0)
|
||||
pixel(i * 4 + 1, j, 0)
|
||||
pixel(i * 4 + 2, j, 0)
|
||||
pixel(i * 4 + 3, j, 0)
|
||||
pixel(i * 4 + 1, j, 0)
|
||||
pixel(i * 4 + 2, j, 0)
|
||||
pixel(i * 4 + 3, j, 0)
|
||||
t = "Hello from python FPS:" + str(fps()) + " X:" + str(mouseX) + " Y:" + str(mouseY)
|
||||
for i in range(len(t)):
|
||||
text(t[i], 4 + (i * 7), 4, 20 + i)
|
||||
|
||||
|
||||
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_virtualScreenWindowBounds = {0.0f, 0.0f, (float)m_windowWidth, (float)m_windowHeight};
|
||||
updateFunction = nullptr;
|
||||
calculateScreenPositionInWindow();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
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() {
|
||||
BeginTextureMode(m_virtualScreen);
|
||||
}
|
||||
@ -194,6 +183,11 @@ void Graphics::endDraw() {
|
||||
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
|
||||
Rectangle m_virtualScreenLocalBounds; // virtual screen bounds
|
||||
RenderTexture2D m_virtualScreen; // actual pixel screen
|
||||
pkpy::PyObject* updateFunction;
|
||||
|
||||
|
||||
private:
|
||||
@ -47,6 +46,8 @@ public:
|
||||
void beginDraw();
|
||||
void endDraw();
|
||||
|
||||
void updateVMMouse(pkpy::VM* vm);
|
||||
|
||||
void loadPalette(std::string path);
|
||||
int mouseX();
|
||||
int mouseY();
|
||||
@ -54,9 +55,6 @@ public:
|
||||
|
||||
void bindMethods(pkpy::VM* vm);
|
||||
|
||||
void searchForDrawFunc(pkpy::VM* vm);
|
||||
|
||||
|
||||
void Clear(int paletteIndex);
|
||||
void Pixel(int x, int y, int paletteIndex);
|
||||
void Circle(int x, int y, int radius, int paletteIndex);
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "Utilities.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
std::string Pycron::PythonDirectory = "./python";
|
||||
|
||||
std::string loadFileToString(const std::string& filename) {
|
||||
std::ifstream file(filename); // Open the file
|
||||
@ -24,30 +25,19 @@ std::string loadFileToString(const std::string& filename) {
|
||||
|
||||
Pycron::Pycron() {
|
||||
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();
|
||||
bindMethods();
|
||||
|
||||
m_graphics = new Graphics{virtualScreenWidth, virtualScreenHeight, initialScale};
|
||||
m_graphics->loadPalette("../resources/palette2.hex");
|
||||
m_graphics->bindMethods(m_vm);
|
||||
m_graphics->updateVMMouse(m_vm);
|
||||
m_stateManager = new StateManager(this);
|
||||
|
||||
|
||||
|
||||
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(){
|
||||
@ -64,6 +54,7 @@ void Pycron::StartGameLoop() {
|
||||
if (IsKeyPressed(KEY_F)) {
|
||||
m_graphics->toggleFullScreen();
|
||||
}
|
||||
m_graphics->updateVMMouse(m_vm);
|
||||
m_graphics->draw(this->m_stateManager);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,16 +8,21 @@ class Graphics;
|
||||
class StateManager;
|
||||
|
||||
class Pycron {
|
||||
public:
|
||||
static std::string PythonDirectory;
|
||||
|
||||
private:
|
||||
const int virtualScreenWidth = 360;
|
||||
const int virtualScreenHeight = 203;
|
||||
const int initialScale = 3;
|
||||
Graphics* m_graphics;
|
||||
StateManager* m_stateManager;
|
||||
pkpy::VM* m_vm;
|
||||
|
||||
public:
|
||||
|
||||
pkpy::VM* m_vm;
|
||||
Graphics* m_graphics;
|
||||
|
||||
|
||||
Pycron();
|
||||
~Pycron();
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "StateManager.h"
|
||||
|
||||
StateManager::StateManager(Pycron *pycron) : m_pycron(pycron){
|
||||
m_gameState = new GameState(this);
|
||||
m_gameState = new GameState(this, m_pycron->m_vm);
|
||||
RequestStateChange(GAME);
|
||||
}
|
||||
|
||||
@ -19,9 +19,15 @@ void StateManager::RequestStateChange(StateManager::StateType state) {
|
||||
}
|
||||
|
||||
if(m_currentState){
|
||||
m_currentState->OnEnter();
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StateManager::Draw(Graphics *graphics) {
|
||||
|
||||
@ -3,18 +3,28 @@
|
||||
//
|
||||
|
||||
#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) {
|
||||
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() {
|
||||
//TODO: Python preprocess scripts
|
||||
PreProcessScripts();
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
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 OnEnter() override;
|
||||
void OnExit() 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