Compare commits

...

2 commits

Author SHA1 Message Date
030f1a8722 input and sprite handling, plus music! 2025-04-27 03:16:51 -04:00
a677eca173 dynamic size for demo font 2025-04-25 21:43:31 -04:00
7 changed files with 188 additions and 7 deletions

4
.gitignore vendored
View file

@ -160,4 +160,6 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
conf/user*.json
/conf/user*.json
/data/*
!/data/README.md

View file

@ -0,0 +1,84 @@
from . import input
from pyglet.window import key
import pyglet.clock
from enum import Enum
from collections import defaultdict
bindings = defaultdict(lambda: None)
firing = defaultdict(lambda: None)
actions = []
fixed_rate = 0.003
class RepeatType(Enum):
No = 0
Interval = 1
Fixed = 2
class FiringTime(Enum):
Immediate = 0
Lazy = 1
class KeyBinding(object):
def __init__(self, key, action, repeat=RepeatType.Fixed, interval=fixed_rate, delay=FiringTime.Immediate):
self.key = key
self.action = action
self.repeat = repeat
self.interval = interval
self.repeat_offset = None
self.delay = delay
self.firedonce = False
def fire(self, clock):
global firing
self.repeatfire(clock)
firing[self.key] = True
def unfire(self, clock):
if self.delay == FiringTime.Lazy and not self.firedonce:
self.trigger()
firing[self.key] = False
def repeatfire(self, clock):
if self.repeat_offset == None:
self.repeat_offset = 0.0
if self.delay == FiringTime.Immediate:
self.trigger()
if self.repeat != RepeatType.No:
self.repeat_offset += clock
while self.repeat_offset > self.interval:
# print(f"accumulated offset by {clock} to {self.repeat_offset}")
self.repeat_offset -= self.interval
self.trigger()
def trigger(self):
global actions
# print(f"Repeat firing for {self.repeat_offset} x {self.repeat_offset / self.interval}")
actions.append(self.action)
self.firedonce = True
def process_keys(clock):
global actions
actions = []
#clock = pyglet.clock.get_default()
for keybind in bindings.keys():
binding = bindings[keybind]
is_firing = firing[keybind]
is_pressed = input.state[keybind]
if is_pressed and not is_firing:
# print(f"Starting firing for key")
binding.fire(clock)
elif not is_pressed and is_firing:
# print(f"Stopping firing for key")
binding.unfire(clock)
elif is_firing:
binding.repeatfire(clock)
def bind(key, action, repeat=RepeatType.Fixed, interval=fixed_rate, delay=FiringTime.Immediate):
global bindings
kb = KeyBinding(key, action, repeat, interval, delay)
bindings[key] = kb

View file

@ -2,9 +2,18 @@ import os
import sys
from . import config
from .file import *
import pyglet.resource
g_data = {}
class ModDependency(object):
def __init__(self: object, modname: str):
self.name = modname
self.deps = []
def add(self: object, modname: str):
self.deps.append(modname)
class ModInfo(object):
def __init__(self: object, modname: str):
self.name = modname
@ -44,13 +53,31 @@ def load_mods() -> None:
# handle zip mods here somehow
# full_modlist[mn][me] = mod
pass
elif me == '' or os.path.isdir(os.path.join(program_path(), 'data', mn)):
moddata = ModInfoDir()
elif me == '' and os.path.isdir(os.path.join(program_path(), 'data', mn)):
# bare directory used for mod development/game development
moddata = ModInfoDir(mn)
if moddata.has_modinfo():
full_modlist[mn][me] = moddata
modlist = {}
for mn in full_modlist.keys():
print(f"Checking mod {full_modlist[mn]}")
if '' in full_modlist[mn]:
modlist[mn] = full_modlist[mn]['']
modgraph = {}
if not modlist:
""" we have no mods, which means we have no base game data """
""" assume development mode, and try git! """
import subprocess
projectname = project_name()
subprocess.check_output(["git", "clone", "ssh://git@git.eltanin.net/game_data/" + projectname, "maingame"], cwd=os.path.join(program_path(), "data"))
pyglet.resource.path = []
for mod in modlist:
pyglet.resource.path.append('data/' + mod)
pyglet.resource.reindex()

View file

@ -10,6 +10,9 @@ def program_path() -> str:
return g_pp
def project_name() -> str:
return os.path.split(program_path())[1]
def exists(vault: str, path: str) -> bool:
fp = os.path.join(program_path(), vault, path)
return os.path.exists(fp)

View file

@ -0,0 +1,8 @@
import pyglet.window.key
state = pyglet.window.key.KeyStateHandler()
def init_key_handler(window):
global state
window.push_handlers(state)

View file

@ -1,5 +1,6 @@
import pyglet
from . import config
from . import input
def auto_res(res: list) -> list:
return res
@ -51,4 +52,6 @@ def init_window() -> None:
# print(f"creating window on screen {screen}")
# windows.append(pyglet.window.Window(fullscreen=True, screen=screen))
window = pyglet.window.Window(fullscreen=fs, screen=screens[0])
cfg.save()
input.init_key_handler(window)
cfg.save()

View file

@ -1,23 +1,77 @@
import pyglet
import engine
import unittest
from pyglet.window import key
from enum import Enum
import time
unittest.main(exit=False)
print("Hello!!!")
engine.data.load_mods()
engine.screen.init_window()
window = engine.screen.window
scene_batch = pyglet.graphics.Batch()
label = pyglet.text.Label('Hello, world',
font_name='Times New Roman',
font_size=36,
font_size=window.height//8,
x=window.width//2, y=window.height//2,
anchor_x='center', anchor_y='center')
anchor_x='center', anchor_y='center',
batch=scene_batch)
def center_image(image):
image.anchor_x = image.width // 2
image.anchor_y = image.height // 2
return image
player_image = center_image(pyglet.resource.image('tex/test1.png'))
player_sprite = pyglet.sprite.Sprite(player_image, x=200, y=200, batch=scene_batch)
def move_player(x, y):
player_sprite.x += x
player_sprite.y += y
music_player = pyglet.media.Player()
music_player.loop = True
music_player.queue(pyglet.resource.media('music/menu.mp3'))
music_player.play()
class Actions(Enum):
Quit = 0
Up = 1
Down = 2
Left = 3
Right = 4
action_map = {
Actions.Quit: lambda: pyglet.app.exit(),
Actions.Up: lambda: move_player(0, 1),
Actions.Down: lambda: move_player(0, -1),
Actions.Left: lambda: move_player(-1, 0),
Actions.Right: lambda: move_player(1, 0)
}
engine.binding.bind(key.Q, Actions.Quit)
engine.binding.bind(key.W, Actions.Up)
engine.binding.bind(key.S, Actions.Down)
engine.binding.bind(key.A, Actions.Left)
engine.binding.bind(key.D, Actions.Right)
@window.event
def on_draw():
engine.screen.window.clear()
label.draw()
scene_batch.draw()
def handle_input(clock):
engine.binding.process_keys(clock)
for action in engine.binding.actions:
action_map[action]()
pyglet.clock.schedule_interval(handle_input, engine.binding.fixed_rate)
pyglet.app.run()