Created Basic Engine

This project is kind of a dead end.
This commit is contained in:
OusmBlueNinja 2024-12-23 22:46:16 -06:00
parent e8db72e3f9
commit ae733d164a
10 changed files with 288 additions and 0 deletions

0
core/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
core/input_handler.py Normal file
View 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
View 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
View 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
View 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
View 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