From df9e305828e986415c088c7dfed17759ae30602a Mon Sep 17 00:00:00 2001 From: Bobby Lucero Date: Fri, 26 Apr 2024 23:53:53 -0400 Subject: [PATCH] Key pressed, key down, rectangle, python demo scene --- python/main.py | 211 +++++++++++++++++++++++++------------- python/scene.py | 10 ++ src/Graphics/Graphics.cpp | 27 ++--- src/Graphics/Graphics.h | 7 +- src/Pycron.cpp | 20 +++- src/Pycron.h | 2 + 6 files changed, 188 insertions(+), 89 deletions(-) create mode 100644 python/scene.py diff --git a/python/main.py b/python/main.py index 55b0656..a61b235 100644 --- a/python/main.py +++ b/python/main.py @@ -1,82 +1,153 @@ -# import ball +from scene import Scene -# linecol = 15 -# def draw_line(x0, y0, x1, y1, c): -# dx = abs(x1 - x0) -# dy = abs(y1 - y0) -# sx = 1 if x0 < x1 else -1 -# sy = 1 if y0 < y1 else -1 -# err = dx - dy +fireGradient = [9, 9, 18, 18, 17, 16, 15, 14, 15, 14, 16, 14, 14,14,16, 2, 1] +waterGradient = [9, 9, 43, 43, 42, 41, 40, 39, 40, 39, 41, 39, 39,39,41, 2, 1] -# while x0 != x1 or y0 != y1: -# pixel(x0, y0, c) -# e2 = 2 * err -# if e2 > -dy: -# err -= dy -# x0 += sx -# if e2 < dx: -# err += dx -# y0 += sy +class Particle: + def __init__(self, x, y, velX, velY): + self.x = x + self.y = y + self.velX = velX + self.velY = velY + self.c = fireGradient[0] + self.size = 5 + +class Palette(Scene): + + def __init__(self): + super().__init__() + + def update(self): + pass + + def draw(self): + clear(0) + + for i in range(8): + for j in range(8): + rectangle(10 + (i * 20), 10 + (j * 20), 18, 18, (j * 8 + i)) + text(str(j * 8 + i), 10 + (i * 20), 10 + (j * 20), 9) -# balls = [] +class Main(Scene): -# for i in range(2): -# balls.append(ball.Ball()) + def __init__(self): + super().__init__() + self.fireParts = [] + self.waterParts = [] + for i in range(10): + self.fireParts.append(Particle(width/2, height/2, rnd(-1, 1), rnd(-1, 1))) + self.waterParts.append(Particle(width/2, height/2, rnd(-1, 1), rnd(-1, 1))) -# counter = 0 - -# def update(): -# global linecol -# global counter -# counter += 1 -# #clear(0) -# draw_line(balls[0].x, balls[0].y, balls[1].x, balls[1].y, linecol) - -# for ball in balls: -# ball.draw() - -# for i in range(64): -# for j in range(20): -# pixel(i * 4, j, i) -# pixel(i * 4 + 1, j, i) -# pixel(i * 4 + 2, j, i) -# pixel(i * 4 + 3, j, i) - -# 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) + self.counter = 0 -# clear(0) -# text("test", 2,2, 32) -import easing -import time -funcs = [easing.InSine, easing.OutSine, easing.InOutSine, easing.InQuad, easing.OutQuad, easing.InOutQuad, easing.InBounce, easing.OutBounce, easing.InOutBounce, easing.InElastic, easing.OutElastic, easing.InOutElastic] + def update(self): + global mouseVelX + global mouseVelY + + self.counter += 1 + + for p in self.fireParts[:]: + p.x += p.velX + p.y += p.velY + p.velX += rnd(-0.3,0.3) + p.velY += rnd(-0.3,0.3) + + idx = int(p.size / 5.0 * len(fireGradient) - 1) + + p.c = fireGradient[(len(fireGradient) - 1) - idx] + + if(p.size < 1): + p.size -= 0.01 + else: + p.size -= 0.05 + if(p.size < 0): + self.fireParts.remove(p) + + for p in self.waterParts[:]: + p.x += p.velX + p.y += p.velY + p.velX += rnd(-0.3,0.3) + p.velY += rnd(-0.3,0.3) + + idx = int(p.size / 5.0 * len(fireGradient) - 1) + + p.c = waterGradient[(len(waterGradient) - 1) - idx] + + if(p.size < 1): + p.size -= 0.01 + else: + p.size -= 0.05 + if(p.size < 0): + self.waterParts.remove(p) + + if(key(67)): + x1 = mouseX + (sin(self.counter * 0.1) * 60) + y1 = mouseY + (cos(self.counter * 0.1) * 60) + + x2 = mouseX + (sin(self.counter * 0.1 + (3.141592653)) * 60) + y2 = mouseY + (cos(self.counter * 0.1 + (3.141592653)) * 60) + for i in range(2): + self.fireParts.append(Particle(x1, y1, rnd(-1,1) + mouseVelX * 0.25, rnd(-1,1) + mouseVelY * 0.25)) + self.waterParts.append(Particle(x2, y2, rnd(-1,1) + mouseVelX * 0.25, rnd(-1,1) + mouseVelY * 0.25)) + + def draw(self): + clear(44) + for p in self.fireParts: + if(p.size <= 1): + pixel(p.x, p.y, p.c) + else: + circle(p.x, p.y, int(p.size), p.c) + + for p in self.waterParts: + if(p.size <= 1): + pixel(p.x, p.y, p.c) + else: + circle(p.x, p.y, int(p.size), p.c) + text("C to add particles, T to toggle palette", 3, 3, 0) + text("C to add particles, T to toggle palette", 2, 2, 30) + text("Num Particles: " + str(len(self.fireParts) + len(self.waterParts)), 3, 16, 0) + text("Num Particles: " + str(len(self.fireParts) + len(self.waterParts)), 2, 15, 9) + + +paletteScene = Palette() +mainScene = Main() +current_scene = mainScene + +oldMouseX = 0 +oldMouseY = 0 + +mouseVelX = 0 +mouseVelY = 0 + +KEY_T = 84 + +switch = False -test = {"1" : 0, "2" : 4} -counter = 0 -x = 0 def update(): - cls() - global x - global counter - counter += 0.008 - x += 0.5 - if(counter > 1): - counter = 0 - - for i in range(len(funcs)): - pos = funcs[i](counter) - circle(100 + (pos * 200), 10 + (14 * i), 5, i + 35) + global switch + global current_scene + global mouseVelX + global mouseVelY + global oldMouseX + global oldMouseY - text("The FPS: " + str(fps()), 2, 2, 9) - + mouseVelX = (mouseX - oldMouseX) + mouseVelY = (mouseY - oldMouseY) -def cls(): - for i in range(width): - for j in range(height): - pixel(i , j, int(i + j + x) % 64) - \ No newline at end of file + oldMouseX = mouseX + oldMouseY = mouseY + + + if(keyp(KEY_T)): + switch = not switch + if(switch): + current_scene = paletteScene + else: + current_scene = mainScene + + current_scene.update() + current_scene.draw() + + circle(mouseX, mouseY, 3, 30) diff --git a/python/scene.py b/python/scene.py new file mode 100644 index 0000000..9265bc5 --- /dev/null +++ b/python/scene.py @@ -0,0 +1,10 @@ +class Scene: + + def __init__(self): + pass + + def update(self): + pass + + def draw(self): + pass \ No newline at end of file diff --git a/src/Graphics/Graphics.cpp b/src/Graphics/Graphics.cpp index a34eb7c..11ae986 100644 --- a/src/Graphics/Graphics.cpp +++ b/src/Graphics/Graphics.cpp @@ -19,7 +19,7 @@ Graphics::Graphics(int screenWidth, int screenHeight, int startupScale) : m_scre InitWindow(m_startupScreenWidth, m_startupScreenHeight, "test"); SetTargetFPS(60); m_virtualScreen = LoadRenderTexture(screenWidth, screenHeight); - + m_origin = {0,0}; 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}; calculateScreenPositionInWindow(); @@ -36,17 +36,6 @@ void Graphics::draw(StateManager* stateManager) { } BeginTextureMode(m_virtualScreen); -// ////////// -// try{ -// if(updateFunction != nullptr) -// vm->call(updateFunction); -// } catch(pkpy::Exception e){ -// std::cout << e.summary() << std::endl; -// } -// -// Circle(150,100,50,1); -// Text("Hello from C++", 120, 95, 9); -// ////////// stateManager->Draw(this); @@ -148,6 +137,16 @@ void Graphics::bindMethods(pkpy::VM *vm) { return vm->None; }}); + vm->bind(vm->builtins, "rectangle(x: int, y: int, width: int, height: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){{ + float x = pkpy::py_cast(vm, args[0]); + float y = pkpy::py_cast(vm, args[1]); + float width = pkpy::py_cast(vm, args[2]); + float height = pkpy::py_cast(vm, args[3]); + float paletteIndex = pkpy::py_cast(vm, args[4]); + this->Rectangle(x, y, width, height, paletteIndex); + return vm->None; + }}); + vm->bind(vm->builtins, "text(t: string, x: int, y: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){ pkpy::PyObject* func_str = vm->builtins->attr("str"); pkpy::PyObject* result = vm->call(func_str, args[0]); @@ -174,6 +173,10 @@ void Graphics::Circle(int x, int y, int radius, int paletteIndex) { DrawCircle(x, y, radius, Palette[paletteIndex]); } +void Graphics::Rectangle(int x, int y, int width, int height, int paletteIndex) { + DrawRectangle(x, y, width, height, Palette[paletteIndex]); +} + void Graphics::Text(std::string s, int x, int y, int paletteIndex) { DrawText(s.c_str(), x, y, 5, Palette[paletteIndex]); } diff --git a/src/Graphics/Graphics.h b/src/Graphics/Graphics.h index 4af319e..242cc2e 100644 --- a/src/Graphics/Graphics.h +++ b/src/Graphics/Graphics.h @@ -29,10 +29,10 @@ private: public: // virtual screen - int m_screenWidth; - int m_screenHeight; + int m_screenWidth = 0; + int m_screenHeight = 0; - bool m_windowShouldClose; + bool m_windowShouldClose = false; static std::vector Palette; @@ -58,6 +58,7 @@ public: void Clear(int paletteIndex); void Pixel(int x, int y, int paletteIndex); void Circle(int x, int y, int radius, int paletteIndex); + void Rectangle(int x, int y, int width, int height, int paletteIndex); void Text(std::string s, int x, int y, int paletteIndex); diff --git a/src/Pycron.cpp b/src/Pycron.cpp index 3291bba..3261168 100644 --- a/src/Pycron.cpp +++ b/src/Pycron.cpp @@ -60,22 +60,24 @@ void Pycron::StartGameLoop() { } void Pycron::bindMethods() { - m_vm->bind(m_vm->builtins, "rnd(min: int, max: int) -> int", getRandomNumber); + m_vm->bind(m_vm->builtins, "rnd(min: float, max: float) -> int", getRandomNumber); m_vm->bind(m_vm->builtins, "sin(num: float) -> float", getSin); m_vm->bind(m_vm->builtins, "cos(num: float) -> float", getCos); m_vm->bind(m_vm->builtins, "fps() -> int", getFPS); + m_vm->bind(m_vm->builtins, "keyp(keycode: int) -> bool", getKeyPressed); + m_vm->bind(m_vm->builtins, "key(keycode: int) -> bool", getKeyDown); } pkpy::PyObject* Pycron::getRandomNumber(pkpy::VM* vm, pkpy::ArgsView args) { - int min = pkpy::py_cast(vm, args[0]); - int max = pkpy::py_cast(vm, args[1]); + float min = pkpy::py_cast(vm, args[0]); + float max = pkpy::py_cast(vm, args[1]); // Seed the random number generator with a random device std::random_device rd; std::mt19937 gen(rd()); // Define a uniform distribution for the range [min, max] - std::uniform_int_distribution distribution(min, max); + std::uniform_real_distribution distribution(min, max); // Generate a random number within the specified range return pkpy::py_var(vm, distribution(gen)); @@ -95,3 +97,13 @@ pkpy::PyObject* Pycron::getFPS(pkpy::VM* vm, pkpy::ArgsView args) { return pkpy::py_var(vm, GetFPS()); } +pkpy::PyObject *Pycron::getKeyPressed(pkpy::VM *vm, pkpy::ArgsView args) { + bool pressed = IsKeyPressed(pkpy::py_cast(vm, args[0])); + return pkpy::py_var(vm, pressed); +} + +pkpy::PyObject *Pycron::getKeyDown(pkpy::VM *vm, pkpy::ArgsView args) { + bool held = IsKeyDown(pkpy::py_cast(vm, args[0])); + return pkpy::py_var(vm, held); +} + diff --git a/src/Pycron.h b/src/Pycron.h index 7b2ec44..7f8575f 100644 --- a/src/Pycron.h +++ b/src/Pycron.h @@ -33,5 +33,7 @@ public: static pkpy::PyObject* getSin(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getCos(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getFPS(pkpy::VM* vm, pkpy::ArgsView args); + static pkpy::PyObject* getKeyPressed(pkpy::VM* vm, pkpy::ArgsView args); + static pkpy::PyObject* getKeyDown(pkpy::VM* vm, pkpy::ArgsView args); };