added pathfinding
This commit is contained in:
parent
dd85d592e1
commit
1b1c170d6b
|
@ -8,6 +8,7 @@ import math
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import pickle
|
import pickle
|
||||||
|
from pathfinding import pathfinding
|
||||||
#import itertools
|
#import itertools
|
||||||
#import multiprocessing
|
#import multiprocessing
|
||||||
|
|
||||||
|
@ -49,7 +50,6 @@ class game:
|
||||||
self._objects = {}
|
self._objects = {}
|
||||||
self._visobjects = {}
|
self._visobjects = {}
|
||||||
self._camera = obj()
|
self._camera = obj()
|
||||||
self._camera.position = vector2()
|
|
||||||
self._camera.zoom = pixelsize
|
self._camera.zoom = pixelsize
|
||||||
self._OAPUPDATING = False
|
self._OAPUPDATING = False
|
||||||
self._handler = audiosys.handler()
|
self._handler = audiosys.handler()
|
||||||
|
@ -113,9 +113,13 @@ class game:
|
||||||
self._root.children.append(target)
|
self._root.children.append(target)
|
||||||
self.addtooap(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):
|
def removeobj(self, target: obj):
|
||||||
if target in self._visobjects: self._visobjects.pop(target)
|
if target.id in self._visobjects: self._visobjects.pop(target.id)
|
||||||
if target in self._objects: self._objects.pop(target)
|
if target.id in self._objects: self._objects.pop(target.id)
|
||||||
self.remfromoap(target)
|
self.remfromoap(target)
|
||||||
|
|
||||||
def distance(self, pos1, pos2):
|
def distance(self, pos1, pos2):
|
||||||
|
@ -174,12 +178,14 @@ class game:
|
||||||
def render(self):
|
def render(self):
|
||||||
if self._OAPUPDATING == False: threading.Thread(target=self.updallobjpositions).start()
|
if self._OAPUPDATING == False: threading.Thread(target=self.updallobjpositions).start()
|
||||||
self._canvas.delete(tk.ALL)
|
self._canvas.delete(tk.ALL)
|
||||||
self._height = int(canvas.winfo_reqheight()/self._camera.zoom)
|
self._height = int(self._canvas.winfo_reqheight()/self._camera.zoom)
|
||||||
self._width = int(canvas.winfo_reqwidth()/self._camera.zoom)
|
self._width = int(self._canvas.winfo_reqwidth()/self._camera.zoom)
|
||||||
self._pixelsize = self._camera.zoom
|
self._pixelsize = self._camera.zoom
|
||||||
for y in range(self._camera.position.y, self._height+self._camera.position.y):
|
#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):
|
#for x in range(self._camera.position.x, self._width+self._camera.position.x):
|
||||||
obj = self.getfromoap(vector2(x, y))
|
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
|
if len(obj) == 0: continue
|
||||||
obj = obj[0]
|
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)
|
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)
|
self.readdobj(self._root.children, TLB)
|
||||||
|
|
||||||
if not "__CMD__" in globals():
|
if not "__CMD__" in globals():
|
||||||
from PIL import Image
|
"""from PIL import Image
|
||||||
from tkinter import filedialog
|
from tkinter import filedialog
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
canvas = tk.Canvas(root)
|
canvas = tk.Canvas(root)
|
||||||
|
@ -269,4 +275,41 @@ if not "__CMD__" in globals():
|
||||||
temp.render()
|
temp.render()
|
||||||
root.update()
|
root.update()
|
||||||
print()
|
print()
|
||||||
input("press enter to exit.")
|
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