如何为多个精灵组创建随机位置?

2 投票
3 回答
1848 浏览
提问于 2025-04-16 13:02

我尝试过用for循环配合blit和draw方法,并且为“PlayerSprite”和“Treegroup”使用了不同的变量。

for PlayerSprite in Treegroup:
    surface.blit(PlayerSprite,(random.randrange(100,500),random.randrange(100,600)))

我还尝试过

 SPRITES=[]
 for Sprites in range(10):
     Sprites= PlayerSprite
     SPRITES.append(Sprites)

但我得到的都是错误信息。

screen=pygame.display.set_mode((640,480))
background1=pygame.image.load("C:\Pygame-Docs\examples\data\Random Map.bmp")


class Tree1(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load('C:\Pygame-Docs\examples\data\Tree 1.bmp')
        self.image=self.image.convert()
        self.rect=self.image.get_rect()
        self.rect.centerx=random.randrange(10,100)
        self.rect.centery=random.randrange(10,100)

# Makes a group of trees 
Howmanytrees=random.randrange(5,10)
Trees=[]        
for tree in range(Howmanytrees):            
trees=Tree1()
Trees.append(trees)

# Howmany groups 
for Treegroup in range(10):
    Treegroup=Trees

# Places groups

PlayerSprite=pygame.sprite.Group(Treegroup)

# keeps loop ( game ) going until canceled
keepgoing=True
while keepgoing:

   for event in pygame.event.get():
      if event.type==pygame.QUIT:
         keepgoing=False

# actually draws screen
screen.blit(background1,(0,0))
PlayerSprite.draw(screen)
pygame.display.flip()

这段代码只显示了5到10棵树“Trees=[]”,其他的什么都没有。我已经为这个问题努力了一个多星期,读了很多教程,浏览了许多网站,但似乎都没有用。我一定是忽略了什么或者漏掉了什么。我本以为这会很简单!

非常感谢!

3 个回答

0

这对我来说真的没什么意义。

for tree in range(Howmanytrees):            
trees=Tree1()
Trees.append(trees)

你这里的循环根本没有做任何事情。tree应该是一个在0到Howmanytrees之间的数字。再说,下面的代码块没有缩进,所以它不属于这个循环。即便如此,这个代码块也不会工作。而且,你用的变量名让自己和我们都搞混了。Trees是对象吗?trees是列表吗?别这样,真的。

我完全不知道下面的代码在干嘛。

# Howmany groups 
for Treegroup in range(10):
    Treegroup=Trees

创建你的SpriteGroup时传入前面提到的trees列表?还是我漏掉了什么 :) TreeGroup = Trees 10次只会执行10次。你并没有使用循环变量。循环中唯一会变化的东西。即便如此,这整段代码都是没用的。

while keepgoing:

   for event in pygame.event.get():
      if event.type==pygame.QUIT:
         keepgoing=False

这会导致一个漂亮的无限循环。它一直在评估keepgoing变量。除非用户退出,否则这个变量永远不会被设置为false,而且它也不会在屏幕上显示任何东西。删掉这个。用这个代替:

for event in pygame.event.get():
    if event.type == QUIT:
        return

这样就不会造成无限循环,因为每次处理的事件数量是有限的。然后程序会循环回去,进行处理、更新、渲染和获取输入。

1

我会使用 randintmove_ip 来实现你想要的效果。下面是我自己游戏中的一段代码,效果也一样:

self.rect.move_ip(random.randint(minX, maxX), random.randint(minY, maxY))

这四个变量 minX、maxX、minY 和 maxY 形成了一个矩形,精灵可以放在这个矩形内。在你的情况下,树木会分布在整个屏幕上,但最大 X 和 Y 的范围会减少,这样树木就不会穿过屏幕底部了。

另外,建议使用 Group 类来存储你的树,而不是用列表。因为列表会限制树木的生成数量,而 Group 则不会。你可以这样调用它:

Treegroup = pygame.sprite.Group

然后要把一个精灵添加到这个组里,可以这样做:

Treegroup.add(Tree1(screen))

确保这个类的初始化方法里有屏幕参数,像这样:

def __init__(self, screen)

完成这些后,你的代码应该看起来像这样:

for Treegroup in range(10):
    Treegroup.add(Tree(screen))
[...]
class Tree(pygame.sprite.Sprite):
    def __init__(self, screen):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image('tree.png', -1)
        self.rect.move_ip(random.randint(0, 800), random.randint(0, 600))
        self.area = screen.get_rect()
1

根据我对你想要实现的理解,下面的代码应该能帮到你。我尽量把Python的语法写得非常简单,因为你看起来是个新手(对于有经验的程序员来说:是的,我下面写的代码很糟糕,但我相信提问者能理解,并且这可能会有所帮助)。

关键是,如果你想得到多个树的组,你必须在一个循环里面再放一个循环。内层循环负责把树放进组里,外层循环则负责放多个组。当然,你可以(而且应该)把内层循环隐藏在某个函数或类里面。

# Howmany groups ? say 3 
trees_groups = []
number_of_groups = 3
for _ in range(number_of_groups):
    # Choose a base position for my group of trees
    base_x = random.randrange(0,530)
    base_y = random.randrange(0,370)
    # Makes a group of trees 
    trees=[]
    number_of_trees = random.randrange(5,10)
    for _ in range(number_of_trees):
        one_tree = Tree1()
        trees.append(one_tree)
    for tree in trees:
        tree.rect.centerx += base_x
        tree.rect.centery += base_y
        trees_groups.append(tree)


# Places groups
PlayerSprite=pygame.sprite.Group(trees_groups)

一些后记

  • 正如其他人所说的,你不应该使用大写的变量名。Python的习惯是把大写的变量名留给类使用。
  • 另外,使用range循环而不使用基础变量是个坏习惯。我用下划线作为循环变量的名字来强调这一点,因为它没有被使用。

撰写回答