2014-03-28 18 views
0

我想製作一個遊戲,你可以在屏幕上移動一個角色,並且如果我的角色碰到了一棵樹的圖片,角色會停止移動。得到這個工作後,我試圖做的是改變代碼,而不是僅僅使用樹變量,我想遍歷一個小部件列表,這樣如果我的角色遇到它們中的任何一個,我的角色就​​會停止移動。奇怪的是,當我在列表中只有一個小部件時,它可以工作。例如,如果我在代碼中放置list [0]或list [1],那麼遇到這些小部件時我的角色將停止。但是,如果我在列表中有多個小部件並嘗試遍歷列表,它不起作用,那麼在遇到任何小部件時我的角色不會停止。爲什麼我無法遍歷對象來檢查碰撞

我猜我做了for循環的錯誤。最終我需要它,這樣如果我的角色進入列表中的任何圖像,角色將停止移動。

這是我for循環的代碼片段,下面我已經包含了整個代碼(如果有幫助的話)。

段:

def on_keyboard_down(self, keyboard, keycode, text, modifiers): 
    if keycode[1] == 'left': 
     self.source = 'selectionscreen/left.zip' 
     self.anim_delay=.20 
     if self.x < (Window.width * .25): 
      bglayout.x += 4 
     else: 
      for i in listofwidgets: 
       if self.collide_widget(i): 
        self.x -=0 
       else: 
        self.x -=6 

全碼:

from kivy.app import App 
from kivy.uix.widget import Widget 
from kivy.uix.image import Image 
from kivy.core.window import Window 
from kivy.uix.screenmanager import ScreenManager, Screen 
from kivy.uix.label import Label 
from kivy.uix.behaviors import ButtonBehavior 
from kivy.core.audio import SoundLoader 
from kivy.uix.relativelayout import RelativeLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.gridlayout import GridLayout 
from kivy.uix.screenmanager import FallOutTransition 
from kivy.clock import Clock 
from kivy.graphics import Color 



gamelayout = FloatLayout(size=(300, 300)) 
bglayout = FloatLayout() 
characterselectionlayout = GridLayout(cols=2) 


class Game(Screen): 

class Bg(Image): 

    def __init__(self, **kwargs): 
     super(Bg, self).__init__(**kwargs) 
     self.allow_stretch = True 
     self.size_hint = (None, None) 
     self.size = (1440, 1440) 



class Npcs(Image): 
    def __init__(self, **kwargs): 
     super(Npcs, self).__init__(**kwargs) 
     self.allow_stretch=True 



class MoveableImage(Image): 

    def __init__(self, **kwargs): 
     super(MoveableImage, self).__init__(**kwargs) 
     self._keyboard = Window.request_keyboard(None, self) 
     if not self._keyboard: 
      return 
     self._keyboard.bind(on_key_down=self.on_keyboard_down) 
     self._keyboard.bind(on_key_up=self.on_keyboard_up) 

     self.y = (Window.height/2.1) 
     self.app = App.get_running_app() 



    def on_keyboard_down(self, keyboard, keycode, text, modifiers): 
     if keycode[1] == 'left': 
      self.source = 'selectionscreen/left.zip' 
      self.anim_delay=.20 
      if self.x < (Window.width * .25): 
       bglayout.x += 4 
      else: 
       for i in listofwidgets: 
        if self.collide_widget(i): 
         self.x -=0 
        else: 
         self.x -=6 

     elif keycode[1] == 'right': 
      self.source ='selectionscreen/right.zip' 
      self.anim_delay=.20 
      if self.x > (Window.width * .70): 
       bglayout.x -= 4 
      else: 
       for i in listofwidgets: 
        if self.collide_widget(i): 
         self.x += 0 
        else: 
         self.x += 6 

     else: 
      return False 
     return True 


class gameApp(App): 
    def build(self): 
     global sm 
     sm = ScreenManager() 
     game = Game(name='game') 
     sm.add_widget(game) 
     global listofobject 
     listofobject = [] 
     hero = MoveableImage(source='selectionscreen/right1.png', size_hint=(None,None), allow_stretch = False, size=(40, 65)) 
     self.tree = Npcs(source='selectionscreen/tree.zip', allow_stretch=False, size_hint=(None,None), pos_hint={'x':.20, 'y':.30}, size=(50, 50), pos=(300, 300)) 
     self.testdude = Npcs(source='selectionscreen/testdude.png', allow_stretch=False, size_hint=(None,None), pos_hint={'x':.60, 'y':.70}, size=(100, 124), pos=(800, 900)) 
     listofwidgets.append(self.tree) 
     listofwidgets.append(self.testdude) 
     self.background=Bg(source='selectionscreen/background12.png', pos_hint={'x':0, 'y':0}) 
     bglayout.add_widget(self.background) 
     bglayout.add_widget(self.tree) 
     bglayout.add_widget(self.testdude) 
     gamelayout.add_widget(bglayout) 
     gamelayout.add_widget(hero) 
     game.add_widget(gamelayout) 

     return sm 





if __name__ == '__main__': 
    gameApp().run() 

回答

2

您遇到的問題是,如果他失敗與每個你的對象碰撞你的角色移動。所以如果你有三個物體而他沒有擊中任何物體,他會以他正常速度的三倍移動。如果他與其中一人發生碰撞,他的速度會減慢兩倍,但會繼續前進。

您需要更改您的代碼,以便在允許他移動前測試他是否與任何物品發生碰撞。在any功能內置可與此(調用它發電機表情)幫助:

if any(self.collide_widget(i) for i in listofwidgets): 
    self.x -=0 
else: 
    self.x -=6 

如果你想寫一個明確的循環,形成等價是:

for i in listofwidgets: 
    if self.collide_widget(i): 
     self.x -= 0 
     break 
else: # this block is run only if the loop ran to the end without breaking 
    self.x -= 6 
+0

這很有道理,我會給它一個鏡頭。 – david

+0

什麼是'任何'? – david

+0

'any'是一個函數構建函數,它測試其可迭代參數中的值直到找到一個「真」的值。如果是這樣,它也會返回「True」。如果它在沒有找到「真」值的情況下到達迭代器的末尾,它將返回「False」。你可以用一個明確的循環來做同樣的事情,但是當Python爲你提供它時沒有必要! – Blckknght

0

步行十字型()在這裏很方便。

for widget in gameApp.walk(self, loopback=False): 
     if type(widget) == Npcs: 

這會給你一個特定的小部件。你會考慮以某種方式重寫你的代碼是這樣的:

for widget in gameApp.walk(self, loopback=False): 
    if type(widget) == Npcs: 
     if not self.collide_widget(widget): 
      x-=6 
      break 

但這看起來南轅北轍,如果這場比賽將有很多,很多小部件。