diff --git a/hashengine.py b/hashengine.py index aa319f5..76c8f32 100644 --- a/hashengine.py +++ b/hashengine.py @@ -182,6 +182,11 @@ class obj: self.fcolor = color3() self._touching = event() +class model: + def __init__(self, objects): + self._objects = objects + self.ID = 0 + class camera(obj): def __init__(self): super().__init__() @@ -237,15 +242,20 @@ class game: half = vector2(target.velocity.x/2, target.velocity.y/2) target.velocity = vector2(half.x, half.y) target2.velocity = half + self._threads.extend(target._touching.execute()) + self._threads.extend(target2._touching.execute()) def calcphysobj(self, target: obj): - if target.anchored == True: return + opos = vector2(target.position.x, target.position.y) + collide = False + if target.anchored == True: return [opos, collide] if target.collide == True: colliding = self.collidingpos(target.position+target.velocity, [target,]) for i in colliding: target._touching.execute() i._touching.execute() self.handlecollision(target, i) + collide = True target.position += target.velocity target.velocity += vector2(0, target.gravity) target.velocity += target.acceleration @@ -259,6 +269,17 @@ class game: if y != 0: y = y/temp target.velocity = vector2(x, y) + return [opos, collide] + + def calcphysmodel(self, target: model): + reverse = [] + for i in target._objects: + back = self.calcphysmodel(i) + reverse.append((i, back[0])) + if back[1]: + for obj in reverse: + obj[0].Position = obj[1] + break def addobj(self, obj): id = "" @@ -288,11 +309,19 @@ class game: tochange.append((x, y)) #self._renderer.pix(x, y, " ", color3(255, 255, 255), color3(255, 255, 255)) for i in list(self._objects.values()): - pos = i.position + self.camera.position - if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue# - pos = vector2(round(pos.x), round(pos.y)) - self._renderer.pix(pos.x, pos.y, i.char, i.bcolor, i.fcolor) - if (pos.x, pos.y) in tochange: tochange.remove((pos.x, pos.y)) + if isinstance(i, obj): + pos = i.position + self.camera.position + if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue# + pos = vector2(round(pos.x), round(pos.y)) + self._renderer.pix(pos.x, pos.y, i.char, i.bcolor, i.fcolor) + if (pos.x, pos.y) in tochange: tochange.remove((pos.x, pos.y)) + if isinstance(i, model): + for tobj in i._objects: + pos = tobj.position + self.camera.position + if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue# + pos = vector2(round(pos.x), round(pos.y)) + self._renderer.pix(pos.x, pos.y, tobj.char, tobj.bcolor, tobj.fcolor) + if (pos.x, pos.y) in tochange: tochange.remove((pos.x, pos.y)) for i in tochange: self._renderer.pix(i[0], i[1], " ", color3(255, 255, 255), color3(255, 255, 255)) self._renderer.update() diff --git a/icons/model.png b/icons/model.png new file mode 100644 index 0000000..7dfc1c2 Binary files /dev/null and b/icons/model.png differ diff --git a/langsys/lang/de_DE.LAN b/langsys/lang/de_DE.LAN index 293e8b7..9be2ffd 100644 --- a/langsys/lang/de_DE.LAN +++ b/langsys/lang/de_DE.LAN @@ -31,4 +31,5 @@ "sound": "Sound", "IPS": "Python Skript importieren", "COBS": "Objekte durch String erstellen", +"IOM": "Erstellte Objekte", } \ No newline at end of file diff --git a/langsys/lang/en_EN.LAN b/langsys/lang/en_EN.LAN index fb3bf3e..845431b 100644 --- a/langsys/lang/en_EN.LAN +++ b/langsys/lang/en_EN.LAN @@ -31,4 +31,5 @@ "sound": "Sound", "IPS": "Import python script", "COBS": "Create objects by string", +"IOM": "Created objects", } \ No newline at end of file diff --git a/main.py b/main.py index ddc6f11..e3a7569 100644 --- a/main.py +++ b/main.py @@ -7,8 +7,8 @@ from tkinter import messagebox from tkinter import filedialog import copy import hashengine -global LH -if __name__ == "__main__": +def norms(): + global LH import PCPL import langsys PCPL.interpreter.ENG = hashengine @@ -17,16 +17,25 @@ if __name__ == "__main__": lang = lang.read() LH.setlang(lang) # LH.string("") -else: +def replacelh(): + global LH class rLH: def __init__(self): pass def string(self, target): return target + def getlangs(self): + return () LH = rLH() +if __name__ == "__main__": + norms() +else: + replacelh() +if len(sys.argv) == 2: + if sys.argv[1] == "NOLANG": + replacelh() import ast import subprocess -import sys import time import shutil import os @@ -112,8 +121,8 @@ class previewrend: self._keys = {} for i in tkeys: self._keys[i] = False - self._win.bind("", self.keypupd) - self._win.bind("", self.keydupd) + self._win.bind("", self.keypupd, add="+") + self._win.bind("", self.keydupd, add="+") for y in range(size[1]): for x in range(size[0]): @@ -237,7 +246,7 @@ def selectlang(new): container.quit() subprocess.Popen([sys.executable, __file__]) -def add(objtype): +def add(objtype, parent=""): global objtree obj = getattr(types, objtype)() args = {} @@ -245,11 +254,8 @@ def add(objtype): if i.startswith("_"): continue args[i] = getattr(obj, i) temp = {"id": objtype, "args": args, "name": LH.string(objtype)} - id = "" - chars = list(string.ascii_letters) - for i in range(255): - id = id + random.choice(chars) - if GUIe == True: objtree.insert("", tk.END, text=LH.string(objtype), image=icons[objtype], iid=id, tags=("objsel")) + id = genid() + if GUIe == True: objtree.insert(parent, tk.END, text=LH.string(objtype), image=icons[objtype], iid=id, tags=("objsel")) gamedata[id] = temp if objtype in crucial: preview.addobj(obj) @@ -258,23 +264,32 @@ def add(objtype): return id def renameobj(): - target = objtree.focus() + target = objtree.focus() if target == "": return new = easygui.enterbox(LH.string("NN"), LH.string("rename")) if new: objtree.item(target, text=new) gamedata[target]["name"] = new -def delobj(): - target = objtree.focus() - if target == "": return - atritree.delete(*atritree.get_children()) +def delobjg(target): objtree.delete(target) temp = gamedata.pop(target) if temp["id"] in crucial: preview.removeobjbyid(temp["args"]["ID"]) preview.render() +def delobj(): + target = objtree.selection() + if target == (): return + atritree.delete(*atritree.get_children()) + for i in target: + if "HASHMODEL" in objtree.item(i, "tags"): + for f in objtree.get_children(i): + delobjg(f) + objtree.delete(i) + else: + delobjg(i) + def rpopup(event): try: rmenu.tk_popup(event.x_root, event.y_root) @@ -446,6 +461,12 @@ class gsound: def testing(): global testproc + global running + try: + if running == True: return + except: + pass + running = True testproc = multiprocessing.Process(target=execgame, args=(prepgamedata(),)) testproc.start() @@ -512,7 +533,13 @@ def muladd(target): def stoptest(): global testproc + global running + try: + if running == False: return + except: + return testproc.terminate() + running = False def build(): print("asking user for output directory...") @@ -551,8 +578,17 @@ def importPS(): gamedata[temp]["args"]["code"] = str(target.read()) target.close() +def genid(): + id = "" + chars = list(string.ascii_letters) + for i in range(255): + id = id + random.choice(chars) + return id + def COBS(target: str, offset=hashengine.vector2(), ignore=[" ",]): target = target.split("\n") + tempid = genid() + if GUIe == True: objtree.insert("", tk.END, text=LH.string("IOM"), image=icons["model"], iid=tempid, tags=("HASHMODEL")) for i in range(len(target)): y = i i = target[i] @@ -561,7 +597,7 @@ def COBS(target: str, offset=hashengine.vector2(), ignore=[" ",]): f = i[x] if f in ignore: continue - temp = add("obj") + temp = add("obj", tempid) #gamedata[temp]["args"]["ID"] gamedata[temp]["args"]["char"] = f setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "char", f) @@ -583,7 +619,7 @@ def GUIinit(): global GUIe GUIe = True container = tk.Tk() - container.bind("", updatepreviewcam) + container.bind("", updatepreviewcam, add="+") global icons icons = {} @@ -595,7 +631,7 @@ def GUIinit(): preview = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, container=container, offset=[0, 0]), sounddir="/") #tree init - objtree = tkk.Treeview(container, selectmode="browse", columns=("-")) + objtree = tkk.Treeview(container, columns=("-")) objtree.heading("#0", text=LH.string("objs")) objtree.tag_bind("objsel", "<>", updatribute) objtree.grid(row=1, column=0) diff --git a/mtTkinter.py b/mtTkinter.py index c497f45..87bedc7 100644 --- a/mtTkinter.py +++ b/mtTkinter.py @@ -1,4 +1,59 @@ +'''Thread-safe version of tkinter. +Copyright (c) 2014, Andrew Barnert + +Based on mtTkinter (for Python 2.x), copyright (c) 2009, Allen B. Taylor + +This module is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser Public License for more details. + +You should have received a copy of the GNU Lesser Public License +along with this program. If not, see . + +Usage: + + import mttkinter as tkinter + # Use "t." as usual. + +or + + from mtt import * + # Use tkinter module definitions as usual. + +This module modifies the original tkinter module in memory, making all +functionality thread-safe. It does this by wrapping the Tk class' tk +instance with an object that diverts calls through an event queue when +the call is issued from a thread other than the thread in which the Tk +instance was created. The events are processed in the creation thread +via an 'after' event. + +The modified Tk class accepts two additional keyword parameters on its +__init__ method: + mtDebug: + 0 = No debug output (default) + 1 = Minimal debug output + ... + 9 = Full debug output + mtCheckPeriod: + Amount of time in milliseconds (default 100) between checks for + out-of-thread events when things are otherwise idle. Decreasing + this value can improve GUI responsiveness, but at the expense of + consuming more CPU cycles. + +Note that, because it modifies the original tkinter module (in memory), +other modules that use tkinter (e.g., Pmw) reap the benefits automagically +as long as mttkinter is imported at some point before extra threads are +created. + +Author: Allen B. Taylor, a.b.taylor@gmail.com +''' import sys import threading if sys.version_info[0] == 2: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..84eb4fd --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +["easygui", "simpleaudio", "tkinter"] \ No newline at end of file diff --git a/tests/modeltest b/tests/modeltest new file mode 100644 index 0000000..ff503cb --- /dev/null +++ b/tests/modeltest @@ -0,0 +1 @@ +[{'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 1, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 2, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': 1, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 2, 'y': 1, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': 2, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 1, 'y': 2, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 2, 'y': 2, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}] \ No newline at end of file