camera system and saving/loading

main
Justus Jan Nico Wolff 2024-05-12 17:44:34 +02:00
parent 6329f77d3b
commit 7dffa204a0
7 changed files with 159 additions and 22 deletions

2
clang
View File

@ -1 +1 @@
en_EN de_DE

View File

@ -1,9 +1,10 @@
import tkinter as tk import tkinter as tk
import string import string
import random import random
import threading
class stdrend: class stdrend:
def __init__(self, size): def __init__(self, size, cam):
self._size = size self._size = size
self._grid = {} self._grid = {}
self._win = tk.Tk() self._win = tk.Tk()
@ -34,6 +35,7 @@ class color3:
self.r = r self.r = r
self.g = g self.g = g
self.b = b self.b = b
self._type = "color3"
def __add__(self, v): def __add__(self, v):
temp = color3(self.r+v.r, self.g+v.g, self.b+v.b) temp = color3(self.r+v.r, self.g+v.g, self.b+v.b)
@ -81,6 +83,7 @@ class vector2:
def __init__(self, x=0, y=0): def __init__(self, x=0, y=0):
self.x = x self.x = x
self.y = y self.y = y
self._type = "vector2"
def __add__(self, v): def __add__(self, v):
return vector2(self.x+v.x, self.y+v.y) return vector2(self.x+v.x, self.y+v.y)
@ -115,6 +118,14 @@ class enum:
cammode = enum({"editable": 0, "follow": 1}) cammode = enum({"editable": 0, "follow": 1})
class event:
def __init__(self):
self._attached = []
def execute(self):
for i in self._attached:
threading.Thread(target=i).start()
class obj: class obj:
def __init__(self): def __init__(self):
self.position = vector2() self.position = vector2()
@ -147,9 +158,9 @@ class game:
def __init__(self, size=[10, 10], renderer=stdrend): def __init__(self, size=[10, 10], renderer=stdrend):
if renderer == None: raise TypeError("Renderer class needed!") if renderer == None: raise TypeError("Renderer class needed!")
self._size = size self._size = size
self._renderer = renderer(size)
self._objects = {} self._objects = {}
self.camera = camera() self.camera = camera()
self._renderer = renderer(size, self.camera)
def addobj(self, obj): def addobj(self, obj):
id = "" id = ""
@ -173,6 +184,9 @@ class game:
return self._objects[id] return self._objects[id]
def render(self): 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()): for i in list(self._objects.values()):
pos = i.position + self.camera.position 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 if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue

View File

@ -15,8 +15,12 @@
"attribute-val": "Wert", "attribute-val": "Wert",
"newval": "Neuen Wert eingeben", "newval": "Neuen Wert eingeben",
"error": "Fehler", "error": "Fehler",
"SCE": "Länge des neuen Wertes muss 1 sein!", "SCE": "Laenge des neuen Wertes muss 1 sein!",
"true": "Wahr", "true": "Wahr",
"false": "Falsch", "false": "Falsch",
"objs": "Objekte", "objs": "Objekte",
"suc": "Erfolg!",
"save-suc": "Gespeichert!",
"xcam": "Kamera x Position:",
"ycam": "Kamera y Position:",
} }

View File

@ -18,5 +18,9 @@
"SCE": "Length of the new value must be 1!", "SCE": "Length of the new value must be 1!",
"true": "True", "true": "True",
"false": "False", "false": "False",
"objs": "Objects" "objs": "Objects",
"suc": "Success!",
"save-suc": "Saved!",
"xcam": "Camera x position:",
"ycam": "Camera y position:",
} }

147
main.py
View File

@ -4,11 +4,13 @@ sys.dont_write_bytecode = True
import mtTkinter as tk import mtTkinter as tk
from tkinter import ttk as tkk from tkinter import ttk as tkk
from tkinter import messagebox from tkinter import messagebox
from tkinter import filedialog
import PCPL import PCPL
import langsys import langsys
import time import ast
import subprocess import subprocess
import sys import sys
import time
import hashengine import hashengine
import os import os
import random import random
@ -17,6 +19,8 @@ import easygui
global LH global LH
global gamedata global gamedata
global cooldown
cooldown = False
gamedata = {} gamedata = {}
LH = langsys.langhandler() LH = langsys.langhandler()
lang = open("clang", 'r') lang = open("clang", 'r')
@ -26,26 +30,61 @@ LH.setlang(lang)
PCPL.interpreter.ENG = hashengine PCPL.interpreter.ENG = hashengine
def prepgamedata():
out = []
for i in gamedata:
i = gamedata[i]
temp = {"id": i["id"], "name": i["name"]}
tempargs = {}
tosearch = {}
for arg in i["args"]:
if not arg in extypes and not arg in ignoreat:
tosearch[arg] = i["args"][arg]
continue
if arg in ignoreat: continue
tempargs[arg] = i["args"][arg]
for argname in tosearch:
arg = tosearch[argname]
temp2 = getattributes(arg)
temp2.update({"ARGID": arg._type})
tempargs[argname] = temp2
temp["args"] = tempargs
out.append(temp)
return out
class script: class script:
def __init__(self): def __init__(self):
self.code = "" self.code = ""
def execute(self): def execute(self, API):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar() PCPL.resetvar()
PCPL.LIS("HASHBASE") PCPL.LIS("HASHBASE")
PCPL.run(self.code) PCPL.run(self.code)"""
prep = {"HASHAPI": API}
exec(self.code, prep)
class previewrend: class previewrend:
def __init__(self, size, container, offset): def __init__(self, size, cam, container, offset):
self._size = size self._size = size
self._grid = {} self._grid = {}
self._win = container self._win = container
self._frame = tk.Frame(container)
self._posframe = tk.Frame(self._frame)
self._cam = cam
self._xcam = tk.Label(self._posframe, text="-")
self._ycam = tk.Label(self._posframe, text="-")
self._xcam.grid(row=size[1], column=0)
self._ycam.grid(row=size[1]+1, column=0)
for y in range(size[1]): for y in range(size[1]):
for x in range(size[0]): for x in range(size[0]):
temp = tk.Label(text=" ") temp = tk.Label(self._frame, text=" ", borderwidth=1, relief=tk.GROOVE, width=3)
temp.grid(row=y+offset[1], column=x+offset[0]) temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update() self._win.update()
self._grid[f"{x}:{y}"] = temp self._grid[f"{x}:{y}"] = temp
self._posframe.grid()
self._frame.grid()
def coltohex(self, target): def coltohex(self, target):
colors = [] colors = []
@ -58,6 +97,8 @@ class previewrend:
return "#"+out return "#"+out
def pix(self, x, y, text, bcolor, fcolor): def pix(self, x, y, text, bcolor, fcolor):
self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x))
self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y))
if f"{x}:{y}" in self._grid: if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
self._win.update() self._win.update()
@ -71,7 +112,6 @@ def selectlang(new):
def add(objtype): def add(objtype):
global objtree global objtree
crucial = ["obj"]
obj = getattr(types, objtype)() obj = getattr(types, objtype)()
args = {} args = {}
for i in dir(obj): for i in dir(obj):
@ -88,6 +128,7 @@ def add(objtype):
preview.addobj(obj) preview.addobj(obj)
gamedata[id]["args"]["ID"] = obj.ID gamedata[id]["args"]["ID"] = obj.ID
preview.render() preview.render()
return id
def renameobj(): def renameobj():
target = objtree.focus() target = objtree.focus()
@ -102,7 +143,10 @@ def delobj():
if target == "": return if target == "": return
atritree.delete(*atritree.get_children()) atritree.delete(*atritree.get_children())
objtree.delete(target) objtree.delete(target)
gamedata.pop(target) temp = gamedata.pop(target)
if temp["id"] in crucial:
preview.removeobjbyid(temp["args"]["ID"])
preview.render()
def rpopup(event): def rpopup(event):
try: try:
@ -153,6 +197,66 @@ def halatribute(event):
atritree.item(target, values=(new)) atritree.item(target, values=(new))
preview.render() preview.render()
def updatepreviewcam(char):
global cooldown
if cooldown == True: return
cooldown = True
char = char.char
if char == "w": preview.camera.position += hashengine.vector2(y=1)
if char == "a": preview.camera.position += hashengine.vector2(x=1)
if char == "s": preview.camera.position -= hashengine.vector2(y=1)
if char == "d": preview.camera.position -= hashengine.vector2(x=1)
preview.render()
time.sleep(0)
cooldown = False
def save():
target = filedialog.asksaveasfile()
target.write(str(prepgamedata()))
target.close()
messagebox.showinfo(LH.string("suc"), LH.string("save-suc"))
def clear():
global gamedata
objtree.delete(*objtree.get_children())
atritree.delete(*atritree.get_children())
gamedata = {}
preview._objects = {}
preview.camera.position = hashengine.vector2()
preview.render()
def importobj(target):
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
objtree.item(oid, text=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(preview.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i])
id["args"].update(outargs)
def load():
file = filedialog.askopenfile()
target = file.read()
file.close()
target = ast.literal_eval(target)
clear()
for i in target:
importobj(i)
preview.render()
def GUIinit(): def GUIinit():
global container global container
global objtree global objtree
@ -161,6 +265,7 @@ def GUIinit():
global currentat global currentat
global preview global preview
container = tk.Tk() container = tk.Tk()
container.bind("<KeyPress>", updatepreviewcam)
global icons global icons
icons = {} icons = {}
@ -169,13 +274,13 @@ def GUIinit():
icons[i.split(".")[0]] = tk.PhotoImage(file=f"icons/{i}") icons[i.split(".")[0]] = tk.PhotoImage(file=f"icons/{i}")
#preview init #preview init
preview = hashengine.game(renderer=lambda size: previewrend(size, container=container, offset=[0, 0])) preview = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, container=container, offset=[0, 0]))
#tree init #tree init
objtree = tkk.Treeview(container, selectmode="browse") objtree = tkk.Treeview(container, selectmode="browse", columns=("-"))
objtree.heading("#0", text=LH.string("objs")) objtree.heading("#0", text=LH.string("objs"))
objtree.tag_bind("objsel", "<<TreeviewSelect>>", updatribute) objtree.tag_bind("objsel", "<<TreeviewSelect>>", updatribute)
objtree.grid(row=10, column=11) objtree.grid(row=1, column=0)
#attribute tree init #attribute tree init
currentat = "temp" currentat = "temp"
@ -183,7 +288,7 @@ def GUIinit():
atritree.heading("#0", text=LH.string("attribute")) atritree.heading("#0", text=LH.string("attribute"))
atritree.heading("#1", text=LH.string("attribute-val")) atritree.heading("#1", text=LH.string("attribute-val"))
atritree.bind("<Double-1>", halatribute) atritree.bind("<Double-1>", halatribute)
atritree.grid(row=11, column=11) atritree.grid(row=2, column=0)
#right click menu #right click menu
rmenu = tk.Menu(container, tearoff=0) rmenu = tk.Menu(container, tearoff=0)
@ -197,9 +302,9 @@ def GUIinit():
container.config(menu=menu) container.config(menu=menu)
filemenu = tk.Menu(menu) filemenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("file"), menu=filemenu) menu.add_cascade(label=LH.string("file"), menu=filemenu)
filemenu.add_command(label=LH.string("new")) filemenu.add_command(label=LH.string("new"), command=clear)
filemenu.add_command(label=LH.string("open")) filemenu.add_command(label=LH.string("open"), command=load)
filemenu.add_command(label=LH.string("save")) filemenu.add_command(label=LH.string("save"), command=save)
filemenu.add_separator() filemenu.add_separator()
filemenu.add_command(label=LH.string("exit"), command=container.quit) filemenu.add_command(label=LH.string("exit"), command=container.quit)
@ -249,8 +354,12 @@ global types
global icon global icon
global ignoreat global ignoreat
global valtypes global valtypes
global extypes
global attypes
global crucial
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.pngg"}) 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 = " "
@ -279,5 +388,9 @@ valtypes = {
"anchored": abool, "anchored": abool,
"code": acode, "code": acode,
} }
extypes = list(valtypes.keys())
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
GUIinit() GUIinit()

View File

@ -0,0 +1 @@
[{'id': 'obj', 'name': 'Objekt', 'args': {'anchored': False, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'touch': True, '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': 0, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}]

1
tests/EXTobjtest 100644
View File

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