2013-02-15 52 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

相关问题