精灵与对象功能碰撞



我是否可以创建一个函数,如果精灵(火箭(与星体物体碰撞,它会显示一条消息?

class Rocket(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.rect=self.image.get_rect()
        self.image=Rocket.image
        self.firecountdown = 0
    def setup(self):
        self.rect.x=700
        self.rect.y=random.randint(20,380)
    def updateposition(self):
        self.rect.x=self.rect.x-1
        time.sleep(0.005)
        if self.rect.x == 0 :
            self.rect.x = 700 + random.randint(0, 100)
            self.rect.y=random.randint(20,380)

asteroids=[]
asteroidsize=[]
for i in range(25):
        x=random.randrange(700,10000)
        y=random.randrange(0,400)
        asteroids.append([x,y])
        asteroids[i]=Asteroid()
for i in range(25):
        asteroidsize.append(random.randint(6,15))

while True:
        for i in range(len(asteroids)):

        pygame.draw.circle(screen,GREY,asteroids[i],asteroidsize[i])

        asteroids[i][0]-=2

        if asteroids[i][0]<0:
            y=random.randrange(0,400)
            asteroids[i][1]=y
            x=random.randrange(700,720)
            asteroids[i][0]=x

您可以在 Rocket 类上编写一个检查冲突的函数。由于小行星是圆的,你需要检查圆上离精灵矩形中心最近的点是否在矩形的范围内:

def check_asteroid_collision( self, asteroid, size ) :
    # Create a vector based on the distance between the two points
    distx   = self.rect.centerx - asteroid[0];
    disty   = self.rect.centery - asteroid[1];
    # Get magnitude (sqrt of x^2 + y^2)
    distmag = ((distx * distx) + (disty * disty)) ** 0.5;
    # Get the closest point on the circle:
    # Circle center + normalized vector * radius
    clsx    = asteroid[0] + distx / distmag * size;
    clsy    = asteroid[1] + disty / distmag * size;
    # Check if it's within our rect
    if self.rect.collidepoint( clsx, clsy ) :
        # We're colliding!! Do whatever
        print( "Oh no!" );

然后在游戏循环中,您可以通过调用以下命令来检查碰撞:

while True:
    for i in range(len(asteroids)):
        ...
        # Collision checking
        myrocket.check_asteroid_collision( asteroids[i], asteroidsize[i] );

请记住,这个过程有点昂贵,它会检查每颗小行星是否相撞。如果有大量的小行星,它会运行缓慢。

虽然我不编写python代码,但我可以给你一个简单的例子,说明如何完成这样的事情。

    使所有游戏
  1. 对象继承自常规游戏物品类,这样您就可以知道所有物品都有一个位置和一个碰撞半径。

    class: int positionX int positionY int radius

  2. 然后将所有项目保留在游戏对象的全局列表中。

  3. 循环浏览您的游戏列表,看看是否有任何两个项目发生冲突

    foreach object1 in gameObjectsList: foreach object2 in gameObjectsList: if(object1 != object2) if(math.sqrt(object1.positionX - object2.positionX)**2 + (object1.positionY - object2.positionY)**2) <= object1.radius + object2.radius. //Things are colliding

  4. 随着游戏的进行,请确保保持每个对象中的位置变量更新。

这基本上意味着你有你的游戏对象列表,你遍历每个游戏帧,并检查它们是否有任何相互接触。

或者用纯数学的方式,使用距离公式(link(得到两个项目之间的距离,然后检查它们的总半径是否大于这个距离。如果是他们正在触摸。

是的,得分是可能的。我假设你知道精灵碰撞功能:pygame.sprite.spritecollide()。如果您不这样做,请查看 PyGame 文档。或者谷歌一下。但这是你如何做到的。第一。在代码开头的pygame,init()行之后添加以下代码行:

variable = 0
variable_font = pygame.font.Font(None, 50)
variable_surf = variable_font.render(str(variable), 1, (0, 0, 0))
variable_pos = [10, 10]

显然,variable可以是字符串,只需删除第 3 行中的str()即可。第 1 行是不言自明的 - 它是您将在屏幕上看到的值(只是=符号和/或参数之后的内容(。第 2 行决定您希望邮件采用的字体和大小。如果选择 None and 50 ,则表示您希望消息采用正常字体和大小为 50。第三行在屏幕上呈现或粘贴消息包含字符串/数字的变量的名称、数字 1(我不知道为什么(以及消息的颜色。如果变量包含数字,请在其周围加上一个str()。最后一行将是消息的位置。但是你需要先把它弄得更厉害。要防止消息永远出现在屏幕上,请创建一个变量:

crashed = 0

然后使您的实例和组:

ship = Rocket(None)
asteroids = pygame.sprite.Group() #This is recommended, try making a class for the asteroids

最后是您的碰撞代码:

if pygame.sprite.spritecollide(Rocket, asteroids, True):
    crashed = 1

您可以使用 crashed 变量控制比特:

if crashed == 0:
    screen.blit(ship.image, ship.rect)
elif crashed == 1:
    screen.blit(ship.image, ship.rect)
    screen.blit(variable_surf, variable_pos)

当您的飞船坠毁时(碰撞代码中crashed = 1(,最后一行将在屏幕上列出的位置(variable_pos(闪亮您的信息。您可以使用创建一些代码来使crashed恢复为 0。记住要做pygame.display.flip()否则会发生奇怪的事情。希望这个答案对你有所帮助!

最新更新