微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何检测碰撞?小游戏

如何解决如何检测碰撞?小游戏

我正在创建平台游戏,有红色方块(他们应该杀了我)和白色方块(平台) 当我死了,我应该在当前关卡开始时复活。 我做了碰撞检测,但只有在我移动时才有效(当我跳到红色方块并且我没有按任何东西时,它不起作用)

所以我真的很想知道如何更好地处理碰撞。

谢谢 代码

from pygame import *

WIN_WIDTH = 1923
WIN_HEIGHT = 1000

disPLAY = (WIN_WIDTH,WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30

pygame.init()

green = (0,255,0)


screen = pygame.display.set_mode(disPLAY,FLAGS,DEPTH)

font = pygame.font.SysFont('Consolas',30)
text = font.render('Your score: ',True,(0,0))
textRect = text.get_rect()
textRect.center = (40,55)

level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP","P                                                          P","P                        PP                                P","P                                 PP                       P","P             PP                                           P","P                     PP                                   P","P                                                   P      P","P                            PP                     P      P","P                    PP                             P      P","P           PP                                      P      P","P                      PPP                          P     PP","P                                                   P     LP","PSSSSSSSSSSSSSSSSSSSSsspPPSSSSSSSSSSSSSSSSSSSSSSSSsspsspPPPPPP","EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",]



def main():
    pygame.display.set_caption("Use W,A,S,D and Space to move!")
    timer = pygame.time.Clock()

    up = down = left = right = running = left_dash = right_dash = dashing = False
    bg = Surface((3200,32))
    bg.convert()
    bg.fill(Color("#000000"))
    entities = pygame.sprite.Group()
    platforms = []
    killing_entities = []
    another_level = []
    blockade = []
    player = Player(767,900)


    x = y = 0


    global level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x,y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = Block(x,y)
                platforms.append(e)
                entities.add(e)
            if col == "S":
                s = Spike(x,y)
                killing_entities.append(s)
                entities.add(s)
            if col == "L":
                l = Another_Level(x,y)
                another_level.append(l)
                entities.add(l)

            x += 32
        y += 32
        x = 0

    entities.add(player)
    running = True
    while running:
        screen.blit(text,textRect)

        timer.tick(65)

        for e in pygame.event.get():
            if e.type == KEYDOWN and e.key == K_SPACE:
                up = True
            if e.type == KEYDOWN and e.key == K_s:
                down = True
            if e.type == KEYDOWN and e.key == K_a:
                left = True
            if e.type == KEYDOWN and e.key == K_d:
                right = True
            if e.type == KEYDOWN and e.key == K_q:
                running = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left_dash = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right_dash = True                

            if e.type == KEYUP and e.key == K_SPACE:
                up = False
            if e.type == KEYUP and e.key == K_s:
                down = False
            if e.type == KEYUP and e.key == K_d:
                right = False
            if e.type == KEYUP and e.key == K_a:
                left = False
            if e.type == KEYUP and e.key == K_d:
                right = False

            if pygame.sprite.spritecollideany(player,killing_entities):
                main()

            if pygame.sprite.spritecollideany(player,another_level):
                level = [
    "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP","PPS                                                        P","PEE                                                        P","PSS                                                        P","PP                                                         P","P         P                                                P","PSSSSSSSSSSSSSSSSSSSSsspPPSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSsspPPP","EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",]
                main()

        for y in range(32):
            for x in range(32):
                screen.blit(bg,(x * 32,y * 32))

        player.update(up,down,left,right,left_dash,right_dash,running,dashing,platforms)
        entities.draw(screen)
        
        pygame.display.flip()
        pygame.display.update()

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Player(Entity):
    def __init__(self,x,y):
        Entity.__init__(self)
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = Surface((32,32))
        self.image.fill(Color("#0000FF"))
        self.image.convert()
        self.rect = Rect(x,y,32,32)

    def update(self,up,platforms):
        if up:
            if self.onGround: self.yvel -= 9
        if down:
            pass
        if running:
            self.xvel = 12

        if left_dash:
            self.rect.move_ip(-20,-2)
            left_dash = False
        
        if right_dash:
            self.rect.move_ip(20,-2)
            right_dash = False

        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:
            self.yvel += 0.25
            if self.yvel > 100: self.yvel = 100
        if not(left or right):
            self.xvel = 0        
        self.rect.left += self.xvel
        self.collide(self.xvel,platforms)
        self.rect.top += self.yvel
        self.onGround = False
        self.collide(0,self.yvel,platforms)

    def collide(self,xvel,yvel,platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self,p):
                if isinstance(p,Block):
                    pygame.event.post(pygame.event.Event(QUIT))
                if xvel > 0:
                    self.rect.right = p.rect.left
                if xvel < 0:
                    self.rect.left = p.rect.right
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = 0
                if yvel < 0:
                    self.rect.top = p.rect.bottom
                    self.onGround = False
    

class Platform(Entity):
    def __init__(self,y):
        Entity.__init__(self)
        self.image = Surface((32,32))
        self.image.convert()
        self.image.fill(Color("#ddddDF"))
        self.rect = Rect(x,32)

    def update(self):
        pass

class Block(Platform):
    def __init__(self,y):
        Platform.__init__(self,y)
        self.image.fill(Color("#000000"))

class Spike(pygame.sprite.Sprite):
    def __init__(self,y)
        self.image = Surface((33,33))
        self.image.convert()
        self.image.fill(Color("#E70018"))
        self.rect = Rect(x,33,33)

class Another_Level(pygame.sprite.Sprite):
    def __init__(self,33))
        self.image.convert()
        self.image.fill(Color("#8C563E"))
        self.rect = Rect(x,33)
        
        
if __name__ == "__main__":
    main()```

解决方法

您检查每个帧中每个事件与 killing_entities 列表的冲突。因此,如果事件队列中当前没有事件,则行:

if pygame.sprite.spritecollideany(player,killing_entities):
    main()

永远不会被执行。我猜您只希望在主循环中使用该代码,而不是在事件处理循环中。

您的代码中还有一些奇怪的地方,例如

  • 您不处理 QUIT event,因此无法关闭游戏窗口。

  • 您使用相同的变量 running 作为主循环的条件并更改播放器的 xvel

  • 也无需两次更新显示(只需使用 pygame.display.flip())。

  • 您正在将一个巨大的 (3200x32px) Surface 每帧 1024 次传送到屏幕上。如果您想用黑色填充屏幕,只需每帧调用一次 screen.fill('black')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。