added building

main
Justus Jan Nico Wolff 2024-05-13 19:57:26 +02:00
parent 7c6afef69b
commit ae80270d71
19 changed files with 1573 additions and 18 deletions

View File

@ -201,11 +201,12 @@ class game:
def calcphysobj(self, target: obj): def calcphysobj(self, target: obj):
if target.anchored == True: return if target.anchored == True: return
colliding = self.collidingpos(target.position+target.velocity, [target,]) if target.collide == True:
for i in colliding: colliding = self.collidingpos(target.position+target.velocity, [target,])
target._touching.execute() for i in colliding:
i._touching.execute() target._touching.execute()
self.handlecollision(target, i) i._touching.execute()
self.handlecollision(target, i)
target.position += target.velocity target.position += target.velocity
target.velocity += vector2(0, target.gravity) target.velocity += vector2(0, target.gravity)
target.velocity += target.acceleration target.velocity += target.acceleration

BIN
icons/build.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

BIN
icons/stop-test.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

BIN
icons/test.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View File

@ -25,4 +25,7 @@
"ycam": "Kamera y Position:", "ycam": "Kamera y Position:",
"testing": "Testen", "testing": "Testen",
"test": "Spiel ausfuehren", "test": "Spiel ausfuehren",
"stest": "Test stoppen",
"building": "Bauen",
"build": "Bauen",
} }

View File

@ -25,4 +25,7 @@
"ycam": "Camera y position:", "ycam": "Camera y position:",
"testing": "Testing", "testing": "Testing",
"test": "Execute game", "test": "Execute game",
"stest": "Stop execution",
"building": "Building",
"build": "Build",
} }

93
main.py
View File

@ -13,10 +13,10 @@ import subprocess
import sys import sys
import time import time
import hashengine import hashengine
import shutil
import os import os
import random import random
import string import string
import threading
import easygui import easygui
global LH global LH
@ -34,8 +34,18 @@ PCPL.interpreter.ENG = hashengine
def prepgamedata(): def prepgamedata():
out = [] out = []
tempwin = tk.Tk()
bar = tkk.Progressbar(tempwin)
bar.place(width=200)
ptext = tk.Label(tempwin, text="NONE")
ptext.place()
count = 1
for i in gamedata: for i in gamedata:
i = gamedata[i] i = gamedata[i]
ptext.config(text=i["name"])
bar.step(count/len(gamedata))
count += 1
tempwin.update()
temp = {"id": i["id"], "name": i["name"]} temp = {"id": i["id"], "name": i["name"]}
tempargs = {} tempargs = {}
tosearch = {} tosearch = {}
@ -52,6 +62,7 @@ def prepgamedata():
tempargs[argname] = temp2 tempargs[argname] = temp2
temp["args"] = tempargs temp["args"] = tempargs
out.append(temp) out.append(temp)
tempwin.destroy()
return out return out
class script: class script:
@ -91,7 +102,7 @@ class previewrend:
colors = [] colors = []
target = [target.r, target.g, target.b] target = [target.r, target.g, target.b]
for i in target: for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:]) colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:])
out = "" out = ""
for i in colors: for i in colors:
out = out + i out = out + i
@ -252,12 +263,26 @@ def importobj(target):
def load(): def load():
file = filedialog.askopenfile() file = filedialog.askopenfile()
tempwin = tk.Tk()
ptext = tk.Label(tempwin, text="NONE")
ptext.place(y=30)
stat = tk.Label(tempwin, text="NONE")
stat.place(y=50)
target = file.read() target = file.read()
file.close() file.close()
target = ast.literal_eval(target) target = ast.literal_eval(target)
clear() clear()
count = 1
bar = tkk.Progressbar(tempwin, maximum=len(target))
bar.place(width=200)
for i in target: for i in target:
ptext.config(text="Current: "+i["name"])
bar.step()
stat.config(text=f"Object {count}/{len(target)}")
tempwin.update()
importobj(i) importobj(i)
count += 1
tempwin.destroy()
preview.render() preview.render()
def log(text, end="\n", flush=False): def log(text, end="\n", flush=False):
@ -266,10 +291,14 @@ def log(text, end="\n", flush=False):
file.write(text+end) file.write(text+end)
file.close() file.close()
def NULL():
pass
def testing(): def testing():
print("preparing log file...") print("preparing log file...")
global logfile global logfile
global maingame global maingame
global window
temp = time.gmtime(time.time()) temp = time.gmtime(time.time())
logfile = "" logfile = ""
for i in temp: for i in temp:
@ -280,6 +309,7 @@ def testing():
API = {"print": log, "HASHBASE": hashengine} API = {"print": log, "HASHBASE": hashengine}
log("Done!") log("Done!")
window = tk.Tk() window = tk.Tk()
window.protocol("WM_DELETE_WINDOW", NULL)
maingame = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, window, [0, 0])) maingame = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, window, [0, 0]))
API["HASHGAME"] = maingame API["HASHGAME"] = maingame
log("main game initalised!") log("main game initalised!")
@ -304,7 +334,6 @@ while True:
i = HASHGAME._objects[i] i = HASHGAME._objects[i]
HASHGAME.calcphysobj(i) HASHGAME.calcphysobj(i)
HASHGAME.render() HASHGAME.render()
time.sleep(.0)
""" """
gameloopsc = script() gameloopsc = script()
gameloopsc.code = gamescript gameloopsc.code = gamescript
@ -312,6 +341,32 @@ while True:
log("game test started!!!") log("game test started!!!")
log("---------------------") log("---------------------")
def muladd(target):
for i in range(10):
add(target)
def stoptest():
maingame.stopscripts()
window.destroy()
def build():
print("asking user for output directory...")
target = filedialog.askdirectory()
print("building started")
print("generating HEGF file...")
hegf = str(prepgamedata())
file = open(target+"/game.HEGF", 'w')
file.write(hegf)
file.close()
print("done.")
print("copying files...")
tocopy = ["mtTkinter.py", "player.py", "hashengine.py"]
for i in tocopy:
print(f"copying {i}...")
shutil.copyfile(i, target+"/"+i)
print("done.")
print("building finished!")
def GUIinit(): def GUIinit():
global container global container
global objtree global objtree
@ -367,10 +422,16 @@ def GUIinit():
menu.add_cascade(label=LH.string("add"), menu=addmenu) menu.add_cascade(label=LH.string("add"), menu=addmenu)
addmenu.add_command(label=LH.string("obj"), command=lambda: add("obj")) addmenu.add_command(label=LH.string("obj"), command=lambda: add("obj"))
addmenu.add_command(label=LH.string("script"), command=lambda: add("script")) addmenu.add_command(label=LH.string("script"), command=lambda: add("script"))
#addmenu.add_command(label=LH.string("obj"), command=lambda: muladd("obj"))
testmenu = tk.Menu(menu) testmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("testing"), menu=testmenu) menu.add_cascade(label=LH.string("testing"), menu=testmenu)
testmenu.add_command(label=LH.string("test"), command=testing) testmenu.add_command(label=LH.string("test"), command=testing, image=icons["test"], compound="left")
testmenu.add_command(label=LH.string("stest"), command=stoptest, image=icons["stop-test"], compound="left")
buildmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("building"), menu=buildmenu)
buildmenu.add_command(label=LH.string("build"), command=build, image=icons["build"], compound="left")
langmenu = tk.Menu(menu) langmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("langs"), menu=langmenu) menu.add_cascade(label=LH.string("langs"), menu=langmenu)
@ -390,28 +451,37 @@ def ats(mode, old):
return "N" return "N"
return out return out
else: else:
return "N" return old
def anum(old): def anum(old):
out = easygui.integerbox(LH.string("newval"), LH.string("newval"), lowerbound=-9999999999, upperbound=9999999999) out = easygui.enterbox(LH.string("newval"), LH.string("newval"))
if out: if out:
return out if "." in out:
try:
out = float(out)
return out
except ValueError:
return old
else:
return int(out)
else: else:
return 0 return old
def abool(old): def abool(old):
out = easygui.boolbox(LH.string("newval"), LH.string("newval"), (LH.string("true"), LH.string("false"))) out = easygui.boolbox(LH.string("newval"), LH.string("newval"), (LH.string("true"), LH.string("false")))
return out if out:
return out
else:
return old
def acode(old): def acode(old):
out = easygui.textbox(LH.string("newval"), LH.string("newval"), old) out = easygui.textbox(LH.string("newval"), LH.string("newval"), old)
if out: if out:
return out return out
else: else:
return "NULL" return old
global types global types
global icon
global ignoreat global ignoreat
global valtypes global valtypes
global extypes global extypes
@ -419,7 +489,6 @@ global attypes
global crucial global crucial
crucial = ["obj"] crucial = ["obj"]
types = hashengine.enum({"obj": hashengine.obj, "script": script}) types = hashengine.enum({"obj": hashengine.obj, "script": script})
icon = hashengine.enum({"obj": "icons/object.png", "script": "icons/script.png"})
ignoreat = ["ID", "execute"] ignoreat = ["ID", "execute"]
"""self.position = vector2() """self.position = vector2()
self.char = " " self.char = " "

184
player.py 100644
View File

@ -0,0 +1,184 @@
import hashengine
import random
import ast
import string
import threading
import mtTkinter as tk
import time
global gamedata
gamedata = {}
class rend:
def __init__(self, size, cam, container, offset):
self._size = size
self._grid = {}
self._win = container
self._frame = tk.Frame(container)
self._cam = cam
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(self._frame, text=" ", width=3)
temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update()
self._grid[f"{x}:{y}"] = temp
self._frame.grid()
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class script:
def __init__(self):
self.code = ""
def execute(self, API):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar()
PCPL.LIS("HASHBASE")
PCPL.run(self.code)"""
exec(self.code, API)
def add(objtype):
obj = getattr(types, objtype)()
args = {}
for i in dir(obj):
if i.startswith("_"): continue
args[i] = getattr(obj, i)
temp = {"id": objtype, "args": args, "name": objtype}
id = ""
chars = list(string.ascii_letters)
for i in range(255):
id = id + random.choice(chars)
gamedata[id] = temp
if objtype in crucial:
game.addobj(obj)
gamedata[id]["args"]["ID"] = obj.ID
return id
def importobj(target):
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
#create arguments
outargs = {}
for argname in target["args"]:
arg = target["args"][argname]
if isinstance(arg, dict):
ID = arg.pop("ARGID")
obj = attypes[ID]()
for i in arg:
setattr(obj, i, arg[i])
arg = obj
outargs[argname] = arg
#apply arguments to obj
if target["id"] in crucial:
for i in outargs:
setattr(game.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i])
id["args"].update(outargs)
def load(target):
file = open(target, 'r')
target = file.read()
file.close()
target = ast.literal_eval(target)
for i in target:
importobj(i)
def log(text, end="\n", flush=False):
global logfile
file = open(logfile+".txt", 'a')
file.write(text+end)
file.close()
def NULL():
pass
def run():
print("preparing log file...")
global logfile
global win
global game
temp = time.gmtime(time.time())
logfile = ""
for i in temp:
logfile = logfile + "S" + str(i)
print("done")
log("Log file start!")
log("Preparing API...")
API = {"print": log, "HASHBASE": hashengine}
log("Done!")
API["HASHGAME"] = game
log("main game initalised!")
scripts = []
for i in gamedata:
i = gamedata[i]
if i["id"] != "script": continue
i = i["args"]["code"]
obj = script()
obj.code = i
scripts.append(obj)
for i in scripts:
game.startscript(lambda: i.execute(API))
gamescript = """
global HASHGAME
import time
while True:
for i in HASHGAME._objects:
i = HASHGAME._objects[i]
HASHGAME.calcphysobj(i)
HASHGAME.render()
"""
gameloopsc = script()
gameloopsc.code = gamescript
game.startscript(lambda: gameloopsc.execute(API))
log("game test started!!!")
log("---------------------")
def wait():
time.sleep(0.1)
load("game.HEGF")
run()
global types
global ignoreat
global valtypes
global extypes
global attypes
global crucial
global game
win = tk.Tk()
game = hashengine.game(renderer=lambda size, cam: rend(size, cam, win, [0, 0]))
crucial = ["obj",]
types = hashengine.enum({"obj": hashengine.obj, "script": script})
ignoreat = ["ID", "execute"]
"""self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.touch = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()"""
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
threading.Thread(target=wait).start()
win.mainloop()

View File

@ -0,0 +1 @@
[{'id': 'obj', 'name': 'testobj', 'args': {'anchored': False, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 0, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 255, 'ARGID': 'color3'}, 'position': {'x': 5, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'script', 'name': 'skript pos test', 'args': {'code': 'import random\nimport time\ntime.sleep(3)\nobjects = list(HASHGAME._objects.values())\nobject = objects[0]\nstartpos = object.position\nwhile True:\n\tobject.position = startpos + HASHBASE.vector2(random.randint(-3, 3), random.randint(-3, 3))\n\ttime.sleep(.01)'}}]

View File

@ -0,0 +1,287 @@
import tkinter as tk
import string
import random
import threading
import time
class stdrend:
def __init__(self, size, cam):
self._size = size
self._grid = {}
self._win = tk.Tk()
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(text=" ")
temp.grid(row=y, column=x)
self._win.update()
self._grid[f"{x}:{y}"] = temp
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class color3:
def __init__(self, r=0, g=0, b=0):
self.r = r
self.g = g
self.b = b
self._type = "color3"
def __add__(self, v):
temp = color3(self.r+v.r, self.g+v.g, self.b+v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __sub__(self, v):
temp = color3(self.r-v.r, self.g-v.g, self.b-v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __mul__(self, v):
temp = color3(self.r*v.r, self.g*v.g, self.b*v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __iadd__(self, v):
temp = color3(self.r+v.r, self.g+v.g, self.b+v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __isub__(self, v):
temp = color3(self.r-v.r, self.g-v.g, self.b-v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __imul__(self, v):
temp = color3(self.r*v.r, self.g*v.g, self.b*v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
class vector2:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
self._type = "vector2"
def _magnitude(self):
return abs(self.x+self.y)
def __add__(self, v):
return vector2(self.x+v.x, self.y+v.y)
def __sub__(self, v):
return vector2(self.x-v.x, self.y-v.y)
def __mul__(self, v):
return vector2(self.x*v.x, self.y*v.y)
def __iadd__(self, v):
return vector2(self.x+v.x, self.y+v.y)
def __isub__(self, v):
return vector2(self.x-v.x, self.y-v.y)
def __imul__(self, v):
return vector2(self.x*v.x, self.y*v.y)
class NULL:
def __init__(self):
return None
class enum:
def __init__(self, sel):
self._sel = dict(sel)
for i in self._sel:
setattr(self, i, self._sel[i])
def getposssel(self):
return list(self._sel.keys())
cammode = enum({"editable": 0, "follow": 1})
class event:
def __init__(self):
self._attached = []
def execute(self):
threads = []
for i in self._attached:
temp = threading.Thread(target=i)
temp.start()
threads.append(temp)
return threads
def attach(self, target):
self._attached.append(target)
class obj:
def __init__(self):
self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()
self._touching = event()
class camera(obj):
def __init__(self):
super().__init__()
self.mode = cammode.editable
self.subject = None
self.collide = False
self.touch = False
self.char = " "
def update(self):
if self.mode == cammode.follow and self.subject:
self.position = self.subject.position
class game:
def __init__(self, size=[10, 10], renderer=stdrend):
if renderer == None: raise TypeError("Renderer class needed!")
self._size = size
self._objects = {}
self.camera = camera()
self._renderer = renderer(size, self.camera)
self._threads = []
def collidingpos(self, pos, ignore):
out = []
for i in self._objects:
i = self._objects[i]
if i in ignore: continue
if (i.position-pos)._magnitude() < 1 and i.collide == True:
out.append(i)
return out
def colliding(self, target):
out = []
if target.collide == False: return []
out = self.collidingpos(target.position, [target,])
return out
def handlecollision(self, target: obj, target2: obj):
if target2.anchored == True:
target.velocity = vector2()
else:
half = vector2(target.velocity.x/2, target.velocity.y/2)
target.velocity = vector2(half.x, half.y)
target2.velocity = half
def calcphysobj(self, target: obj):
if target.anchored == True: return
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)
target.position += target.velocity
target.velocity += vector2(0, target.gravity)
target.velocity += target.acceleration
temp = 2
if target.friction != 0:
temp = 2 / target.friction
x = target.velocity.x
y = target.velocity.y
if x != 0:
x = x/temp
if y != 0:
y = y/temp
target.velocity = vector2(x, y)
def addobj(self, obj):
id = ""
for i in range(256):
id = id + random.choice(list(string.ascii_letters))
obj.ID = id
self._objects[id] = obj
def removeobj(self, obj):
self._objects.pop(obj.ID)
obj.ID = NULL()
def removeobjbyid(self, id):
self._objects.pop(id).ID = NULL()
def between(self, min, max, target):
if min < target < max: return True
return False
def getobjbyid(self, id):
return self._objects[id]
def render(self):
for x in range(self._size[0]):
for y in range(self._size[1]):
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
self._renderer.pix(round(pos.x), round(pos.y), i.char, i.bcolor, i.fcolor)
self._renderer.update()
def startscript(self, target):
temp = threading.Thread(target=target)
temp.start()
self._threads.append(temp)
def stopscripts(self):
for i in self._threads:
i.join(.0)
if __name__ == "__main__":
testgame = game()
object = obj()
object.char = "#"
object.anchored = False
object.position = vector2(5, 5)
object.gravity = 1
floor = obj()
floor.char = "#"
floor.anchored = True
floor.position = vector2(5, 9)
floor.gravity = 0
floor.bcolor = color3(255, 255, 255)
testgame.addobj(object)
testgame.addobj(floor)
testgame.render()
print(object.ID)
while True:
testgame.calcphysobj(object)
testgame.calcphysobj(floor)
testgame.render()
time.sleep(0)

View File

@ -0,0 +1,175 @@
import sys
import threading
if sys.version_info[0] == 2:
# Python 2
from Tkinter import *
import Queue as queue
else:
# Python 3
from tkinter import *
import queue
class _Tk(object):
"""Wrapper for underlying attribute tk of class Tk"""
def __init__(self, tk, mt_debug=0, mt_check_period=10):
"""
:param tk: Tkinter.Tk.tk Tk interpreter object
:param mt_debug: Determines amount of debug output.
0 = No debug output (default)
1 = Minimal debug output
...
9 = Full debug output
:param mt_check_period: Amount of time in milliseconds (default
10) 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.
# TODO: Replace custom logging functionality with standard
# TODO: logging.Logger for easier access and standardization
"""
self._tk = tk
# Create the incoming event queue
self._event_queue = queue.Queue(1)
# Identify the thread from which this object is being created
# so we can tell later whether an event is coming from another
# thread.
self._creation_thread = threading.current_thread()
# Create attributes for kwargs
self._debug = mt_debug
self._check_period = mt_check_period
# Destroying flag to be set by the .destroy() hook
self._destroying = False
def __getattr__(self, name):
"""
Diverts attribute accesses to a wrapper around the underlying tk
object.
"""
return _TkAttr(self, getattr(self._tk, name))
class _TkAttr(object):
"""Thread-safe callable attribute wrapper"""
def __init__(self, tk, attr):
self._tk = tk
self._attr = attr
def __call__(self, *args, **kwargs):
"""
Thread-safe method invocation. Diverts out-of-thread calls
through the event queue. Forwards all other method calls to the
underlying tk object directly.
"""
# Check if we're in the creation thread
if threading.current_thread() == self._tk._creation_thread:
# We're in the creation thread; just call the event directly
if self._tk._debug >= 8 or \
self._tk._debug >= 3 and self._attr.__name__ == 'call' and \
len(args) >= 1 and args[0] == 'after':
print('Calling event directly:', self._attr.__name__, args, kwargs)
return self._attr(*args, **kwargs)
else:
if not self._tk._destroying:
# We're in a different thread than the creation thread;
# enqueue the event, and then wait for the response.
response_queue = queue.Queue(1)
if self._tk._debug >= 1:
print('Marshalling event:', self._attr.__name__, args, kwargs)
self._tk._event_queue.put((self._attr, args, kwargs, response_queue), True, 1)
is_exception, response = response_queue.get(True, None)
# Handle the response, whether it's a normal return value or
# an exception.
if is_exception:
ex_type, ex_value, ex_tb = response
raise ex_type(ex_value, ex_tb)
return response
def _Tk__init__(self, *args, **kwargs):
"""
Hook for Tkinter.Tk.__init__ method
:param self: Tk instance
:param args, kwargs: Arguments for Tk initializer
"""
# We support some new keyword arguments that the original __init__ method
# doesn't expect, so separate those out before doing anything else.
new_kwnames = ('mt_check_period', 'mt_debug')
new_kwargs = {
kw_name: kwargs.pop(kw_name) for kw_name in new_kwnames
if kwargs.get(kw_name, None) is not None
}
# Call the original __init__ method, creating the internal tk member.
self.__original__init__mtTkinter(*args, **kwargs)
# Replace the internal tk member with a wrapper that handles calls from
# other threads.
self.tk = _Tk(self.tk, **new_kwargs)
# Set up the first event to check for out-of-thread events.
self.after_idle(_check_events, self)
# Define a hook for class Tk's destroy method.
def _Tk_destroy(self):
self.tk._destroying = True
self.__original__destroy()
def _check_events(tk):
"""Checks events in the queue on a given Tk instance"""
used = False
try:
# Process all enqueued events, then exit.
while True:
try:
# Get an event request from the queue.
method, args, kwargs, response_queue = tk.tk._event_queue.get_nowait()
except queue.Empty:
# No more events to process.
break
else:
# Call the event with the given arguments, and then return
# the result back to the caller via the response queue.
used = True
if tk.tk._debug >= 2:
print('Calling event from main thread:', method.__name__, args, kwargs)
try:
response_queue.put((False, method(*args, **kwargs)))
except SystemExit:
raise # Raises original SystemExit
except Exception:
# Calling the event caused an exception; return the
# exception back to the caller so that it can be raised
# in the caller's thread.
from sys import exc_info # Python 2 requirement
ex_type, ex_value, ex_tb = exc_info()
response_queue.put((True, (ex_type, ex_value, ex_tb)))
finally:
# Schedule to check again. If we just processed an event, check
# immediately; if we didn't, check later.
if used:
tk.after_idle(_check_events, tk)
else:
tk.after(tk.tk._check_period, _check_events, tk)
"""Perform in-memory modification of Tkinter module"""
# Replace Tk's original __init__ with the hook.
Tk.__original__init__mtTkinter = Tk.__init__
Tk.__init__ = _Tk__init__
# Replace Tk's original destroy with the hook.
Tk.__original__destroy = Tk.destroy
Tk.destroy = _Tk_destroy

View File

@ -0,0 +1,184 @@
import hashengine
import random
import ast
import string
import threading
import mtTkinter as tk
import time
global gamedata
gamedata = {}
class rend:
def __init__(self, size, cam, container, offset):
self._size = size
self._grid = {}
self._win = container
self._frame = tk.Frame(container)
self._cam = cam
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(self._frame, text=" ", width=3)
temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update()
self._grid[f"{x}:{y}"] = temp
self._frame.grid()
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class script:
def __init__(self):
self.code = ""
def execute(self, API):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar()
PCPL.LIS("HASHBASE")
PCPL.run(self.code)"""
exec(self.code, API)
def add(objtype):
obj = getattr(types, objtype)()
args = {}
for i in dir(obj):
if i.startswith("_"): continue
args[i] = getattr(obj, i)
temp = {"id": objtype, "args": args, "name": objtype}
id = ""
chars = list(string.ascii_letters)
for i in range(255):
id = id + random.choice(chars)
gamedata[id] = temp
if objtype in crucial:
game.addobj(obj)
gamedata[id]["args"]["ID"] = obj.ID
return id
def importobj(target):
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
#create arguments
outargs = {}
for argname in target["args"]:
arg = target["args"][argname]
if isinstance(arg, dict):
ID = arg.pop("ARGID")
obj = attypes[ID]()
for i in arg:
setattr(obj, i, arg[i])
arg = obj
outargs[argname] = arg
#apply arguments to obj
if target["id"] in crucial:
for i in outargs:
setattr(game.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i])
id["args"].update(outargs)
def load(target):
file = open(target, 'r')
target = file.read()
file.close()
target = ast.literal_eval(target)
for i in target:
importobj(i)
def log(text, end="\n", flush=False):
global logfile
file = open(logfile+".txt", 'a')
file.write(text+end)
file.close()
def NULL():
pass
def run():
print("preparing log file...")
global logfile
global win
global game
temp = time.gmtime(time.time())
logfile = ""
for i in temp:
logfile = logfile + "S" + str(i)
print("done")
log("Log file start!")
log("Preparing API...")
API = {"print": log, "HASHBASE": hashengine}
log("Done!")
API["HASHGAME"] = game
log("main game initalised!")
scripts = []
for i in gamedata:
i = gamedata[i]
if i["id"] != "script": continue
i = i["args"]["code"]
obj = script()
obj.code = i
scripts.append(obj)
for i in scripts:
game.startscript(lambda: i.execute(API))
gamescript = """
global HASHGAME
import time
while True:
for i in HASHGAME._objects:
i = HASHGAME._objects[i]
HASHGAME.calcphysobj(i)
HASHGAME.render()
"""
gameloopsc = script()
gameloopsc.code = gamescript
game.startscript(lambda: gameloopsc.execute(API))
log("game test started!!!")
log("---------------------")
def wait():
time.sleep(0.1)
load("game.HEGF")
run()
global types
global ignoreat
global valtypes
global extypes
global attypes
global crucial
global game
win = tk.Tk()
game = hashengine.game(renderer=lambda size, cam: rend(size, cam, win, [0, 0]))
crucial = ["obj",]
types = hashengine.enum({"obj": hashengine.obj, "script": script})
ignoreat = ["ID", "execute"]
"""self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.touch = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()"""
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
threading.Thread(target=wait).start()
win.mainloop()

View File

@ -0,0 +1 @@
[{'id': 'obj', 'name': 'boden', 'args': {'anchored': True, 'char': ' ', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 5, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'obj', 'args': {'anchored': False, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 1, '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': 5, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}]

View File

@ -0,0 +1,287 @@
import tkinter as tk
import string
import random
import threading
import time
class stdrend:
def __init__(self, size, cam):
self._size = size
self._grid = {}
self._win = tk.Tk()
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(text=" ")
temp.grid(row=y, column=x)
self._win.update()
self._grid[f"{x}:{y}"] = temp
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class color3:
def __init__(self, r=0, g=0, b=0):
self.r = r
self.g = g
self.b = b
self._type = "color3"
def __add__(self, v):
temp = color3(self.r+v.r, self.g+v.g, self.b+v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __sub__(self, v):
temp = color3(self.r-v.r, self.g-v.g, self.b-v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __mul__(self, v):
temp = color3(self.r*v.r, self.g*v.g, self.b*v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __iadd__(self, v):
temp = color3(self.r+v.r, self.g+v.g, self.b+v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __isub__(self, v):
temp = color3(self.r-v.r, self.g-v.g, self.b-v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
def __imul__(self, v):
temp = color3(self.r*v.r, self.g*v.g, self.b*v.b)
temp.r = temp.r%255
temp.g = temp.g%255
temp.b = temp.b%255
return temp
class vector2:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
self._type = "vector2"
def _magnitude(self):
return abs(self.x+self.y)
def __add__(self, v):
return vector2(self.x+v.x, self.y+v.y)
def __sub__(self, v):
return vector2(self.x-v.x, self.y-v.y)
def __mul__(self, v):
return vector2(self.x*v.x, self.y*v.y)
def __iadd__(self, v):
return vector2(self.x+v.x, self.y+v.y)
def __isub__(self, v):
return vector2(self.x-v.x, self.y-v.y)
def __imul__(self, v):
return vector2(self.x*v.x, self.y*v.y)
class NULL:
def __init__(self):
return None
class enum:
def __init__(self, sel):
self._sel = dict(sel)
for i in self._sel:
setattr(self, i, self._sel[i])
def getposssel(self):
return list(self._sel.keys())
cammode = enum({"editable": 0, "follow": 1})
class event:
def __init__(self):
self._attached = []
def execute(self):
threads = []
for i in self._attached:
temp = threading.Thread(target=i)
temp.start()
threads.append(temp)
return threads
def attach(self, target):
self._attached.append(target)
class obj:
def __init__(self):
self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()
self._touching = event()
class camera(obj):
def __init__(self):
super().__init__()
self.mode = cammode.editable
self.subject = None
self.collide = False
self.touch = False
self.char = " "
def update(self):
if self.mode == cammode.follow and self.subject:
self.position = self.subject.position
class game:
def __init__(self, size=[10, 10], renderer=stdrend):
if renderer == None: raise TypeError("Renderer class needed!")
self._size = size
self._objects = {}
self.camera = camera()
self._renderer = renderer(size, self.camera)
self._threads = []
def collidingpos(self, pos, ignore):
out = []
for i in self._objects:
i = self._objects[i]
if i in ignore: continue
if (i.position-pos)._magnitude() < 1 and i.collide == True:
out.append(i)
return out
def colliding(self, target):
out = []
if target.collide == False: return []
out = self.collidingpos(target.position, [target,])
return out
def handlecollision(self, target: obj, target2: obj):
if target2.anchored == True:
target.velocity = vector2()
else:
half = vector2(target.velocity.x/2, target.velocity.y/2)
target.velocity = vector2(half.x, half.y)
target2.velocity = half
def calcphysobj(self, target: obj):
if target.anchored == True: return
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)
target.position += target.velocity
target.velocity += vector2(0, target.gravity)
target.velocity += target.acceleration
temp = 2
if target.friction != 0:
temp = 2 / target.friction
x = target.velocity.x
y = target.velocity.y
if x != 0:
x = x/temp
if y != 0:
y = y/temp
target.velocity = vector2(x, y)
def addobj(self, obj):
id = ""
for i in range(256):
id = id + random.choice(list(string.ascii_letters))
obj.ID = id
self._objects[id] = obj
def removeobj(self, obj):
self._objects.pop(obj.ID)
obj.ID = NULL()
def removeobjbyid(self, id):
self._objects.pop(id).ID = NULL()
def between(self, min, max, target):
if min < target < max: return True
return False
def getobjbyid(self, id):
return self._objects[id]
def render(self):
for x in range(self._size[0]):
for y in range(self._size[1]):
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
self._renderer.pix(round(pos.x), round(pos.y), i.char, i.bcolor, i.fcolor)
self._renderer.update()
def startscript(self, target):
temp = threading.Thread(target=target)
temp.start()
self._threads.append(temp)
def stopscripts(self):
for i in self._threads:
i.join(.0)
if __name__ == "__main__":
testgame = game()
object = obj()
object.char = "#"
object.anchored = False
object.position = vector2(5, 5)
object.gravity = 1
floor = obj()
floor.char = "#"
floor.anchored = True
floor.position = vector2(5, 9)
floor.gravity = 0
floor.bcolor = color3(255, 255, 255)
testgame.addobj(object)
testgame.addobj(floor)
testgame.render()
print(object.ID)
while True:
testgame.calcphysobj(object)
testgame.calcphysobj(floor)
testgame.render()
time.sleep(0)

View File

@ -0,0 +1,175 @@
import sys
import threading
if sys.version_info[0] == 2:
# Python 2
from Tkinter import *
import Queue as queue
else:
# Python 3
from tkinter import *
import queue
class _Tk(object):
"""Wrapper for underlying attribute tk of class Tk"""
def __init__(self, tk, mt_debug=0, mt_check_period=10):
"""
:param tk: Tkinter.Tk.tk Tk interpreter object
:param mt_debug: Determines amount of debug output.
0 = No debug output (default)
1 = Minimal debug output
...
9 = Full debug output
:param mt_check_period: Amount of time in milliseconds (default
10) 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.
# TODO: Replace custom logging functionality with standard
# TODO: logging.Logger for easier access and standardization
"""
self._tk = tk
# Create the incoming event queue
self._event_queue = queue.Queue(1)
# Identify the thread from which this object is being created
# so we can tell later whether an event is coming from another
# thread.
self._creation_thread = threading.current_thread()
# Create attributes for kwargs
self._debug = mt_debug
self._check_period = mt_check_period
# Destroying flag to be set by the .destroy() hook
self._destroying = False
def __getattr__(self, name):
"""
Diverts attribute accesses to a wrapper around the underlying tk
object.
"""
return _TkAttr(self, getattr(self._tk, name))
class _TkAttr(object):
"""Thread-safe callable attribute wrapper"""
def __init__(self, tk, attr):
self._tk = tk
self._attr = attr
def __call__(self, *args, **kwargs):
"""
Thread-safe method invocation. Diverts out-of-thread calls
through the event queue. Forwards all other method calls to the
underlying tk object directly.
"""
# Check if we're in the creation thread
if threading.current_thread() == self._tk._creation_thread:
# We're in the creation thread; just call the event directly
if self._tk._debug >= 8 or \
self._tk._debug >= 3 and self._attr.__name__ == 'call' and \
len(args) >= 1 and args[0] == 'after':
print('Calling event directly:', self._attr.__name__, args, kwargs)
return self._attr(*args, **kwargs)
else:
if not self._tk._destroying:
# We're in a different thread than the creation thread;
# enqueue the event, and then wait for the response.
response_queue = queue.Queue(1)
if self._tk._debug >= 1:
print('Marshalling event:', self._attr.__name__, args, kwargs)
self._tk._event_queue.put((self._attr, args, kwargs, response_queue), True, 1)
is_exception, response = response_queue.get(True, None)
# Handle the response, whether it's a normal return value or
# an exception.
if is_exception:
ex_type, ex_value, ex_tb = response
raise ex_type(ex_value, ex_tb)
return response
def _Tk__init__(self, *args, **kwargs):
"""
Hook for Tkinter.Tk.__init__ method
:param self: Tk instance
:param args, kwargs: Arguments for Tk initializer
"""
# We support some new keyword arguments that the original __init__ method
# doesn't expect, so separate those out before doing anything else.
new_kwnames = ('mt_check_period', 'mt_debug')
new_kwargs = {
kw_name: kwargs.pop(kw_name) for kw_name in new_kwnames
if kwargs.get(kw_name, None) is not None
}
# Call the original __init__ method, creating the internal tk member.
self.__original__init__mtTkinter(*args, **kwargs)
# Replace the internal tk member with a wrapper that handles calls from
# other threads.
self.tk = _Tk(self.tk, **new_kwargs)
# Set up the first event to check for out-of-thread events.
self.after_idle(_check_events, self)
# Define a hook for class Tk's destroy method.
def _Tk_destroy(self):
self.tk._destroying = True
self.__original__destroy()
def _check_events(tk):
"""Checks events in the queue on a given Tk instance"""
used = False
try:
# Process all enqueued events, then exit.
while True:
try:
# Get an event request from the queue.
method, args, kwargs, response_queue = tk.tk._event_queue.get_nowait()
except queue.Empty:
# No more events to process.
break
else:
# Call the event with the given arguments, and then return
# the result back to the caller via the response queue.
used = True
if tk.tk._debug >= 2:
print('Calling event from main thread:', method.__name__, args, kwargs)
try:
response_queue.put((False, method(*args, **kwargs)))
except SystemExit:
raise # Raises original SystemExit
except Exception:
# Calling the event caused an exception; return the
# exception back to the caller so that it can be raised
# in the caller's thread.
from sys import exc_info # Python 2 requirement
ex_type, ex_value, ex_tb = exc_info()
response_queue.put((True, (ex_type, ex_value, ex_tb)))
finally:
# Schedule to check again. If we just processed an event, check
# immediately; if we didn't, check later.
if used:
tk.after_idle(_check_events, tk)
else:
tk.after(tk.tk._check_period, _check_events, tk)
"""Perform in-memory modification of Tkinter module"""
# Replace Tk's original __init__ with the hook.
Tk.__original__init__mtTkinter = Tk.__init__
Tk.__init__ = _Tk__init__
# Replace Tk's original destroy with the hook.
Tk.__original__destroy = Tk.destroy
Tk.destroy = _Tk_destroy

View File

@ -0,0 +1,184 @@
import hashengine
import random
import ast
import string
import threading
import mtTkinter as tk
import time
global gamedata
gamedata = {}
class rend:
def __init__(self, size, cam, container, offset):
self._size = size
self._grid = {}
self._win = container
self._frame = tk.Frame(container)
self._cam = cam
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(self._frame, text=" ", width=3)
temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update()
self._grid[f"{x}:{y}"] = temp
self._frame.grid()
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class script:
def __init__(self):
self.code = ""
def execute(self, API):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar()
PCPL.LIS("HASHBASE")
PCPL.run(self.code)"""
exec(self.code, API)
def add(objtype):
obj = getattr(types, objtype)()
args = {}
for i in dir(obj):
if i.startswith("_"): continue
args[i] = getattr(obj, i)
temp = {"id": objtype, "args": args, "name": objtype}
id = ""
chars = list(string.ascii_letters)
for i in range(255):
id = id + random.choice(chars)
gamedata[id] = temp
if objtype in crucial:
game.addobj(obj)
gamedata[id]["args"]["ID"] = obj.ID
return id
def importobj(target):
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
#create arguments
outargs = {}
for argname in target["args"]:
arg = target["args"][argname]
if isinstance(arg, dict):
ID = arg.pop("ARGID")
obj = attypes[ID]()
for i in arg:
setattr(obj, i, arg[i])
arg = obj
outargs[argname] = arg
#apply arguments to obj
if target["id"] in crucial:
for i in outargs:
setattr(game.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i])
id["args"].update(outargs)
def load(target):
file = open(target, 'r')
target = file.read()
file.close()
target = ast.literal_eval(target)
for i in target:
importobj(i)
def log(text, end="\n", flush=False):
global logfile
file = open(logfile+".txt", 'a')
file.write(text+end)
file.close()
def NULL():
pass
def run():
print("preparing log file...")
global logfile
global win
global game
temp = time.gmtime(time.time())
logfile = ""
for i in temp:
logfile = logfile + "S" + str(i)
print("done")
log("Log file start!")
log("Preparing API...")
API = {"print": log, "HASHBASE": hashengine}
log("Done!")
API["HASHGAME"] = game
log("main game initalised!")
scripts = []
for i in gamedata:
i = gamedata[i]
if i["id"] != "script": continue
i = i["args"]["code"]
obj = script()
obj.code = i
scripts.append(obj)
for i in scripts:
game.startscript(lambda: i.execute(API))
gamescript = """
global HASHGAME
import time
while True:
for i in HASHGAME._objects:
i = HASHGAME._objects[i]
HASHGAME.calcphysobj(i)
HASHGAME.render()
"""
gameloopsc = script()
gameloopsc.code = gamescript
game.startscript(lambda: gameloopsc.execute(API))
log("game test started!!!")
log("---------------------")
def wait():
time.sleep(0.1)
load("game.HEGF")
run()
global types
global ignoreat
global valtypes
global extypes
global attypes
global crucial
global game
win = tk.Tk()
game = hashengine.game(renderer=lambda size, cam: rend(size, cam, win, [0, 0]))
crucial = ["obj",]
types = hashengine.enum({"obj": hashengine.obj, "script": script})
ignoreat = ["ID", "execute"]
"""self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.touch = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()"""
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
threading.Thread(target=wait).start()
win.mainloop()

View File

@ -1 +0,0 @@
[{'id': 'obj', 'name': 'boden', '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': False, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 1, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': -5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'script', 'name': 'cam', 'args': {'code': 'global HASHGAME\nglobal HASHBASE\nHASHGAME.camera.position = HASHBASE.vector2(4, 6)'}}]

View File

@ -0,0 +1 @@
[{'id': 'obj', 'name': 'boden', 'args': {'anchored': True, 'char': ' ', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 5, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'obj', 'args': {'anchored': False, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 1, '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': 5, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}]

1
tests/mulobjtest 100644

File diff suppressed because one or more lines are too long