代码之家  ›  专栏  ›  技术社区  ›  crazicrafter1

Pygame列表冲突

  •  0
  • crazicrafter1  · 技术社区  · 7 年前

    我在python中创建了一个地图,使用pygame和一个玩家和墙:

    import pygame
    
    
    x = 25
    y = 19
    
    collision = [
        [0,0,0,37],#vertical
        [4,23,4,27],
        [12,18,12,25],
        [13,0,13,1],
        [13,4,13,7],
        [13,10,13,11],
        [15,13,15,18],
        [15,23,15,37],
        [19,0,19,13],
        [29,25,29,26],
        [29,29,29,37],
        [35,0,35,9],
        [35,12,35,17],
        [35,21,35,26],
        [35,29,35,37],
        [36,17,36,21],
        [44,0,44,6],
        [44,10,44,17],
        [54,0,54,17],
        [0,0,19,0],#horizontal
        [35,0,46,0],
        [52,0,54,0],
        [13,5,19,5],
        [19,6,24,6],
        [30,6,35,6],
        [0,13,10,13],
        [15,13,21,13],
        [25,13,44,13],
        [35,17,36,17],
        [44,17,54,17],
        [35,21,36,21],
        [4,23,12,23],
        [0,25,4,25],
        [19,25,36,25],
        [4,27,12,27],
        [0,37,35,37],
        [14,12,14,12],#dots
        [11,14,11,14]
    ]
    
    white = (255,255,255)
    black = (0,0,0)
    red = (255,0,0)
    
    pygame.init()
    
    screen = pygame.display.set_mode((200,200))
    pygame.display.set_caption('Collision')
    screen.fill(white)
    
    for list in collision:#draw map
        pygame.draw.line(screen,black,(list[0],list[1]),(list[2],list[3]),1)
    
    pygame.draw.line(screen,red,(x,y),(x,y),1)#draw player
    
    pygame.display.update()
    
    while(True):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
    
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    for list in collision:
                        #---START OF EQUATION---#
                        if(list[0]<=list[2] and not(y-1==list[1] and x>=list[0] and x<=list[2])) or (list[0]>list[2] and not(y-1==list[1] and x>=list[2] and x<=list[0])):#updated
                        #---END OF EQUATION---#
                            pygame.draw.line(screen,white,(x,y),(x,y),1)
                            y-=1
                            pygame.draw.line(screen,red,(x,y),(x,y),1)
                            break
                elif event.key == pygame.K_s:
                    for list in collision:
                        if(list[0]<=list[2] and not(y+1==list[1] and x>=list[0] and x<=list[2])) or (list[0]>list[2] and not(y+1==list[1] and x>=list[2] and x<=list[0])):#updated
                            pygame.draw.line(screen,white,(x,y),(x,y),1)
                            y+=1
                            pygame.draw.line(screen,red,(x,y),(x,y),1)
                            break
                elif event.key == pygame.K_a:
                    for list in collision:
                        if(list[1]<=list[3] and not(x-1==list[0] and y>=list[1] and y<=list[3])) or (list[1]>list[3] and not(x-1==list[0] and y>=list[3] and y<=list[1])):#updated
                            pygame.draw.line(screen,white,(x,y),(x,y),1)
                            x-=1
                            pygame.draw.line(screen,red,(x,y),(x,y),1)
                            break
                elif event.key == pygame.K_d:
                    for list in collision:
                        if(list[1]<=list[3] and not(x+1==list[0] and y>=list[1] and y<=list[3])) or (list[1]>list[3] and not(x+1==list[0] and y>=list[3] and y<=list[1])):#updated
                            pygame.draw.line(screen,white,(x,y),(x,y),1)
                            x+=1
                            pygame.draw.line(screen,red,(x,y),(x,y),1)
                            break
                pygame.display.update()
    

    方程式采用“更容易”的格式:

    if (
        list[0]<=list[2]
        and not(
    
            y-1==list[1]
            and
    
            x>=list[0]
            and
            x<=list[2])
    
        )
    
        or
    
        (
    
        list[0]>list[2]
        and not(
    
            y-1==list[1]
            and
    
            x>=list[2]
            and
            x<=list[0]
    
            )
    
        )
    

    向下检测到按键的地方就是im出现问题的地方。我已经多次测试过这个方法,但它总是导致错误的功能。

    每次用户按w/a/s/d时,我都会让我的代码循环遍历“墙”列表,并测试如果没有墙,他们是否能够穿过该空间。假设有一堵这样的墙 here 以红点为玩家。我怎样才能防止玩家通过修改方程式向上或向左移动?

    用于测试碰撞的方程式(每个方向都不同,在这种情况下是向上的):

    if(list[0]<=list[2] and not(y-1==list[1] and x>=list[0] and x<=list[2])) or (list[0]>list[2] and not(y-1==list[1] and x>=list[2] and x<=list[0]))
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   furas    7 年前

    问题是因为它检查了第一面墙,它可能并没有碰撞,然后它会移动,但它并没有检查其他可以碰撞的墙。

    在移动玩家之前,你必须检查所有的墙。

    所有的动作几乎都是一样的-你只使用不同的 x , y 检查新位置-所以我创建了一个函数来检查它。

    def check_collisions(walls, player_new_x, player_new_y):
    
        for x1, y1, x2, y2 in walls:
            if x1 <= player_new_x <= x2 and y1 <= player_new_y <= y2:
                print("COLLIDE")
                return True
    
        return False
    

    完整代码

    import pygame
    
    # --- constants --- (UPPER_CASE_NAMES)
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED   = (255, 0, 0)
    
    FPS = 5
    
    # --- functions --- (lower_case_names)
    
    def check_collisions(walls, player_new_x, player_new_y):
    
        for x1, y1, x2, y2 in walls:
            if x1 <= player_new_x <= x2 and y1 <= player_new_y <= y2:
                print("COLLIDE")
                return True
    
        return False
    
    # --- main ---
    
    collision = [
        [0,0,0,37],#vertical
        [4,23,4,27],
        [12,18,12,25],
        [13,0,13,1],
        [13,4,13,7],
        [13,10,13,11],
        [15,13,15,18],
        [15,23,15,37],
        [19,0,19,13],
        [29,25,29,26],
        [29,29,29,37],
        [35,0,35,9],
        [35,12,35,17],
        [35,21,35,26],
        [35,29,35,37],
        [36,17,36,21],
        [44,0,44,6],
        [44,10,44,17],
        [54,0,54,17],
        [0,0,19,0],#horizontal
        [35,0,46,0],
        [52,0,54,0],
        [13,5,19,5],
        [19,6,24,6],
        [30,6,35,6],
        [0,13,10,13],
        [15,13,21,13],
        [25,13,44,13],
        [35,17,36,17],
        [44,17,54,17],
        [35,21,36,21],
        [4,23,12,23],
        [0,25,4,25],
        [19,25,36,25],
        [4,27,12,27],
        [0,37,35,37],
        [14,12,14,12],#dots
        [11,14,11,14]
    ]
    
    x = 25
    y = 19
    
    
    # - init -
    
    pygame.init()
    
    screen = pygame.display.set_mode((200,200))
    screen.fill(WHITE)
    
    # - draws -
    
    for item in collision:
        pygame.draw.line(screen, BLACK, item[:2], item[2:], 1)
    
    pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
    pygame.display.update()
    
    # - mainloop -
    
    clock = pygame.time.Clock()
    
    while True:
    
        moved = False
    
        # - events -
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
    
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    new_x = x
                    new_y = y - 1
    
                    collide = check_collisions(collision, new_x, new_y)
    
                    if not collide:
                        pygame.draw.line(screen, WHITE, (x, y), (x, y), 1)
                        x = new_x
                        y = new_y
                        pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
                elif event.key == pygame.K_s:
                    new_x = x
                    new_y = y + 1
    
                    collide = check_collisions(collision, new_x, new_y)
    
                    if not collide:
                        pygame.draw.line(screen, WHITE, (x, y), (x, y), 1)
                        x = new_x
                        y = new_y
                        pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
                elif event.key == pygame.K_a:
                    new_x = x - 1
                    new_y = y
    
                    collide = check_collisions(collision, new_x, new_y)
    
                    if not collide:
                        pygame.draw.line(screen, WHITE, (x, y), (x, y), 1)
                        x = new_x
                        y = new_y
                        pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
                elif event.key == pygame.K_d:
                    new_x = x + 1
                    new_y = y
    
                    collide = check_collisions(collision, new_x, new_y)
    
                    if not collide:
                        pygame.draw.line(screen, WHITE, (x, y), (x, y), 1)
                        x = new_x
                        y = new_y
                        pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
        pygame.display.update()
        clock.tick(FPS) # to display less frame and use less CPU
    

    编辑: 您可以按住按键并移动的版本-无需多次按键

    import pygame
    
    # --- constants --- (UPPER_CASE_NAMES)
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    RED   = (255, 0, 0)
    
    FPS = 5
    
    # --- functions --- (lower_case_names)
    
    def check_collisions(walls, player_new_x, player_new_y):
    
        for x1, y1, x2, y2 in walls:
            if x1 <= player_new_x <= x2 and y1 <= player_new_y <= y2:
                print("COLLIDE")
                return True
    
        return False
    
    # --- main ---
    
    collision = [
        [0,0,0,37],#vertical
        [4,23,4,27],
        [12,18,12,25],
        [13,0,13,1],
        [13,4,13,7],
        [13,10,13,11],
        [15,13,15,18],
        [15,23,15,37],
        [19,0,19,13],
        [29,25,29,26],
        [29,29,29,37],
        [35,0,35,9],
        [35,12,35,17],
        [35,21,35,26],
        [35,29,35,37],
        [36,17,36,21],
        [44,0,44,6],
        [44,10,44,17],
        [54,0,54,17],
        [0,0,19,0],#horizontal
        [35,0,46,0],
        [52,0,54,0],
        [13,5,19,5],
        [19,6,24,6],
        [30,6,35,6],
        [0,13,10,13],
        [15,13,21,13],
        [25,13,44,13],
        [35,17,36,17],
        [44,17,54,17],
        [35,21,36,21],
        [4,23,12,23],
        [0,25,4,25],
        [19,25,36,25],
        [4,27,12,27],
        [0,37,35,37],
        [14,12,14,12],#dots
        [11,14,11,14]
    ]
    
    x = 25
    y = 19
    
    
    # - init -
    
    pygame.init()
    
    screen = pygame.display.set_mode((200,200))
    screen.fill(WHITE)
    
    # - draws -
    
    for item in collision:
        pygame.draw.line(screen, BLACK, item[:2], item[2:], 1)
    
    pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
    pygame.display.update()
    
    # - mainloop -
    
    clock = pygame.time.Clock()
    
    move_x = 0
    move_y = 0
    
    while True:
    
        # - events -
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
    
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    move_y = -1
    
                elif event.key == pygame.K_s:
                    move_y = 1
    
                elif event.key == pygame.K_a:
                    move_x = -1
    
                elif event.key == pygame.K_d:
                    move_x = 1
    
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_w:
                    move_y = 0
    
                elif event.key == pygame.K_s:
                    move_y = 0
    
                elif event.key == pygame.K_a:
                    move_x = 0
    
                elif event.key == pygame.K_d:
                    move_x = 0
    
        # - update -
    
        if move_x != 0 or move_y != 0:
    
            new_x = x + move_x
            new_y = y + move_y
    
            collide = check_collisions(collision, new_x, new_y)
    
            if not collide:
                pygame.draw.line(screen, WHITE, (x, y), (x, y), 1)
                x = new_x
                y = new_y
                pygame.draw.line(screen, RED, (x, y), (x, y), 1)
    
    
        pygame.display.update()
        clock.tick(FPS) # to display less frame and use less CPU