1

我是 Python 和一般编程的新手,所以我决定用 2 名玩家制作 Tron 的基本克隆。澄清一下,Tron 是一款游戏,玩家骑着自行车在他们身后创造一条路径/小径。如果一个玩家撞到另一个玩家的路径/轨迹,他们就输了。我试图通过在pygame中使用矩形来检测我的代码中的这种类型的碰撞。

我对如何实现这个想法有一个大致的想法:每次玩家移动时,他们都会在他们身后制作连续的矩形,这些矩形会附加到名为 tron_path_1 或 tron_path_2 的列表中。因此,如果玩家 1 的 rect 与对方玩家(tron_path_2)列表中的 rect 碰撞,我想检测该碰撞。但是在我的代码中,如果每个玩家的两个头部相互碰撞,我只能检测到碰撞。所以我的问题是:如何检测玩家的矩形与对方玩家先前的矩形的碰撞?

import pygame
import sys

class Player():
    def __init__(self, screen, x, y, w, h, dx, dy, tron_path, color):

        """Create player's tron bike."""
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.x = x 
        self.y = y
        self.w = w #width
        self.h = h #height
        self.dx = dx
        self.dy = dy
        self.tron_path = tron_path
        self.color = color

        self.player_rect = pygame.Rect(self.x, self.y, self.w, self.h)

    def update_position(self):
        self.player_rect[0] += self.dx #changes rect's x-coordinate 
        self.player_rect[1] += self.dy #changes rect's y-coordinate

        self.tron_path.append(self.player_rect)

    def draw_player(self):
        pygame.draw.rect(self.screen, self.color, self.player_rect)

# Initialize pygame settings.
pygame.init()
screen = pygame.display.set_mode((1200,700))
pygame.display.set_caption("Tron")

# Player settings
p1_color = ((219,62,177))  #pink
p2_color = ((255,255,255)) #white
players = []
tron_path_1 = [] # List to keep track of rectangles for each player
tron_path_2 = []
p1 = Player(screen, x=200, y=500, w=5, h=5, dx=5, dy=0, tron_path=tron_path_1, color=p1_color) #player 1
p2 = Player(screen, x=1000, y=500, w=5, h=5, dx=-5, dy=0, tron_path=tron_path_2, color=p2_color) #player 2
players.append(p1)
players.append(p2)


# Initialize
while True:
    clockobject = pygame.time.Clock()
    clockobject.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            # Player 1 controls
            if event.key == pygame.K_w:
                p1.dx = 0
                p1.dy = -5

            elif event.key == pygame.K_s:
                p1.dx = 0
                p1.dy = 5

            elif event.key == pygame.K_d:
                p1.dx = 5
                p1.dy = 0

            elif event.key == pygame.K_a:
                p1.dx = -5
                p1.dy = 0

            # Player 2 controls
            if event.key == pygame.K_UP:
                p2.dx = 0
                p2.dy = -5

            elif event.key == pygame.K_DOWN:
                p2.dx = 0
                p2.dy = 5

            elif event.key == pygame.K_RIGHT:
                p2.dx = 5
                p2.dy = 0

            elif event.key == pygame.K_LEFT:
                p2.dx = -5
                p2.dy = 0

    p1.update_position()
    p2.update_position()
    p1.draw_player()
    p2.draw_player()

    # Trying to detect collision with one player and another player's path
    for rect in tron_path_1:
        if p2.player_rect.colliderect(rect):
            print("collision")
    for rect in tron_path_2:
        if p1.player_rect.colliderect(rect):
            print("collision")

    pygame.display.flip()
4

1 回答 1

1

当您这样做时tron_path_1.append(p1.player_rect),您不会创建p1.player_rect. p1.player_rect是引用pygame.Rect对象的变量。
之后tron_path_1.append(p1.player_rect),变量p1.player_rect和列表元素tron_path_1[0]引用同一个对象。
因此,当您更改 时p1.player_rect,列表的元素似乎也发生了变化,因为只有 1 个pygame.Rect对象。

用于.copy()创建矩形的副本:

class Player():
    # [...]

    def update_position(self):
        self.player_rect[0] += self.dx #changes rect's x-coordinate 
        self.player_rect[1] += self.dy #changes rect's y-coordinate

        # self.tron_path.append(self.player_rect) <--- CHANGE TO
        self.tron_path.append(self.player_rect.copy())
于 2020-04-13T18:46:58.160 回答