Pygame 问题 - 在同一类中生成多个精灵

1 投票
1 回答
2382 浏览
提问于 2025-04-17 03:42

不重要的开场白:

大家好,我正在用Python和Pygame做一个游戏。这主要是为了提高我的编程技能,而不是认真制作游戏。我最近因为学习Objective C暂时停了Python,但现在又回来了。这是我在短暂休息前遇到的问题,现在又回过头来想解决它。我花了不少时间研究这个问题,感觉我可能找到了答案,但就是没搞懂。抱歉代码命名不太规范/缺少注释,我会努力改进的。

问题的核心:

总之,我附上了我正在使用的四张图片。这个程序用一个简单的函数在屏幕上放置各种图块。鼠标光标是把剑。光标的整个图像就是这把剑,但我以后会改的。每当光标碰到一个图块时,我让程序在控制台输出“blue”。我的目标是让它在碰到“任何”这种颜色的图块时都能这样做。

从长远来看,我想能够修改这些图块精灵的属性。不同的游戏角色会相互互动,我需要保存每个精灵的状态。我还会为其他精灵设置互动。

现在这些精灵都在生成图像,但我碰撞的矩形只是随着每张图像的生成而移动。我想这和代码是有关系的,但我需要一种方法来处理多个精灵,每个精灵都有自己的碰撞矩形。

谢谢大家

编辑:由于新用户的限制,我无法添加图片。它们可以在这里查看。我好像看到过有人可以(并且确实会)编辑帖子。如果有能力把图片移动到这个帖子里的朋友,欢迎你们这么做。

import random,math,sys,os
import pygame
from pygame.locals import *

pygame.init() #Initializing Pygame

#Colors
black=(0,0,0)

#Screen
screen=pygame.display.set_mode((1200,800),0,0)
pygame.display.set_caption("Nero's Sandbox")
pygame.mouse.set_visible(False)
clock=pygame.time.Clock()
fps=40

#Game Functions:

def terminate():
    pygame.quit()
    sys.exit()

def numgen(x,y):
    return random.randint(x,y)

#Loop Variables
tri=2

#Groups:

allsprites = pygame.sprite.Group()
alltiles = pygame.sprite.Group()
allmice = pygame.sprite.Group()

#Mouse Classes

class Pointy(pygame.sprite.DirtySprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load('redsword.png').convert() #31x32 image
        self.image.set_colorkey(black)
        self.rect=self.image.get_rect()
        self.set=pygame.sprite.Group()
        self.add(allmice, allsprites, self.set)
        pygame.sprite.RenderPlain((self.set,allmice,allsprites))

    def update(self):
        screen.fill(black)
        alltiles.draw(screen)
        if event.type == pygame.MOUSEMOTION:
            pos = pygame.mouse.get_pos()
            self.rect.topright = pos
            self.set.draw(screen)

#Tile Sprites - only one rect is being recognized.

class Tile(pygame.sprite.Sprite):
    def __init__(self, graphic):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(graphic).convert()
        self.image = pygame.transform.scale((self.image),(50,50))
        self.rect=self.image.get_rect()
        self.add(alltiles, allsprites)
        self.set=pygame.sprite.RenderPlain((self))

    def update(self, x, y):
        pos = (x,y)
        self.rect.topleft = pos

#Micers
pointy1=Pointy()

#Game Loops

while True:  #Ensures all loops within program are constantly called when conditions are met.  
    screen.fill(black)
    while tri==2:                                   
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
        pygame.display.flip()
        x = 0
        y = 50
        w = 0
        while  x!=600:
               x=x+50
               w = w+1
               if w%2==0:
                    purpletile1=Tile('purplesquare.png')
                    purpletile1.set.update(x,y)
                    purpletile1.set.draw(screen)
               else:
                   c=numgen(1,2)
                   if c==1:
                           bluetile1=Tile('lightbluesquare.png')
                           bluetile1.set.update(x,y)
                           bluetile1.set.draw(screen)
                   if c==2:
                           redtile1=Tile('redsquare.png')
                           redtile1.set.update(x,y)
                           redtile1.set.draw(screen)
               if x>=600 and y!=450:
                    if y<450:
                        x = 0
                        y = y+50
                        w=w-1
                    if y>=450:
                       tri=3

    while tri==3:
        for event in pygame.event.get():
           if event.type == QUIT:
               terminate()
           alltiles.draw(screen)
           pointy1.set.update()
           pointy1.set.draw(screen)
           pygame.display.flip()
           clock.tick(fps)
           if pygame.sprite.collide_rect(pointy1,bluetile1):
               print('blue')

1 个回答

1

我之前也遇到过同样的问题!我做了一些调试,发现我的类的所有实例都共享了同一个pygame.Rect()的实例。

你可能想把这一行改成:

pygame.sprite.Sprite.__init__(self)

改成:

super.__init__(self)

这样,pygame.sprite.Sprite的初始化方法就会为你的图块设置属性。我可能说错了,我对Python的继承语法不是很熟悉,但我就是这么做的。

也有可能是get_rect导致所有类都使用同一个矩形,但这似乎不太可能。

希望我能帮到你,记住pygame.Rect是一个对象,所以你可能只实例化了一次。

撰写回答