可变速度的Pygame碰撞

时间:2016-02-15 21:41:48

标签: python performance pygame collision

如果你可以帮我们解决这个问题,真的很棒。我们目前正在学校开展游戏项目,我们希望创建一个类似炸弹人的迷宫游戏。

问题如下: 炸弹的位置和速度取决于使用浮动值跟踪的鼠标,但是如果你点击很远,它会变得太高,所以它可以跳过碰撞检测,因为它有时会过快。现在,当你将炸弹与一个块的底部和其他一些碰撞对齐时,还有一些其他奇怪的错误。

方法是否碰撞错误?我们需要检查每个站点还是有更好的解决方案来解决这个问题。我们还考虑过只使用4个方向,但即使这样也没有成功。

我真的希望那里的人可以提供帮助。

class Block( pygame.sprite.Sprite):

    def __init__(self,color = SCHWARZ, width = 40, height = 40, movable = 0):

        super().__init__()

        self.width = width 
        self.height = height

        self.color = color

        self.movable = movable

        self.image = pygame.Surface((width,height))
        self.image.fill(color)

        self.properties()

    def properties(self):

        self.rect = self.image.get_rect()

        self.origin_x = self.rect.centerx
        self.origin_y = self.rect.centery

    def set_pos(self, x, y):
        self.rect.x = x
        self.rect.y = y

    def render(self,window):
        pygame.draw.rect(window,self.color,(self.rect.x,self.rect.y,self.width,self.height))

class Bomb(Block):

    def __init__(self,player, target_x, target_y,countdown,zeit,color = BLAU):

        super().__init__(color, width = 20, height = 20)
        self.target_x = round(target_x)
        self.target_y = round(target_y)

        self.countdown = countdown
        self.zeit = zeit

        self.player_x = player.rect.left + player.width/2
        self.player_y = player.rect.top + player.height/2

        self.set_pos(player.rect.center[0]-self.width/2,player.rect.center[1]-self.height/2)
        self.truepos = list(self.rect.center)

        self.setspeed(3)

    def setspeed(self,factor):

        self.speed_x = (self.target_x - self.player_x)/100
        self.speed_y = (self.target_y - self.player_y)/100




        """self.direction = [0,0]

        if self.target_x - self.player_x < 0:
            self.direction[0] = -1
        elif self.target_x - self.player_x > 0:
            self.direction[0] = 1
        if self.target_y - self.player_y > 0:
            self.direction[1] = 1
        elif self.target_y - self.player_y < 0:
            self.direction[1] = -1

        self.speed_x = self.direction[0]* factor
        self.speed_y = self.direction[1]* factor

        print(self.speed_x)
        print(self.speed_y)"""

    def move(self):

        if self.speed_x != 0:
            self.collision()
        if self.speed_y != 0:
            self.collision()

    def update(self):

        self.move()

        if self.countdown > 0:
            self.countdown -= self.zeit

        elif self.countdown <= 0:
            bomblist_list.remove(self)

    def collision(self):
        for block in block_list:
            if block.movable != 1:
                if self.rect.colliderect(block.rect):
                    self.distance = [abs(block.rect.centerx - (self.truepos[0] + self.speed_x)), abs(block.rect.centery - (self.truepos[1] + self.speed_y))]
                    if self.distance[0] > self.distance[1]:
                        if self.speed_x < 0:
                            self.rect.left = block.rect.right - self.speed_x
                        elif self.speed_x > 0:
                            self.rect.right = block.rect.left -self.speed_x
                        self.speed_x = -self.speed_x
                    elif self.distance[0] < self.distance[1]:
                        if self.speed_y < 0:
                            self.rect.top = block.rect.bottom - self.speed_y
                        elif self.speed_y > 0:
                            self.rect.bottom = block.rect.top - self.speed_y
                        self.speed_y = -self.speed_y



        self.truepos[0] += self.speed_x
        self.truepos[1] += self.speed_y
        self.rect.center = self.truepos

# -------- Main Program Loop -----------
while not done:
    clock.tick(fps)
    millisekunde = float(clock.tick(fps))
    zeit = millisekunde /500
    vergangen += zeit

    # --- Main event loop
    for event in pygame.event.get(): # User macht irgendwas

        if event.type == pygame.QUIT: # Wenn der User Quit klickt
            done = True # Verlässt die Schleife

        elif event.type == pygame.KEYDOWN:
            pass



            #if event.key == pygame.K_UP:
                #if e


        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                mx,my = pygame.mouse.get_pos()
                bomb = Bomb(player,mx,my,3,zeit)
                bomblist_list.append(bomb)
                planted = True

    keys = pygame.key.get_pressed()

    if keys[pygame.K_RIGHT]:
            player.move(speedx,0)
    if keys[pygame.K_LEFT]:
            player.move(-speedx,0)
    if keys[pygame.K_DOWN]:
            player.move(0,speedy)
    if keys[pygame.K_UP]:
            player.move(0,-speedy)

    if planted:
        for bomb in bomblist_list:
            bomb.update()

    screen.fill(SCHWARZ)

    for block in block_list:
        block.render(screen)

    if planted:
        for bomb in bomblist_list:
            bomb.render(screen)

    pygame.draw.rect(screen,red,player.rect)

    pygame.display.update()

pygame.quit()

1 个答案:

答案 0 :(得分:0)

当检查可以在一帧中传递对象的快速移动项目上的碰撞时,您要做的是将其存储在最后一帧上并将其放在当前帧上。有了它,你可以检查它是否应该与最后一帧和当前帧之间的任何东西相撞。

然后你可以通过将它放回应该停止的位置并随后绘制对象来修改它的位置。