Sprite与对象功能碰撞?

时间:2014-12-18 15:21:38

标签: python pygame sprite collision

如果Sprite(Rocket)与astroid对象发生冲突,是否可以创建一个显示消息的函数?

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

3 个答案:

答案 0 :(得分:0)

虽然我不编写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. 随着游戏的进行,请确保在每个对象中更新位置变量。

  5. 这意味着基本上你有你的游戏对象列表,然后你遍历这些游戏框架并检查它们是否相互接触。

    或者就纯数学而言,使用距离公式(link)来获取两个项目之间的距离,然后检查它们的组合半径是否大于此距离。如果是他们正在接触。

答案 1 :(得分:0)

您可以在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] );

请记住,这个过程有些昂贵,它会检查每个小行星是否发生碰撞。如果有大量的小行星,它会慢慢运行。

答案 2 :(得分:0)

是的,可以获得分数。我知道你知道精灵碰撞功能: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行是不言自明的 - 它是您将在屏幕上看到的值(只是后面的内容) =标志和/或parantheses)。第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变量控制blits:

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),最后一个blit行将在屏幕上列出的位置(variable_pos)上显示消息。你可以使用make一些代码使crashed回到0.记住做pygame.display.flip()或者会发生奇怪的事情。我希望这个答案可以帮到你!