pathfinding
parent
9502ee247e
commit
7c8e354103
|
@ -6,6 +6,7 @@ import time
|
|||
import wave
|
||||
import os
|
||||
import math
|
||||
import heapq
|
||||
|
||||
class stdrend:
|
||||
def __init__(self, size, cam):
|
||||
|
@ -151,7 +152,7 @@ def loadsound(path):
|
|||
frames = fd.readframes(1000000000)
|
||||
return frames
|
||||
|
||||
cammode = enum({"editable": 0, "follow": 1})
|
||||
cammode = enum({"editable": 0, "follow": 1, "freecam": 2})
|
||||
|
||||
class event:
|
||||
def __init__(self):
|
||||
|
@ -197,9 +198,20 @@ class camera(obj):
|
|||
self.touch = False
|
||||
self.char = " "
|
||||
|
||||
def update(self):
|
||||
def update(self, game):
|
||||
"""
|
||||
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)
|
||||
"""
|
||||
if self.mode == cammode.follow and self.subject:
|
||||
self.position = self.subject.position
|
||||
if self.mode == cammode.freecam:
|
||||
if game.isdown("w"): self.position += vector2(y=1)
|
||||
if game.isdown("s"): self.position -= vector2(y=1)
|
||||
if game.isdown("a"): self.position += vector2(x=1)
|
||||
if game.isdown("d"): self.position -= vector2(x=1)
|
||||
|
||||
class seqobj:
|
||||
def __init__(self, objects):
|
||||
|
@ -334,6 +346,7 @@ class game:
|
|||
for y in range(self._size[1]):
|
||||
tochange.append((x, y))
|
||||
#self._renderer.pix(x, y, " ", color3(255, 255, 255), color3(255, 255, 255))
|
||||
self.camera.update(self)
|
||||
for i in list(self._objects.values()):
|
||||
if isinstance(i, obj):
|
||||
pos = i.position + self.camera.position
|
||||
|
@ -365,6 +378,80 @@ class game:
|
|||
for i in self.currentsounds:
|
||||
i.stop()
|
||||
|
||||
class pathfinding:
|
||||
def __init__(self, grid_size, objects, game):
|
||||
self.grid_size = grid_size
|
||||
self.objects = objects
|
||||
self._calculate_bounds()
|
||||
self.grid = [[1 for _ in range(self.grid_width)] for _ in range(self.grid_height)]
|
||||
self.game = game
|
||||
self._init_grid()
|
||||
|
||||
def _init_grid(self):
|
||||
for obj in self.objects:
|
||||
if obj.collide:
|
||||
x, y = int(obj.position.x) + self.offset_x, int(obj.position.y) + self.offset_y
|
||||
if 0 <= x < self.grid_width and 0 <= y < self.grid_height:
|
||||
self.grid[y][x] = 0
|
||||
|
||||
def _calculate_bounds(self):
|
||||
min_x, max_x = 0, self.grid_size[0]
|
||||
min_y, max_y = 0, self.grid_size[1]
|
||||
for obj in self.objects:
|
||||
if obj.collide:
|
||||
min_x = min(min_x, int(obj.position.x))
|
||||
max_x = max(max_x, int(obj.position.x))
|
||||
min_y = min(min_y, int(obj.position.y))
|
||||
max_y = max(max_y, int(obj.position.y))
|
||||
self.grid_width = max_x - min_x + 1
|
||||
self.grid_height = max_y - min_y + 1
|
||||
self.offset_x = -min_x
|
||||
self.offset_y = -min_y
|
||||
|
||||
def _heuristic(self, a, b):
|
||||
return abs(a[0] - b[0]) + abs(a[1] - b[1])
|
||||
|
||||
def find_path(self, start, end):
|
||||
self.objects = list(self.game._objects.values())
|
||||
self._calculate_bounds()
|
||||
self._init_grid()
|
||||
start = (int(start.x) + self.offset_x, int(start.y) + self.offset_y)
|
||||
end = (int(end.x) + self.offset_x, int(end.y) + self.offset_y)
|
||||
open_set = []
|
||||
heapq.heappush(open_set, (0, start))
|
||||
came_from = {}
|
||||
g_score = {start: 0}
|
||||
f_score = {start: self._heuristic(start, end)}
|
||||
while open_set:
|
||||
_, current = heapq.heappop(open_set)
|
||||
if math.dist(end, current) <= 1:
|
||||
path = []
|
||||
while current in came_from:
|
||||
path.append(current)
|
||||
current = came_from[current]
|
||||
path.append(start)
|
||||
path.reverse()
|
||||
return [vector2(x - self.offset_x, y - self.offset_y) for x, y in path]
|
||||
|
||||
neighbors = [
|
||||
(current[0] + dx, current[1] + dy)
|
||||
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
||||
if 0 <= current[0] + dx < self.grid_width and 0 <= current[1] + dy < self.grid_height
|
||||
]
|
||||
|
||||
for neighbor in neighbors:
|
||||
if self.grid[neighbor[1]][neighbor[0]] == 0:
|
||||
continue
|
||||
tentative_g_score = g_score[current] + 1
|
||||
|
||||
if neighbor not in g_score or tentative_g_score < g_score[neighbor]:
|
||||
came_from[neighbor] = current
|
||||
g_score[neighbor] = tentative_g_score
|
||||
f_score[neighbor] = tentative_g_score + self._heuristic(neighbor, end)
|
||||
heapq.heappush(open_set, (f_score[neighbor], neighbor))
|
||||
|
||||
return []
|
||||
|
||||
if __name__ == "__main__":
|
||||
testgame = game(sounddir="testsound")
|
||||
object = obj()
|
||||
|
|
23
main.py
23
main.py
|
@ -476,10 +476,11 @@ def halatribute(event):
|
|||
setattr(gamedata[currentobj]["args"][parent], name, new)
|
||||
if "ID" in gamedata[currentobj]["args"]:
|
||||
temp = preview.getobjbyid(gamedata[currentobj]["args"]["ID"])
|
||||
setattr(temp, name, new)
|
||||
setattr(getattr(temp, parent), name, new)
|
||||
atritree.delete(*atritree.get_children())
|
||||
objtree.focus("")
|
||||
updselect(None)
|
||||
preview.render()
|
||||
|
||||
def updatepreviewcam(char):
|
||||
global cooldown
|
||||
|
@ -707,9 +708,11 @@ def testing():
|
|||
|
||||
def APIGEN():
|
||||
global APIPLUG
|
||||
global maingame
|
||||
API = {"print": log, "HASHBASE": hashengine}
|
||||
API["HASHGAME"] = maingame
|
||||
API["SOUND"] = lambda data: gsound(data, maingame)
|
||||
API["PATHFIND"] = hashengine.pathfinding(maingame._size, list(maingame._objects.values()), maingame)
|
||||
for i in APIPLUG:
|
||||
exec(i, globals())
|
||||
temp = globals()["PLUGINAPIFUNC"]()
|
||||
|
@ -1083,7 +1086,6 @@ def GUIinit():
|
|||
menu.add_cascade(label=LH.string("langs"), menu=langmenu)
|
||||
for i in LH.getlangs():
|
||||
langmenu.add_command(label=i, command=lambda i=i: selectlang(i))
|
||||
loadplugins()
|
||||
container.mainloop()
|
||||
|
||||
# attribute changers
|
||||
|
@ -1163,6 +1165,7 @@ def aposx(old):
|
|||
for i in str(tempvar):
|
||||
if not i in numbers:
|
||||
return old
|
||||
if str(tempvar).split(".")[1] == "0": return int(tempvar)
|
||||
return tempvar
|
||||
|
||||
def aposy(old):
|
||||
|
@ -1190,6 +1193,7 @@ def aposy(old):
|
|||
for i in str(tempvar):
|
||||
if not i in numbers:
|
||||
return old
|
||||
if str(tempvar).split(".")[1] == "0": return int(tempvar)
|
||||
return tempvar
|
||||
|
||||
def execgame(gametree, shouldlog=True, fAPIPLUG=[], fRUNPLUG=[]):
|
||||
|
@ -1208,15 +1212,22 @@ def execgame(gametree, shouldlog=True, fAPIPLUG=[], fRUNPLUG=[]):
|
|||
clog = shouldlog
|
||||
run()
|
||||
|
||||
def execcmd(target):
|
||||
try:
|
||||
exec(target, globals())
|
||||
except Exception as e:
|
||||
return e
|
||||
|
||||
def cmd():
|
||||
print(f"hashengine version: {version}")
|
||||
print("CMD")
|
||||
autoexecute = ["loadplugins()"]
|
||||
for i in autoexecute:
|
||||
print(f"> {i}")
|
||||
execcmd(i)
|
||||
while True:
|
||||
cmd = input("> ")
|
||||
try:
|
||||
exec(cmd, globals())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print(execcmd(cmd))
|
||||
|
||||
class rsound:
|
||||
def __init__(self):
|
||||
|
|
|
@ -70,3 +70,10 @@ Hashengine supports audio playback. As previously said, HASHBASE.loadsound(\<PAT
|
|||
to play a sound use SOUND(HASHGAME.sounds[\<Target sound name>]) or if youre using loadsound then SOUND(loadsound(\<PATH>)). this will return a **SOUND** Class which can playback the sound. to play the sound use \<sound>.play().
|
||||
to stop the sound use \<sound>.stop() and to yield until the sound is done playing sue \<sound>.wait()
|
||||
|
||||
## PATHFIND
|
||||
|
||||
### Hashengine provides you with built-in pathfinding
|
||||
|
||||
Hashengine has an built pathfinding system (A*). to use it, use PATHFIND.find_path(\<start vector2>, \<end vector2>).
|
||||
it returns an list of vector2's representing every single waypoint.
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
B #
|
||||
#
|
||||
#
|
||||
A
|
|
@ -0,0 +1 @@
|
|||
[[{'id': 'obj', 'name': 'B', 'SID': 'TqykIpLtCKwtqAdSrksOjKtUmNXVMkXPEnNKVYAjnCbhDGwNbiefXdeJhMxBeNOTWfRCHZWOtdMxmHlcCDPdEXOzGmhuXTQyaVywRqwWOxdVioLSUAZkpivegeBalvtkgfVkIVlaJUGJLHLiOCdncxyNGkciReWUntWGjfQTuIeZSGwWtpakiQQgCZCFpkPUUWYlvLNADLvmCOzKwGQCIMnaVavcHYDEhJStHnzPlYIgASEBDMywrmZeUxtrOlO', 'args': {'anchored': True, 'char': 'B', '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': '#', 'SID': 'TZIeEulKFDdSyFercdukmdlaWqXJtxCNsYUJRehtpqWXtqNrCRIQppHJlLHYlxmOfzSJwjGOMFhOGWFRybutzbfWmxBuuThfZKRaeHqqqdocjkfPxfBVZsqZFTgKYQXcUXtXpXnkSUYZqGZGztgeuOJXyKwTJTLaGMtMfvXmmNXviOlnmBlTbdzgZQoJLTPJqTkmavOKepbCcrzcjDUuCZpfnOaTuehRnyPHFcXbiPIOFRmsqpWfXKwWzREsfyV', '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': 5, 'y': 0, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': '#', 'SID': 'HtBTelOcoHVYzWzpvfwphPDTJCUQgZjmOXomRObTJkhMuefWHbCZPQWSeaGZOcbWXknUYaerTNDmsNOhwAOQZJpHxwrAwtBbyLWuQwggXUXKgWDyUzCNaMLeVaWDEIXRXdWVxmRObSotLnIUDfqByenIsHpitNcMWXCqGpLTzApWHKzhMfIoFoswtqrPydSOOqAWXWLyVhNlhIPjqTUqOyxhBtxJoouAZWfsLBriRwCYQJIsPmFUsWTEZLUzqJi', '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': 5, 'y': 1, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': '#', 'SID': 'rpmRdCpAZzcbSvkgQKCOzzeUnFahtWUVmoEJuXVlVejBTMumOrRRLDLjnpuMkkoztSOaLTVGGEgYzTdAJJXcwfJPXemlENOQFlItDHRojMUmZAlPeCdawyaLqkhHPJPJRVUZCHQOJYlixucjpuqyhcorIUKnzxNYWdQSCIOyHHOIyHMAzZEQLrlwBsCgKAXwTMhNqNXGAEscABPlgvULVegLIbqdVRlQAiQTMbhArjOGxtJhBORsAIUDkrRrViz', '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': 5, 'y': 2, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'A', 'SID': 'kZbEQPYcJFNelliPHswwvvDVeiYGLXYeYvAGHdmDmxdIAFqWlkAFPxNCBlVRXgofJIaBBQaOMUHcnAyFmsHaorUhFIlblXHSdLFsRtLWmkMpPnBmpHrJZhkNCmNEvaZdCtNWnbJfAWdaFOlfHSYNIbenaNQhLXUntneNdMIlpEgWrCVhaOimAcXRDtMwusYibgkCZIIPLnsHtXWcSjjskdzylorzBNCNOJwnLqFLkDLbbeiaoKcqhfdsdMwPNzn', 'args': {'anchored': True, 'char': 'A', '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'}}}, {'id': 'script', 'name': 'Skript', 'SID': 'jjlcqqosdzDsDAjdUlAzeudsNiDEfggOTzGZZdhYPUtMzWPDEnsAgaOpiEeZofjivwPOkkLejUqHRJzIaUwdcNCkeuoEzRyMsLLxoIzzAJbWxlNIcmayhgZDTPAHAEKalgBYizLaxhXISElzdxcaJdoqfAgHJGDkRlvpPPNHoTnizOrVUNcnVpEncJUuOwBevnNRoHhptbJoKRHHsINkJXtkGxIrOVBObXGHlEbXQKyJKSisqvedYtazodZoXUJ', 'args': {'code': 'start = HASHGAME.getobjbySID("TqykIpLtCKwtqAdSrksOjKtUmNXVMkXPEnNKVYAjnCbhDGwNbiefXdeJhMxBeNOTWfRCHZWOtdMxmHlcCDPdEXOzGmhuXTQyaVywRqwWOxdVioLSUAZkpivegeBalvtkgfVkIVlaJUGJLHLiOCdncxyNGkciReWUntWGjfQTuIeZSGwWtpakiQQgCZCFpkPUUWYlvLNADLvmCOzKwGQCIMnaVavcHYDEhJStHnzPlYIgASEBDMywrmZeUxtrOlO")\nend = HASHGAME.getobjbySID("kZbEQPYcJFNelliPHswwvvDVeiYGLXYeYvAGHdmDmxdIAFqWlkAFPxNCBlVRXgofJIaBBQaOMUHcnAyFmsHaorUhFIlblXHSdLFsRtLWmkMpPnBmpHrJZhkNCmNEvaZdCtNWnbJfAWdaFOlfHSYNIbenaNQhLXUntneNdMIlpEgWrCVhaOimAcXRDtMwusYibgkCZIIPLnsHtXWcSjjskdzylorzBNCNOJwnLqFLkDLbbeiaoKcqhfdsdMwPNzn")\nHASHGAME.camera.mode = 2\npath = PATHFIND.find_path(start.position, end.position)\nfor i in path:\n\ttemp = HASHBASE.obj()\n\ttemp.position = i\n\ttemp.char = "-"\n\ttemp.anchored = True\n\tHASHGAME.addobj(temp)'}}], {'Erstellte Objekte': [0, 1, 2, 3, 4]}, 10, 10]
|
Loading…
Reference in New Issue