2013-02-15 55 views
2

我不確定標題是否給出了最佳描述。但這是我的問題。 我有一個名爲'球'的課。每個球都有其自己的寬度,半徑和顏色。 我的代碼工作很好,而我在循環之前加入我自己的球 例如。 ball1 = Ball().... ball2 = Ball() 我使用的是pygame,我想要的是當我按下'Space'時它會添加另一個具有它自己特性的球。我有它,它隨機給出一個寬度,半徑和顏色。 這裏是我的代碼:在循環中添加同一類的新對象

BLACK = (0,0,0) 
WHITE = (255, 255, 255) 
BLUE = (0, 0, 255) 
RED = (255, 0, 0) 
GREEN = (0, 255, 0) 

fps = 30 

color_list = [BLACK, BLUE, GREEN, RED] 

col = None 
siz = None 
wit = None 
posx = None 
posy = None 
ball = None 


class Ball: 

    ballCount = 0 

    def __init__(self): 
     Ball.ballCount +=1 
     self.col = random.choice(color_list) 
     self.siz = random.randint(20, 80) 
     self.wit = random.randint(1, 3) 
     self.posx = random.randint(self.siz, width-self.siz) 
     self.posy = random.randint(self.siz, height-self.siz) 

    def blitball(self): 
     pygame.draw.circle(screen, self.col, (self.posx, self.posy),self.siz, self.wit) 


    def move(self): 
     self.posx+=1 



ball2 = Ball() 
ball1 = Ball() 
ball3 = Ball() 

while True: 

    amount = 0 



    event = pygame.event.poll() 
    keys = pygame.key.get_pressed() 

    if event.type == QUIT: 
     pygame.quit() 
     sys.exit() 

    if keys[K_q]: 
     pygame.quit() 
     sys.exit() 

    ############################################################# 

    if keys[K_SPACE]: 
     eval("ball"+str(Ball.ballCount+1)) = Ball() 

    ############################################################# 

    screen.fill(WHITE) 

    for r in range(Ball.ballCount): 
     amount+=1 
     eval("ball"+str(amount)).move() 
     eval("ball"+str(amount)).blitball() 


    pygame.time.wait(int(1000/fps)) 

    pygame.display.update() 

for r in range(Ball.ballCount):使用,所以我不必鍵入功能每一個球。這工作完美。如果你知道一個更簡單的方式讓我知道。

所以我需要補充的是:

if keys[K_SPACE]: 
    #add another ball, ball3, ball4,..etc. 

如果這意味着要改變我的一些代碼,請隨時告訴我,甚至這樣做自己。 感謝您提前回復。 (我有我的問題內的井號標籤)

丹尼斯

+1

你已經在使用列表,所以你應該知道它們。爲什麼不使用它們呢? – delnan 2013-02-15 18:20:08

+0

似乎更像是一個設計問題 - 你試圖讓球做兩件事 - 代表一個球對象,但也跟蹤所有其他的球對象。似乎你的設計會更簡單,如果你把它們作爲兩個單獨的問題來處理;球和球本身的清單。 – GoingTharn 2013-02-15 18:23:09

回答

3

商店列表中你的球,並作用於他們那裏

# starting three balls 
balls = [Ball(),Ball(),Ball()] 

while True: 
    amount = 0 

    event = pygame.event.poll() 
    keys = pygame.key.get_pressed() 

    if event.type == QUIT: 
     pygame.quit() 
     sys.exit() 

    if keys[K_q]: 
     pygame.quit() 
     sys.exit() 

    ############################################################# 

    if keys[K_SPACE]: 
     balls.append(Ball()) 

    ############################################################# 

    screen.fill(WHITE) 

    for ball_in_play in balls: 
     ball_in_play.move() 
     ball_in_play.blitball() 


    pygame.time.wait(int(1000/fps)) 

    pygame.display.update() 
+0

用於顯示代碼,包括爲什麼'list'使循環更好。 – abarnert 2013-02-15 18:54:09

+0

非常感謝,我從現在開始做到完美! – 2013-02-15 18:54:34

2

你幾乎要創建的名字一個新的變量。

而且,即使在極少數情況下,您幾乎從不想用evalexec來做。

而且,即使你想使用evalexec,你幾乎再也不想用默認locals/globals使用它們。

但是,讓我們看看爲什麼你的代碼不是先工作,然後再怎麼做纔好。

eval("ball"+str(Ball.ballCount+1)) = Ball() 

你生成一個字符串像"ball4",然後調用上eval。毫不奇怪,該評估的字符串爲"ball4"。然後你試圖給這個字符串分配一個新值(新構造的Ball實例),而不是一個變量,顯然這是行不通的。 (其實,我猜你會得到一個SyntaxError爲試圖分配給一個函數調用,甚至任何被評估之前)

爲了解決這個問題,你必須把整個事情裏面eval

eval("ball"+str(Ball.ballCount+1) + " = Ball()") 

但是,這不起作用,因爲eval只適用於表達式,不適用於語句。對於陳述,您需要exec

exec("ball"+str(Ball.ballCount+1) + " = Ball()") 

而且這將消除您的錯誤。

但是讓我們看看創建ball4變量的正確方法:

locals()["ball" + str(Ball.ballCount+1)] = Ball() 

簡單得多,更難得到錯誤的。

但是,一旦你看到的是,爲什麼使用locals()作爲dict時,你可以使用你想要的任何名稱的任何dict煩惱呢?

my_balls["ball" + str(Ball.ballCount+1)] = Ball() 

而且,一旦你這樣做,你不需要在每一個「球」的前綴:

my_balls[Ball.ballCount+1] = Ball() 

而在這一點上,你可能會發現你的鑰匙只是自然數,這意味着你只是用dict模擬list,所以你不妨製作my_balls a list

然後,你不再需要Ball.ballCount - 它只是len(my_balls)

那麼,使用evalexec有什麼不好?如果你的代碼難以調試(並且在交互式終端中試驗),它會打開巨大的安全漏洞(想象你向用戶詢問下一個球的號碼,然後他給了你回來「3; os.system('rm -rf /'); _」然後你試圖exec("Ball" + user_input_string + " = Ball()"))。

但所有這一切都沒有什麼是相比,它使您的代碼更難以閱讀的事實。比較:

eval("ball"+str(amount)).move() 

balls[amount].move() 
+0

非常感謝您的回答。儘管我認爲Paul Seeb展示了一種很好的方式來完成我想要做的事情,但現在我很高興現在我明白Eval和Exec好了很多,對於我未來的一些計劃,這個答案應該對我很有幫助。我選擇了Paul Seebs的答案,因爲這將是我在代碼中使用的,但是您的答案同樣有用,這是一個艱難的決定。非常感謝。 – 2013-02-15 19:02:35

相關問題