2017-09-15 23 views
2

在我的2D遊戲中,我有幾個具有空self.target = []屬性的「單元」對象實例(精靈對象)初始化後。Python如何檢查目標對象是否不再是相同的實例或「有效」

然後,他們會在附近找到一個有效的「植物」目標對象,這將成爲細胞的「self.target」。

'細胞'然後將導向植物,最終碰撞並吃掉它,然後植物被設置爲「.kill()」,另一種植物在隨機的新座標處重新生成。有幾個工廠實例(spr_plant_group的一部分)和幾個單元(屬於spr_cell_group)。每個植物'X'的生命值(我認爲是200),如果沒有被吃掉,就是.kill() - ed,並且一個新的植物在隨機座標下產生。

問題是這樣的:如果一個細胞的目標植物碰巧從年齡開始消失,或被某物吃掉,那麼細胞的self.target信息仍然指向舊的「植物」對象的數據。這意味着單元格正在追逐一個幻影對象,顯然還有一個有效的x和y座標。

問題:我如何告訴細胞它的目標是死的,消失了,無效?如果我能做到這一點,我認爲它會解決'幻影'目標對象。的相關代碼

件:

class Agent(sprite.Sprite): 

def __init__(self, sense_range, size, food, maxspeed): 

    sprite.Sprite.__init__(self) 
    self.x = randint(0,450) 
    self.y = randint(0,450) 
    self.ang = randint(0,359) 
    self.turn_rate = 2 
    self.dx = 0 
    self.dy = 0 
    self.speed = 1 
    self.maxspeed = maxspeed 
    self.food = int(food) 
    self.max_food = food*1.5 
    self.target = [] 
    self.sense_range = sense_range 

# Snip------This part below is supposed to find a new target, but it only 
# works for the first one when the cell spawns, then I can't seem to 
# get it to become 'empty' so that the "if self.target == []" can do its 
# thing.... 

    def seek_food(self): 

    if (self.target == []): 
     #find cell a target within "sense_range" distance (say 200 pixels) 
     dist = self.sense_range 
     targ = [] 
     for t in spr_plant_group: 
      t_dist = abs(self.x - t.x) 
      if t_dist <= dist: 
       targ = t 
       dist = t_dist 

     self.target = targ 
     print ("Found target...",dist, self.target) 

    else: 
     #already have a target, so move cell toward target 
     dx = self.target.x - self.x 
     dy = self.target.y - self.y 
     rads = atan2(dy,dx) 
     rads %= 2*pi 
     degs = degrees(rads) 
     direction = degs - self.ang 
     if direction > 0: 
      self.ang = self.ang + self.turn_rate 
     elif direction < 0: 
      self.ang = self.ang - self.turn_rate 

     # Correct for angle being out of 0-360* range 
     if self.ang > 360: 
      self.ang -= 360 
     elif self.ang < 0: 
      self.ang += 360 

#---This is just a piece of the Plant class for your reference 

class Plant (sprite.Sprite): 
def __init__(self): 

    sprite.Sprite.__init__(self) 

    self.x = randint(0,450) 
    self.y = randint(0,450) 
    self.age = 1 + randint(0,50) 

作爲參考,下面。植物年齡的增加,直到200個蜱,然後他們殺了,和一個新的重生......

def update_plants(): 
for shrub in spr_plant_group: 
    shrub.age += 1 

    # Respawn a new plant in a different place 
    if shrub.age >= 200: 
     shrub.kill() 
     plant.append (Plant()) 

回答

1

編輯:其實,這是一個簡單得多。 Pygame's Sprite class supports an alive method,所以才這樣做:

def seek_food(self): 
    if (self.target == [] or not self.target.alive()): 
     # Find a new target that isn't dead... 
    else: 
     # Move to the (alive) target... 

您可以使用the Observer design pattern一些變種。用一個額外的屬性擴展你的Plant類,跟蹤任何以工廠爲目標的Cell實例。當一個細胞針對一個植物時,它會將它自己添加到植物的列表中。在工廠死亡之前,它會通知其所有的電池。

在植物類新的屬性:

class Plant (sprite.Sprite): 
    def __init__(self): 
     # ... 
     self.followers = [] 
     # ... 

細胞訂閱追隨者的工廠的名單:

def seek_food(self): 
    if (self.target == []): 
     # ... 
     self.target = targ 
     self.target.followers.append(self) 
     # ... 
    else: 
     # ... 

植物類重寫它的父類殺功能,所以它在死前通知它的追隨者:

(這裏,小區類是直接修改每個工廠的目標,但你可以封裝不同,如果你想要的行爲)

def kill(self): 
    for follower in self.followers: 
     follower.target = [] 
    self.followers = [] 

    super().kill() 
+0

「細胞類重寫它的父類的殺滅作用,使其前通知其追隨者死亡:「 你的意思是>>植物<<類(不是細胞)覆蓋它的殺死功能,所以它可以先清除它的追隨者列表?這會更有意義。 – PySam

+0

我實現了你的建議,並且完全按照我的需要工作。 細胞重新獲得一個新的植物目標,如果他們的舊的死亡或被食用,並改變他們的過程截獲。 謝謝!看起來像一個非常明顯的解決方案與sprite.alive(),我清楚地忘記了! – PySam

相關問題