追逐函数考虑到pygame中前面的矩形

时间:2014-10-31 17:18:56

标签: python pygame

我有两只动物,猫和老鼠。猫必须追逐老鼠。

我根据这篇文章写了这个函数:Pygame making an object chase the cursor

def chase(self):
        dx = mouse.rect.x - self.rect.x
        dy = mouse.rect.y - self.rect.y
        distance = math.sqrt(dx*dx + dy*dy)
        dx /= distance
        dy /= distance
        dx *= 8
        dy *= 8
        self.move(dx, dy)
        pygame.display.update()

但我的屏幕看起来像这样:

level_definition = """
WWWWWWWWW
        W
W W     W
W W  P  W
WWWWWWWWW
"""

因此屏幕中间有墙。当猫正在追逐鼠标时,如何更改功能以便将其记入墙壁?

修改

感谢JoranBeasley,我知道我需要使用A 搜索算法来查找路径。找到此链接:http://code.google.com/p/find-a-way/downloads/list。它包含solver.py,其中包含可以找到路径的A 星型算法类。不知道如何将它合并到这个例子中。不知道如何在Star类中输入障碍。

Solver看起来像这样:

class Star(object):
    """This class is the astar algorithm itself.  The goal is to make it
    flexible enough that it can be used in isolation."""
    def __init__(self,start,end,move_type,barriers):
        """Arguments start and end are coordinates to start solving from and to.
        move_type is a string cooresponding to the keys of the ADJACENTS and
        HEURISTICS constant dictionaries. barriers is a set of cells which the
        agent is not allowed to occupy."""
        self.start,self.end = start,end
        self.moves = ADJACENTS[move_type]
        self.heuristic = HEURISTICS[move_type]
        self.barriers = barriers
        self.setup()

    def setup(self):
        """Initialize sets,dicts and others"""
        self.closed_set = set((self.start,)) #Set of cells already evaluated
        self.open_set   = set() #Set of cells to be evaluated.
        self.came_from = {} #Used to reconstruct path once solved.
        self.gx = {self.start:0} #Cost from start to current position.
        self.hx = {} #Optimal estimate to goal based on heuristic.
        self.fx = {} #Distance-plus-cost heuristic function.
        self.current = self.start
        self.current = self.follow_current_path()
        self.solution = []
        self.solved = False

    def get_neighbors(self):
        """Find adjacent neighbors with respect to how our agent moves."""
        neighbors = set()
        for (i,j) in self.moves:
            check = (self.current[0]+i,self.current[1]+j)
            if check not in (self.barriers|self.closed_set):
                neighbors.add(check)
        return neighbors

    def follow_current_path(self):
        """In the very common case of multiple points having the same heuristic
        value, this function makes sure that points on the current path take
        presidence.  This is most obvious when trying to use astar on an
        obstacle free grid."""
        next_cell = None
        for cell in self.get_neighbors():
            tentative_gx = self.gx[self.current]+1
            if cell not in self.open_set:
                self.open_set.add(cell)
                tentative_best = True
            elif cell in self.gx and tentative_gx < self.gx[cell]:
                tentative_best = True
            else:
                tentative_best = False

            if tentative_best:
                x,y = abs(self.end[0]-cell[0]),abs(self.end[1]-cell[1])
                self.came_from[cell] = self.current
                self.gx[cell] = tentative_gx
                self.hx[cell] = self.heuristic(x,y)
                self.fx[cell] = self.gx[cell]+self.hx[cell]
                if not next_cell or self.fx[cell]<self.fx[next_cell]:
                    next_cell = cell
        return next_cell

    def get_path(self,cell):
        """Recursively reconstruct the path. No real need to do it recursively."""
        if cell in self.came_from:
            self.solution.append(cell)
            self.get_path(self.came_from[cell])

    def evaluate(self):
        """Core logic for executing the astar algorithm."""
        if self.open_set and not self.solved:
            for cell in self.open_set:
                if (self.current not in self.open_set) or (self.fx[cell]<self.fx[self.current]):
                    self.current = cell
            if self.current == self.end:
                self.get_path(self.current)
                self.solved = True
            self.open_set.discard(self.current)
            self.closed_set.add(self.current)
            self.current = self.follow_current_path()
        elif not self.solution:
            self.solution = "NO SOLUTION"

编辑:

错误:

Exception in thread Thread-128:
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 1082, in run
    self.function(*self.args, **self.kwargs)
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/Test.py", line 198, in printit
    cat.chase()
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/Test.py", line 65, in chase
    best_path = get_current_best_path()
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/Test.py", line 153, in get_current_best_path
    return MyAStar(start_pt,end_pt,barriers).get_best_path()
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/Test.py", line 142, in __init__
    self.setup()
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/solver.py", line 64, in setup
    self.current = self.follow_current_path()
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/solver.py", line 83, in follow_current_path
    for cell in self.get_neighbors():
  File "/Users/cnnlakshmen_2000/Dropbox/Pygame/solver.py", line 73, in get_neighbors
    if check not in (self.barriers|self.closed_set):
TypeError: unsupported operand type(s) for |: 'list' and 'set'

代码:https://www.dropbox.com/s/omqj5121ev43mxc/Test.py?dl=0

1 个答案:

答案 0 :(得分:1)

类似这样的事情

from solver import Star
class MyAStar(Star):
    def __init__(self,start_pt,end_pt,barriers):
      self.start,self.end = start_pt,end_pt
      self.moves = ADJACENTS[move_type]
      self.barriers = barriers
      self.setup()

    def heuristic(self,x,y):
      return (x-self.end[0])**2 + (y - self.end[0])**2
    def get_best_path(self):
      self.evaluate()
      return self.solution

def get_current_best_path():
  start_pt,end_pt = (enemy.x,enemy.y),(mouse.x,mouse.y) 
  barriers = [(barrier1.x,barrier1.y),...,(barrierN.x,barrierN.y)]
  return Star(start_pt,end_pt,barriers).get_best_path()

best_path = get_current_best_path()
moves = 0
RECALC_PATH_COUNT = 5 #recalculate path every five moves
while best_path: # you would do this in the chase function
  next_move = best_path.pop()
  moves += 1
  if moves > RECALC_PATH_COUNT:
    moves = 0
    best_path = get_current_best_path()