Created Basic Engine
This project is kind of a dead end.
This commit is contained in:
parent
e8db72e3f9
commit
ae733d164a
0
core/__init__.py
Normal file
0
core/__init__.py
Normal file
BIN
core/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
core/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
core/__pycache__/input_handler.cpython-311.pyc
Normal file
BIN
core/__pycache__/input_handler.cpython-311.pyc
Normal file
Binary file not shown.
BIN
core/__pycache__/lua_api.cpython-311.pyc
Normal file
BIN
core/__pycache__/lua_api.cpython-311.pyc
Normal file
Binary file not shown.
BIN
core/__pycache__/renderer.cpython-311.pyc
Normal file
BIN
core/__pycache__/renderer.cpython-311.pyc
Normal file
Binary file not shown.
15
core/input_handler.py
Normal file
15
core/input_handler.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# engine/input_handler.py
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class InputHandler:
|
||||||
|
def __init__(self):
|
||||||
|
self.keys = {}
|
||||||
|
|
||||||
|
def process_event(self, event):
|
||||||
|
if event.type == pygame.KEYDOWN:
|
||||||
|
self.keys[event.key] = True
|
||||||
|
elif event.type == pygame.KEYUP:
|
||||||
|
self.keys[event.key] = False
|
||||||
|
|
||||||
|
def is_key_pressed(self, key):
|
||||||
|
return self.keys.get(key, False)
|
64
core/lua_api.py
Normal file
64
core/lua_api.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# engine/lua_api.py
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class LuaAPI:
|
||||||
|
def __init__(self, renderer, input_handler):
|
||||||
|
self.renderer = renderer
|
||||||
|
self.input_handler = input_handler
|
||||||
|
|
||||||
|
def get_api(self, lua):
|
||||||
|
# Expose functions to Lua
|
||||||
|
lua.globals()['cls'] = self.cls
|
||||||
|
lua.globals()['px'] = self.px
|
||||||
|
lua.globals()['spr'] = self.spr
|
||||||
|
lua.globals()['btn'] = self.btn
|
||||||
|
|
||||||
|
def cls(self, color=0):
|
||||||
|
self.renderer.clear(color)
|
||||||
|
|
||||||
|
def px(self, x, y, color=1):
|
||||||
|
self.renderer.draw_pixel(x, y, color)
|
||||||
|
|
||||||
|
def spr(self, x, y, sprite, color=1):
|
||||||
|
"""
|
||||||
|
Draws a sprite at position (x, y).
|
||||||
|
|
||||||
|
:param x: X-coordinate
|
||||||
|
:param y: Y-coordinate
|
||||||
|
:param sprite: 2D list representing the sprite
|
||||||
|
:param color: Color index
|
||||||
|
"""
|
||||||
|
# Convert Lua table to Python list if necessary
|
||||||
|
if hasattr(sprite, 'keys'):
|
||||||
|
# If sprite is a Lua table, convert it to a Python list
|
||||||
|
sprite = [sprite[i + 1] for i in range(len(sprite))]
|
||||||
|
self.renderer.draw_sprite(x, y, sprite, color)
|
||||||
|
|
||||||
|
def btn(self, button):
|
||||||
|
"""
|
||||||
|
Checks if a specific button is pressed.
|
||||||
|
|
||||||
|
Button Mapping:
|
||||||
|
0: Left Arrow
|
||||||
|
1: Right Arrow
|
||||||
|
2: Up Arrow
|
||||||
|
3: Down Arrow
|
||||||
|
4: Z (Button A)
|
||||||
|
5: X (Button B)
|
||||||
|
|
||||||
|
:param button: Button index
|
||||||
|
:return: Boolean indicating if the button is pressed
|
||||||
|
"""
|
||||||
|
# Map button indices to Pygame keys
|
||||||
|
key_map = {
|
||||||
|
0: pygame.K_LEFT,
|
||||||
|
1: pygame.K_RIGHT,
|
||||||
|
2: pygame.K_UP,
|
||||||
|
3: pygame.K_DOWN,
|
||||||
|
4: pygame.K_z, # Button A
|
||||||
|
5: pygame.K_x, # Button B
|
||||||
|
}
|
||||||
|
key = key_map.get(button)
|
||||||
|
if key:
|
||||||
|
return self.input_handler.is_key_pressed(key)
|
||||||
|
return False
|
50
core/renderer.py
Normal file
50
core/renderer.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# engine/renderer.py
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Renderer:
|
||||||
|
def __init__(self, surface):
|
||||||
|
self.surface = surface
|
||||||
|
# Define a simple 8-bit palette (e.g., NES palette)
|
||||||
|
self.palette = [
|
||||||
|
(84, 84, 84), # Color 0
|
||||||
|
(0, 30, 116), # Color 1
|
||||||
|
(8, 16, 144), # Color 2
|
||||||
|
(48, 0, 136), # Color 3
|
||||||
|
(68, 0, 100), # Color 4
|
||||||
|
(92, 0, 48), # Color 5
|
||||||
|
(84, 4, 0), # Color 6
|
||||||
|
(60, 24, 0), # Color 7
|
||||||
|
(32, 42, 0), # Color 8
|
||||||
|
(8, 58, 0), # Color 9
|
||||||
|
(0, 64, 0), # Color 10
|
||||||
|
(0, 60, 0), # Color 11
|
||||||
|
(0, 50, 60), # Color 12
|
||||||
|
(0, 0, 0), # Color 13
|
||||||
|
(0, 0, 0), # Color 14
|
||||||
|
(0, 0, 0), # Color 15
|
||||||
|
]
|
||||||
|
|
||||||
|
def clear(self, color=0):
|
||||||
|
if 0 <= color < len(self.palette):
|
||||||
|
self.surface.fill(self.palette[color])
|
||||||
|
else:
|
||||||
|
self.surface.fill(self.palette[0]) # Default to background color
|
||||||
|
|
||||||
|
def draw_pixel(self, x, y, color_index):
|
||||||
|
if 0 <= color_index < len(self.palette):
|
||||||
|
if 0 <= x < self.surface.get_width() and 0 <= y < self.surface.get_height():
|
||||||
|
self.surface.set_at((int(x), int(y)), self.palette[color_index])
|
||||||
|
|
||||||
|
def draw_sprite(self, x, y, sprite, color_index=1):
|
||||||
|
"""
|
||||||
|
Draws a sprite at position (x, y).
|
||||||
|
|
||||||
|
:param x: X-coordinate
|
||||||
|
:param y: Y-coordinate
|
||||||
|
:param sprite: 2D list representing the sprite
|
||||||
|
:param color_index: Color index to use for the sprite
|
||||||
|
"""
|
||||||
|
for row_idx, row in enumerate(sprite):
|
||||||
|
for col_idx, pixel in enumerate(row):
|
||||||
|
if pixel:
|
||||||
|
self.draw_pixel(x + col_idx, y + row_idx, color_index)
|
89
main.py
Normal file
89
main.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# main.py
|
||||||
|
import pygame
|
||||||
|
from core.lua_api import LuaAPI
|
||||||
|
from core.renderer import Renderer
|
||||||
|
from core.input_handler import InputHandler
|
||||||
|
from lupa import LuaRuntime
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Constants for 8-bit style
|
||||||
|
SCREEN_WIDTH = 160
|
||||||
|
SCREEN_HEIGHT = 144
|
||||||
|
SCALE_FACTOR = 5 # Scale up for visibility
|
||||||
|
FPS = 60
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pygame.init()
|
||||||
|
pygame.display.set_caption("8-Bit Python Engine")
|
||||||
|
window = pygame.display.set_mode((SCREEN_WIDTH * SCALE_FACTOR, SCREEN_HEIGHT * SCALE_FACTOR))
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
# Create a surface for the 8-bit display
|
||||||
|
display_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||||
|
|
||||||
|
# Initialize components
|
||||||
|
renderer = Renderer(display_surface)
|
||||||
|
input_handler = InputHandler()
|
||||||
|
lua = LuaRuntime(unpack_returned_tuples=True)
|
||||||
|
api = LuaAPI(renderer, input_handler)
|
||||||
|
api.get_api(lua) # Expose API to Lua
|
||||||
|
|
||||||
|
# Load Lua game script
|
||||||
|
script_path = os.path.join("scripts", "game.lua")
|
||||||
|
if not os.path.exists(script_path):
|
||||||
|
print(f"Error: Lua script '{script_path}' not found.")
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(script_path, "r") as f:
|
||||||
|
lua_script = f.read()
|
||||||
|
|
||||||
|
try:
|
||||||
|
lua.execute(lua_script)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error executing Lua script: {e}")
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Retrieve update and draw functions from Lua
|
||||||
|
lua_globals = lua.globals()
|
||||||
|
if not hasattr(lua_globals, 'update') or not hasattr(lua_globals, 'draw'):
|
||||||
|
print("Error: Lua script must define 'update' and 'draw' functions.")
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
update = lua_globals.update
|
||||||
|
draw = lua_globals.draw
|
||||||
|
|
||||||
|
running = True
|
||||||
|
while running:
|
||||||
|
delta_time = clock.tick(FPS) / 1000.0 # Seconds since last frame
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
input_handler.process_event(event)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Update game logic via Lua
|
||||||
|
update(delta_time)
|
||||||
|
|
||||||
|
# Clear the display
|
||||||
|
renderer.clear()
|
||||||
|
|
||||||
|
# Draw game elements via Lua
|
||||||
|
draw()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error during Lua execution: {e}")
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Scale and blit to the window
|
||||||
|
scaled_surface = pygame.transform.scale(display_surface, (SCREEN_WIDTH * SCALE_FACTOR, SCREEN_HEIGHT * SCALE_FACTOR))
|
||||||
|
window.blit(scaled_surface, (0, 0))
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
70
scripts/game.lua
Normal file
70
scripts/game.lua
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
-- scripts/game.lua
|
||||||
|
|
||||||
|
-- Define a simple sprite (e.g., 8x8 pixel player)
|
||||||
|
player_sprite = {
|
||||||
|
{0,1,1,0,0,1,1,0},
|
||||||
|
{1,0,0,1,1,0,0,1},
|
||||||
|
{1,0,0,1,1,0,0,1},
|
||||||
|
{0,1,1,0,0,1,1,0},
|
||||||
|
{0,1,1,0,0,1,1,0},
|
||||||
|
{1,0,0,1,1,0,0,1},
|
||||||
|
{1,0,0,1,1,0,0,1},
|
||||||
|
{0,1,1,0,0,1,1,0},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Define a simple enemy sprite
|
||||||
|
enemy_sprite = {
|
||||||
|
{2,2,2,2,2,2,2,2},
|
||||||
|
{2,0,0,0,0,0,0,2},
|
||||||
|
{2,0,2,2,2,2,0,2},
|
||||||
|
{2,0,2,0,0,2,0,2},
|
||||||
|
{2,0,2,2,2,2,0,2},
|
||||||
|
{2,0,0,0,0,0,0,2},
|
||||||
|
{2,2,2,2,2,2,2,2},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
}
|
||||||
|
|
||||||
|
player_x = 72
|
||||||
|
player_y = 68
|
||||||
|
player_speed = 60 -- pixels per second
|
||||||
|
|
||||||
|
enemy_x = 40
|
||||||
|
enemy_y = 40
|
||||||
|
enemy_speed = 30 -- pixels per second
|
||||||
|
|
||||||
|
function update(dt)
|
||||||
|
-- Player Movement
|
||||||
|
if btn(0) then -- Left
|
||||||
|
player_x = player_x - player_speed * dt
|
||||||
|
end
|
||||||
|
if btn(1) then -- Right
|
||||||
|
player_x = player_x + player_speed * dt
|
||||||
|
end
|
||||||
|
if btn(2) then -- Up
|
||||||
|
player_y = player_y - player_speed * dt
|
||||||
|
end
|
||||||
|
if btn(3) then -- Down
|
||||||
|
player_y = player_y + player_speed * dt
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Enemy Movement: simple back and forth
|
||||||
|
enemy_x = enemy_x + enemy_speed * dt
|
||||||
|
if enemy_x > 120 then
|
||||||
|
enemy_speed = -enemy_speed
|
||||||
|
elseif enemy_x < 40 then
|
||||||
|
enemy_speed = -enemy_speed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function draw()
|
||||||
|
-- Draw Player
|
||||||
|
spr(math.floor(player_x), math.floor(player_y), player_sprite, 11)
|
||||||
|
|
||||||
|
-- Draw Enemy
|
||||||
|
spr(math.floor(enemy_x), math.floor(enemy_y), enemy_sprite, 9)
|
||||||
|
|
||||||
|
-- Draw some pixels as obstacles or decorations
|
||||||
|
px(80, 72, 5)
|
||||||
|
px(81, 72, 5)
|
||||||
|
px(82, 72, 5)
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user