base system finished

This commit is contained in:
Justus Jan Nico Wolff 2024-07-06 15:21:14 +02:00
parent fdd3775da6
commit dd85d592e1
5 changed files with 176 additions and 17 deletions

View file

@ -1,7 +1,75 @@
import simpleaudio
class sound:
import simpleaudio as sa
import wave
import base64
import os
# channels OK
# bytes per sample OK
# sample rate OK
class handler:
def __init__(self):
raise NotImplementedError()
self.storage = {}
def loadfromstring(self, target):
# decode frames from b64
frames = base64.b64decode(target[1])
# rebuild tuple
temp = (frames, target[2], target[3], target[4])
self.storage[target[0]] = temp
def loadsound(self, target):
if target == None: return
with wave.open(target, 'r') as fd:
frames = fd.readframes(-1)
channels = fd.getnchannels()
bytespersample = fd.getsampwidth()
frequency = fd.getframerate()
self.storage[os.path.basename(target.split(".")[0])] = (frames, channels, bytespersample, frequency)
# frames, channels, bytespersample, frequency
return os.path.basename(target.split(".")[0])
def getsound(self, target):
if not target in self.storage: raise ValueError(f"Sound {target} not loaded!")
else: return sound(self.storage[target])
def tostring(self, target):
if not target in self.storage: raise ValueError(f"Sound {target} not loaded!")
data = self.storage[target]
# encode frames to b64
frames = str(base64.b64encode(data[0]), "ascii", "ignore")
# rebuild tuple
out = (target, frames, data[1], data[2], data[3])
# name, frames, channels, bytespersample, frequency
return out
class sound:
def __init__(self, data):
self.frames = data[0]
self.channels = data[1]
self.bps = data[2]
self.freq = data[3]
self._playing = False
self._soundobj = None
def play(self):
if self._playing == True and self._soundobj.is_playing(): return
self._soundobj = sa.play_buffer(self.frames, self.channels, self.bps, self.freq)
self._playing = True
def stop(self):
if self._playing == False: return
self._soundobj.stop()
self._playing = False
def wait(self):
if self._playing == False: return
self._soundobj.wait_done()
self._playing = False
if __name__ == "__main__":
temp = handler()
print(temp.loadsound("sounds/joyride.wav"))
tsound = temp.getsound("joyride")
tsound.play()
tsound.wait()

View file

@ -1,10 +1,13 @@
import mtTkinter as tk
from HEMD import color3, vector2, event, enum, NULL
from HEMD import color3, vector2, event, NULL
import audiosys
from loadbar import loadbar
import random
import string
import math
import time
import threading
import pickle
#import itertools
#import multiprocessing
@ -22,10 +25,20 @@ class obj:
self.id = NULL()
self.color = color3()
self.colliding = event()
self.parent = NULL()
self._parent = NULL()
self.children = []
self.ignorecollision = []
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, value):
self._parent.children.remove(self)
self._parent = value
self._parent.children.append(self)
class game:
def __init__(self, canvas: tk.Canvas, pixelsize=3):
self._canvas = canvas
@ -39,6 +52,10 @@ class game:
self._camera.position = vector2()
self._camera.zoom = pixelsize
self._OAPUPDATING = False
self._handler = audiosys.handler()
self._threads = []
self._root = obj()
self._scripts = []
"""self._workers = []
self._processes = 2 # total number of processes.
for i in range(self._processes):
@ -92,6 +109,8 @@ class game:
if physics: self._objects[temp] = target
self._visobjects[temp] = target
target.id = temp
target._parent = self._root
self._root.children.append(target)
self.addtooap(target)
def removeobj(self, target: obj):
@ -171,20 +190,83 @@ class game:
self.calcphysobj(i)
return time.time()-start
def savegame(self):
print("pickling root...")
outobjects = pickle.dumps(self._root)
print("copying scripts...")
outscripts = []
TLB = loadbar(20, len(self._scripts))
for i in self._scripts:
outscripts.append(i)
TLB.current += 1
TLB.render()
print("encoding sounds...")
outsounds = []
TLB = loadbar(20, len(self._handler.storage))
for i in self._handler.storage:
outsounds.append(self._handler.tostring(i))
TLB.current += 1
TLB.render()
return {"obj": outobjects, "scripts": outscripts, "sounds": outsounds}
def readdobj(self, target, TLB):
TLB.repeat += len(target)
TLB.steps = TLB.repeat/TLB.length
for i in target.copy():
self.addobj(i, True, i.id)
if len(i.children) > 0: self.readdobj(i.children, TLB)
TLB.current += 1
TLB.render()
def loadgame(self, target):
print("loading objects...")
self._root = pickle.loads(target["obj"])
print("loading scripts...")
self._scripts = []
TLB = loadbar(20, len(target["scripts"]))
for i in target["scripts"]:
self._scripts.append(i)
TLB.current += 1
TLB.render()
print()
print("loading sounds...")
self._handler.storage = {}
TLB = loadbar(20, len(target["sounds"]))
for i in target["sounds"]:
self._handler.loadfromstring(i)
TLB.current += 1
TLB.render()
print("readding objects...")
self._OAP = {}
self._objects = {}
self._visobjects = {}
TLB = loadbar(20, 0)
self.readdobj(self._root.children, TLB)
if not "__CMD__" in globals():
from PIL import Image
from tkinter import filedialog
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.grid()
temp = game(canvas)
for i in range(10):
tempobj = obj()
tempobj.position = vector2(5, i)
tempobj.anchored = False
tempobj.velocity.x = 1
tempobj.collide = True
temp.addobj(tempobj)
while True:
took = temp.updobjs()
temp.render()
root.update()
time.sleep(0.1-took)
tempimg = Image.open(filedialog.askopenfilename())
tempimg = tempimg.resize((temp._width, temp._height))
for y in range(temp._height):
for x in range(temp._width):
tempobj = obj()
tempobj.position = vector2(x, y)
tempcolor = tempimg.getpixel((x, y))
tempobj.color = color3(tempcolor[0], tempcolor[1], tempcolor[2])
temp.addobj(tempobj)
print(f"{y}/{temp._height}", end="\r", flush=True)
tempstate = temp.savegame()
print("resetting...")
temp.__init__(canvas)
input("press enter to reload state")
print("loading...")
temp.loadgame(tempstate)
temp.render()
root.update()
print()
input("press enter to exit.")

9
loadbar.py Normal file
View file

@ -0,0 +1,9 @@
class loadbar:
def __init__(self, length=10, full=10):
self.steps = full/length
self.length = length
self.repeat = full
self.current = 0
def render(self):
print("["+("#"*int(self.current/self.steps))+(" "*(self.length-int(self.current/self.steps)))+"]"+f" {self.current}/{self.repeat}", end="\r", flush=True)

BIN
sounds/intro.wav Normal file

Binary file not shown.

BIN
sounds/joyride.wav Normal file

Binary file not shown.