added pathfinding
This commit is contained in:
parent
dd85d592e1
commit
1b1c170d6b
|
@ -8,6 +8,7 @@ import math
|
|||
import time
|
||||
import threading
|
||||
import pickle
|
||||
from pathfinding import pathfinding
|
||||
#import itertools
|
||||
#import multiprocessing
|
||||
|
||||
|
@ -49,7 +50,6 @@ class game:
|
|||
self._objects = {}
|
||||
self._visobjects = {}
|
||||
self._camera = obj()
|
||||
self._camera.position = vector2()
|
||||
self._camera.zoom = pixelsize
|
||||
self._OAPUPDATING = False
|
||||
self._handler = audiosys.handler()
|
||||
|
@ -113,9 +113,13 @@ class game:
|
|||
self._root.children.append(target)
|
||||
self.addtooap(target)
|
||||
|
||||
def getobjbyid(self, id):
|
||||
if not id in self._objects: raise TypeError(f"No object with id {id} was found")
|
||||
return self._objects[id]
|
||||
|
||||
def removeobj(self, target: obj):
|
||||
if target in self._visobjects: self._visobjects.pop(target)
|
||||
if target in self._objects: self._objects.pop(target)
|
||||
if target.id in self._visobjects: self._visobjects.pop(target.id)
|
||||
if target.id in self._objects: self._objects.pop(target.id)
|
||||
self.remfromoap(target)
|
||||
|
||||
def distance(self, pos1, pos2):
|
||||
|
@ -174,12 +178,14 @@ class game:
|
|||
def render(self):
|
||||
if self._OAPUPDATING == False: threading.Thread(target=self.updallobjpositions).start()
|
||||
self._canvas.delete(tk.ALL)
|
||||
self._height = int(canvas.winfo_reqheight()/self._camera.zoom)
|
||||
self._width = int(canvas.winfo_reqwidth()/self._camera.zoom)
|
||||
self._height = int(self._canvas.winfo_reqheight()/self._camera.zoom)
|
||||
self._width = int(self._canvas.winfo_reqwidth()/self._camera.zoom)
|
||||
self._pixelsize = self._camera.zoom
|
||||
for y in range(self._camera.position.y, self._height+self._camera.position.y):
|
||||
for x in range(self._camera.position.y, self._width+self._camera.position.y):
|
||||
obj = self.getfromoap(vector2(x, y))
|
||||
#for y in range(self._camera.position.y, self._height+self._camera.position.y):
|
||||
#for x in range(self._camera.position.x, self._width+self._camera.position.x):
|
||||
for y in range(self._height):
|
||||
for x in range(self._width):
|
||||
obj = self.getfromoap(vector2(x+self._camera.position.x, y+self._camera.position.y))
|
||||
if len(obj) == 0: continue
|
||||
obj = obj[0]
|
||||
self._canvas.create_rectangle(x*self._pixelsize, y*self._pixelsize, x*self._pixelsize+self._pixelsize, y*self._pixelsize+self._pixelsize, fill=obj.color.__tohex__(), width=0)
|
||||
|
@ -244,7 +250,7 @@ class game:
|
|||
self.readdobj(self._root.children, TLB)
|
||||
|
||||
if not "__CMD__" in globals():
|
||||
from PIL import Image
|
||||
"""from PIL import Image
|
||||
from tkinter import filedialog
|
||||
root = tk.Tk()
|
||||
canvas = tk.Canvas(root)
|
||||
|
@ -269,4 +275,41 @@ if not "__CMD__" in globals():
|
|||
temp.render()
|
||||
root.update()
|
||||
print()
|
||||
input("press enter to exit.")"""
|
||||
root = tk.Tk()
|
||||
canvas = tk.Canvas(root)
|
||||
canvas.grid()
|
||||
temp = game(canvas)
|
||||
temp._camera.position.x = -5
|
||||
temp._camera.position.y = -10
|
||||
pathfind = pathfinding(temp)
|
||||
start = obj()
|
||||
start.position = vector2(-3, -3)
|
||||
start.color = color3(0, 255)
|
||||
temp.addobj(start)
|
||||
goal = obj()
|
||||
goal.position = vector2(50, 80)
|
||||
goal.color = color3(255)
|
||||
temp.addobj(goal)
|
||||
tempobjlist = []
|
||||
out = pathfind.find_path(start.position, goal.position)
|
||||
for i in out:
|
||||
tempobj = obj()
|
||||
tempobj.position = i
|
||||
tempobjlist.append(tempobj)
|
||||
temp.addobj(tempobj)
|
||||
for i in range(50):
|
||||
goal.position.y -= 1
|
||||
for i in tempobjlist:
|
||||
temp.removeobj(i)
|
||||
#temp.updallobjpositions()
|
||||
out = pathfind.find_path(start.position, goal.position)
|
||||
for i in out:
|
||||
tempobj = obj()
|
||||
tempobj.position = i
|
||||
temp.addobj(tempobj)
|
||||
tempobjlist.append(tempobj)
|
||||
temp.render()
|
||||
root.update()
|
||||
input("press enter to exit.")
|
||||
|
||||
|
|
78
pathfinding.py
Normal file
78
pathfinding.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
import heapq
|
||||
from HEMD import vector2
|
||||
import math
|
||||
|
||||
class pathfinding:
|
||||
def __init__(self, game):
|
||||
self.grid_size = [game._width, game._height]
|
||||
self.objects = list(game._visobjects.values())
|
||||
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._visobjects.values())
|
||||
self._calculate_bounds()
|
||||
self.grid = [[1 for _ in range(self.grid_width)] for _ in range(self.grid_height)]
|
||||
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 []
|
Loading…
Reference in a new issue