如何让我的玩家在敌人的矩形物体侧面和底部发生矩形碰撞?Pygame

4
我试图让我的玩家方块和敌人方块在侧面和底部发生碰撞,使玩家方块不会穿过敌人方块,但我不知道为什么它一直把我传送到上面,一点都不起作用。可以看视频,非常感谢任何帮助。我只需要让我的方块在侧面碰撞时不要穿过或向上移动。
我的碰撞部分:

    playerman.isJump = False
    collide = False
    for platform in platforms:
        if playerman.rect.colliderect(platform.rect):
            collide = True
            playerman.isJump = False
            playerman.y = platform.rect.top - playerman.height + 1
            if playerman.rect.right > platform.rect.left and playerman.rect.left < platform.rect.left - playerman.width:
                playerman.x = platform.rect.left - playerman.width
            if playerman.rect.left < platform.rect.right and playerman.rect.right > platform.rect.right + playerman.width:
                playerman.x = platform.rect.right



没有图片,只有方块可以用来测试代码

import pygame,random

window = pygame.display.set_mode((800,800), pygame.NOFRAME)

# player factory
class player:
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.color = color
        self.speed = 4
        self.fall = 0
        self.isJump = False
        self.jumpCount = 10
        self.rect = pygame.Rect(x,y,height,width)
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect)

# player factory
class platform:
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.color = color
        self.rect = pygame.Rect(x,y,height,width)
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect)


white = (255,255,255)
platform1 = platform(590,590,60,60,white)

platforms = [platform1]

# make the player
pink = (205,105,205)
playerman = player(300,300,60,60,pink)



# the game fps
clock = pygame.time.Clock()
FPS = 30

def keyevents():
    if keys[pygame.K_w]:
        playerman.y -= playerman.speed

    if keys[pygame.K_s]:
        playerman.y += playerman.speed

    if keys[pygame.K_d]:
        playerman.x += playerman.speed

    if keys[pygame.K_a]:
        playerman.x -= playerman.speed

    if keys[pygame.K_SPACE]:
        playerman.isJump = True



                
def jump():
    if playerman.isJump:
        if playerman.jumpCount >= -10:
            neg = 1
            if playerman.jumpCount < 0:
                neg = -1
            playerman.y -= playerman.jumpCount**2 * 0.5 * neg
            playerman.jumpCount -= 1
        else:
            playerman.isJump = False
            playerman.jumpCount = 10

    collide = False        # this makes the player fall down up to 
         # move the player
    if not playerman.isJump:
        playerman.y += playerman.fall
        playerman.fall += 1
        playerman.isJump = False
                    
        if playerman.rect.bottom >= 680:
            collide = True
            playerman.isJump = False
            playerman.JumpCount = 10
            playerman.y = 680 - playerman.height

        if collide:
            if keys[pygame.K_SPACE]:
                playerman.isJump = True
            playerman.fall = 0




# redraw the window
def redraw():
    playerman.draw()
    platform.draw()
# main loop
runninggame = True
while runninggame:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runningggame = False

    # key event
    keys = pygame.key.get_pressed()

    # this is the key events
    keyevents()

    jump() # JUMP AND COLLISION on the grawn

    playerman.isJump = False
    collide = False
    for platform in platforms:
        if playerman.rect.colliderect(platform.rect):
            collide = True
            playerman.isJump = False
            playerman.y = platform.rect.top - playerman.height + 1
            if playerman.rect.right > platform.rect.left and playerman.rect.left < platform.rect.left - playerman.width:
                playerman.x = platform.rect.left - playerman.width
            if playerman.rect.left < platform.rect.right and playerman.rect.right > platform.rect.right + playerman.width:
                playerman.x = platform.rect.right





    window.fill((0,0,0))
    redraw()
    pygame.display.update()
pygame.quit()

我只是想要一个基础的碰撞检测,即当我的敌人矩形的左、右和底部被触碰时它不会穿过去,而如果我从上面碰撞,则可以让我的玩家站在上面。

2个回答

1
为了使碰撞后的速度相同,您应该执行 self.speed = -self.speed,但您还可以添加自定义数量到速度中,以使速度更快,并减去更多以在碰撞后获得更快的速度。(这增加了更多的速度定制)

你能给我一个例子吗?我有点困惑。 - Habib Ismail
1
所以在上面的例子中,您使用了self。因此,要以向量形式获取对象的速度,您将想要使用self.speed,但是当您撞到它时,您希望创建碰撞,因此当您注册碰撞时,您希望将方向和速度设置为相反的方向,因此-self.speed将使其反转,因为它是负数。然后,您需要将其设置为self.speed以改变速度和方向。 - Leo Gaunt
@HabibIsmail 这有帮助吗? - Leo Gaunt
1
我会做出的改变是:如果playerman.rect.right > platform.rect.left并且playerman.rect.left < platform.rect.left - playerman.width:playerman.speed = -playerman.speed如果playerman.rect.left < platform.rect.right并且playerman.rect.right > platform.rect.right + playerman.width:playerman.speed = -playerman.speed - Leo Gaunt

1
我终于成功地制作出了解决方案!这里是一些代码,可以让一切正常工作。如果您愿意,我可以在聊天中向您描述我所做的更改以及它们的作用。请注意,我是用Python 3编程的,因此您可能需要进行一些更改才能使其在Python 2中工作。
import pygame,random

window = pygame.display.set_mode((800,800), pygame.NOFRAME)

# player factory
class player:
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.moveleft = True
        self.moveright = True
        self.color = color
        self.speed = 4
        self.fall = 0
        self.isJump = False
        self.jumpCount = 10
        self.rect = pygame.Rect(x,y,height,width)
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect)

# player factory
class platform:
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.color = color
        self.rect = pygame.Rect(x,y,height,width)
    def draw(self):
        self.rect.topleft = (self.x,self.y)
        pygame.draw.rect(window,self.color,self.rect)


white = (255,255,255)
platform1 = platform(590,590,60,60,white)

platforms = [platform1]

# make the player
pink = (205,105,205)
playerman = player(300,300,60,60,pink)



# the game fps
clock = pygame.time.Clock()
FPS = 30

def keyevents():
    if keys[pygame.K_w]:
        playerman.y -= playerman.speed

    if keys[pygame.K_s]:
        playerman.y += playerman.speed

    if keys[pygame.K_d]:
        if playerman.moveright:
            playerman.x += playerman.speed    

    if keys[pygame.K_a]:
        if playerman.moveleft:
            playerman.x -= playerman.speed

    if keys[pygame.K_SPACE]:
        playerman.isJump = True



                
def jump():
    if playerman.isJump:
        if playerman.jumpCount >= -10:
            neg = 1
            if playerman.jumpCount < 0:
                neg = -1
            playerman.y -= playerman.jumpCount**2 * 0.5 * neg
            playerman.jumpCount -= 1
        else:
            playerman.isJump = False
            playerman.jumpCount = 10

    collide = False        # this makes the player fall down up to 
         # move the player
    if not playerman.isJump:
        playerman.y += playerman.fall
        playerman.fall += 1
        playerman.isJump = False
                    
        if playerman.rect.bottom >= 680:
            collide = True
            playerman.isJump = False
            playerman.JumpCount = 10
            playerman.y = 680 - playerman.height

        if collide:
            if keys[pygame.K_SPACE]:
                playerman.isJump = True
            playerman.fall = 0




# redraw the window
def redraw():
    playerman.draw()
    platform.draw()
# main loop
runninggame = True
while runninggame:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runningggame = False

    # key event
    keys = pygame.key.get_pressed()

    # this is the key events
    keyevents()

    jump() # JUMP AND COLLISION on the grawn

    playerman.isJump = False
    collide = False
    for platform in platforms:
        if playerman.rect.colliderect(platform.rect):
            collide = True
            playerman.isJump = False
            if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom) or
                platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom)):
                playerman.y = platform.rect.top - playerman.height + 1
                playerman.moveright = True
                playerman.moveleft = True
            
            if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.top) or
                platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom - 10)):
                playerman.moveright = False
            elif (platform.rect.collidepoint(playerman.rect.left, playerman.rect.top) or
                  platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom - 10)):
                playerman.moveleft = False
        else:
            playerman.moveright = True
            playerman.moveleft = True
                
                

    window.fill((0,0,0))
    redraw()
    pygame.display.update()
pygame.quit()

我刚刚编辑了我的回答,包括了一个示例。 - M-Chen-3
我已经尝试过你的示例,但它仍然以相同的方式反应,将我传送到顶部。 - Habib Ismail
最后4行代码根本没有被调用。请优化条件。 - M-Chen-3
让我们在聊天中继续这个讨论 - Habib Ismail
我已经找到了解决方案!!请查看我的更新答案。 - M-Chen-3
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接