2014-10-08 100 views
-1

我一直在寻找一个我一直以来遇到的问题的答案,说实话,这是十个月来我第一次不能找到答案。我已经看了很多问题,字典做的工作,这个结论被发现是错误的(我试图用字典(大多数的答案建议),但他们没有奏效。)唯一的其他答案我可以发现是使用exec(),但他们似乎总是伴随着一条评论说他们很危险,所以我已经摆脱了他们。使用字符串在Pygame中调用Python 3.3中的变量

在我的问题: 这是我在Pygame中一直工作在代码的例子:

import pygame,sys 
from pygame.locals import * 
pygame.init() 
screen = pygame.display.set_mode((800,230)) 
pygame.display.set_caption('Example') 
tickclock = pygame.time.Clock() 
change = 1 
car1 = pygame.image.load('Car1.png') 
car2 = pygame.image.load('Car2.png') 
while True: 
    for event in pygame.event.get(): 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 
     elif event.type == KEYDOWN: 
      if event.key == K_ESCAPE: 
       pygame.quit() 
       sys.exit() 
      elif event.key == K_SPACE:#To change the picture when the user presses space 
       change = change + 1 
    #Current way-----# 
    if change == 1: 
     screen.blit(car1,(0,0)) 
    elif change == 2: 
     screen.blit(car2,(0,0)) 
    #Continue until all pictures are used... 
    elif change > 2:#The 2 will change based on the amount of pictures. 
     change = 1 
    #----------------# 
    pygame.display.flip() 
    tickclock.tick(60) 

凡被注释为“当前道路”是我的问题是。如果有很多Pygame显示的图片,使用if/elif语句的这个消息可能会占用大量的行数,并且由于每if/elif语句后每调用一次screen.blit()都会增加一倍。

这是我想要做什么的例子:

import pygame,sys 
from pygame.locals import * 
pygame.init() 
screen = pygame.display.set_mode((800,230)) 
pygame.display.set_caption('Example') 
tickclock = pygame.time.Clock() 
varcar = 'car' 
varnum = '1' 
car1 = pygame.image.load('Car1.png') 
car2 = pygame.image.load('Car2.png') 
while True: 
    for event in pygame.event.get(): 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 
     elif event.type == KEYDOWN: 
      if event.key == K_ESCAPE: 
       pygame.quit() 
       sys.exit() 
      elif event.key == K_SPACE:#To change the picture when the user presses space 
       varnum = int(varnum) 
       varnum = varnum + 1 
       varnum = int(varnum) 
    #Using this to substitute the class I set up for the actual file--# 
    varcombined = varcar + varnum#To make varcombined = 'car1','car2',etc. 
    if varnum > 2:#To keep varnum within the loaded image numbers 
     varnum = 1 
    #-----------------------------------------------------------------# 
    #The way I wish to use--------------------------------------------# 
    #Some Code 
    screen.blit(varcombined,(0,0)) 
    pygame.display.flip() 
    tickclock.tick(60) 

我想在这里做的是结合varcar和varnumber变量,这样我可以在varcombined变量将它们结合起来,而只有改变varnumber变量。这会给出与加载图像的变量名称相同的字符串:car1和car2。然后,我想通过使用该字符串作为实际变量名的替代,在第31行的'screen.blit(varcombined,(0,0))'中以某种方式调用变量car1和car2。 (实际上并不需要动态地创建一个新的变量)

有没有办法做到这一点,如果是这样,那该怎么办?

即使这个问题看起来有点特殊,但我认为这可以让很多可能需要/希望使用字符串来调用变量的人受益。

如果有人不明白我在问什么,只是这么说,我会尝试编辑该问题来澄清。

编辑

谢谢你为他们快速的回答abarnert和费尔南多布宜诺斯艾利斯。 :)

我不确定是否应该将其作为编辑或其他问题,但由于最近的问题,我需要扩展我的问题。

我用了abarnert的答案,它像一个魅力。

car_dictionary = {1: car1 2: car2} 

#-----------# 

screen.blit(car_dictionary[change], (0,0)) 

我现在想问一下,我应该在我添加了一个“truck1”和“truck2”的形象,而现在1和2,而且汽车和卡车之间不仅需要交换的情况下做? 如果有办法做到这一点当然。

+0

当你说“我试图使用字典(大多数答案提示),但他们没有奏效”时,你究竟尝试了什么?因为这正是你想要的:一个映射“{1:car1,2:car2}”的字典。然后你可以做,例如'screen.blit(car_dictionary [change],(0.0))',不需要'if' /'else'。 (或者,更好的是,甚至不要创建单独的'car1'和'car2'变量;只需在汽车字典中首先构造汽车。) – abarnert 2014-10-08 23:22:45

+0

@abarnert - 既然你告诉我这件事,我一直在寻找列入名单和词典,他们可以做的事情真的很棒。我现在得到了代码工作。我只是以错误的方式使用字典。我明白为什么现在这个问题被标记下来。谢谢您的帮助。因为它,我是一个更好的人。 – Flutterguy135 2014-10-25 20:08:45

+0

如果你的代码能够工作,你应该编辑你的问题,使其更清楚你没有得到的东西,然后编写(并接受)解释你如何解决它的答案。(除非你认为费尔南多 - 艾利斯的答案是足够的,在这种情况下,你应该接受它,或者你认为我应该把我的评论变成一个答案。)同时,对于后续问题,你应该创建一个新问题 – abarnert 2014-10-27 18:27:45

回答

0

所以,你想要的这里是要想办法让这取决于change12car1car2。并且,理想情况下,能够将此扩展到car73而不写入73 elif陈述链。

虽然它可能通过构建变量名,然后进行查找,然后在适当的全球/本地/对象范围内(例如,vars()['car{}'.format(change)]),this is a very bad idea,为lots of reasons做到这一点。

做到这一点,正确的方法是将车存放在字典中,由varnum值键:

cars = {1: car1, 2: car2} 

,或者甚至更好,直接装载车进入字典,一个循环,和唐“T甚至创造摆在首位的独立变量(当你有73辆汽车这将变得很繁琐):

cars = {} 
for num in range(1, 3): 
    car = pygame.image.load('Car{}.png'.format(num)) 
    cars[num] = car 

或者更简单地说:

cars = {num: pygame.image.load('Car{}.png'.format(num)) for num in range(1, 3)} 

现在,用钥匙查找一辆汽车,那只是cars[change]。特别是,你的代码就变成了:

screen.blit(cars[change], (0.0)) 

值得一提的是,在现有的代码,按键并没有真正做的加载时间之后任何事情。它们只是连续的整数,你只需从第一个整数开始,一个接一个地计数,然后在第一个结束时回滚到第一个整数。如果在真实代码中这是真的,那么在这里你甚至不需要字典,只是一个列表;你需要做的唯一的变化是从0开始,而不是从1

change = 0 
cars = [pygame.image.load('Car{}.png'.format(num)) for num in range(1, 3)] 

如果你需要change的是挑车的唯一计数,可以摆脱进一步简化该change。你只是想遍历cars,永远重复。 itertools.cycle使这一个单线。取而代之的while True:,你可以这样做:

for car in itertools.cycle(cars): 

然后,而不是cars[change]你只需要使用car

0

你可以使用一个字典,正如:

car1 = pygame.image.load('Car1.png') 
car2 = pygame.image.load('Car2.png') 

... 

screen.blit({"car1": car1, "car2": car2}[varcombined], (0,0)) 

或者你甚至可以取代你的varcombinedcarNumber变量,例如 - 因此改变你的字典{1: car1, 2: car2}

希望有所帮助。