簡體   English   中英

如何在Pygame中檢查矩形與矩形的先前位置的碰撞?

[英]How do I check collision of a rectangle and a previous position of a rectangle in Pygame?

我正在制作一個Tron游戲( https://www.classicgamesarcade.com/game/21670/tron-game.html ),需要檢查所有賽車手是否相互撞撞。

import pygame
pygame.init()

screenWidth = 500
screenHeight = 500
clock = pygame.time.Clock()
win = pygame.display.set_mode((screenWidth,screenHeight))
#both width and height of the characters
radius = 5
#amount of change in the x or y of the characters every frame
vel = 5

pygame.display.set_caption("Tron")


class character(object):
    #'direction' is the direction the character will move
    #'keyBinds' are the keys that can change the direction
    def __init__(self, x, y, color, direction, keyBinds):
        self.x = x
        self.y = y
        self.color = color
        self.direction = direction
        self.keyBinds = keyBinds

    #changes the direction the character moves
    def changeDirection(self, keys):
        #only changes when the right key was pressed and the character isn't already moving the opposite direction
        if keys[self.keyBinds[0]] and self.direction != 'r': 
            self.direction = 'l'
        elif keys[self.keyBinds[1]] and self.direction != 'l':
            self.direction = 'r'
        elif keys[self.keyBinds[2]] and self.direction != 'd':
            self.direction = 'u'
        elif keys[self.keyBinds[3]] and self.direction != 'u':
            self.direction = 'd'

    def move(self, vel):
        if self.direction == 'l':
            self.x -= vel
        elif self.direction == 'r':
            self.x += vel
        elif self.direction == 'u':
            self.y -= vel
        elif self.direction == 'd':
            self.y += vel

    #returns True if the character should be dead
    def checkDead(self, radius, screenWidth, screenHeight):
        #check if the character is out of bounds
        if (self.x < 0) or (self.x + radius > screenWidth) or (self.y < 0) or (self.y + radius > screenWidth):
            return True
        #check if the character has collided WIP


#makes a list with characters
chars = [
    character(480, 250, (255,0,0), 'l', (pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN)),
    character(20, 250, (0,255,0), 'r', (pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s))
    ]
run = True

#main loop
while run:
    #makes the loop run 30 times a second
    clock.tick(30)

    #closes the window, if 'X' is pressed
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    #logs all keys being pressed in a list I think xd
    keys = pygame.key.get_pressed()

    #closes the window, if there are no characters left in 'chars'
    if len(chars) > 0:
        #runs all object functions of every character in 'chars'
        for char in chars:
            char.changeDirection(keys)
            char.move(vel)
            #draws a rectangle representing the charater
            pygame.draw.rect(win, char.color, (char.x, char.y, radius, radius))
            #removes the character from 'chars' if checkDead returns True
            if char.checkDead(radius, screenWidth, screenHeight):
                chars.pop(chars.index(char))
    else:
        run = False

    pygame.display.update()

pygame.quit()

只有2個賽車手(在我的代碼中稱為字符),我可以使用一堆if語句來檢查其命中框的位置是否匹配,但是我計划稍后再增加8個賽車手,因此我認為不是一個好選擇。

現在出現了一個更大的問題。 就像在經典的《特隆》中一樣,我也需要讓賽車手的先前位置也算作碰撞。

除此之外,我一直都很欣賞關於如何改進代碼的提示,因此,如果您發現有任何不同的處理方法,請告訴我!

提前致謝!

編輯1:從以下方式更改標題:如何檢查Pygame中多個對象的矩形碰撞? 到:如何在Pygame中檢查矩形與矩形的先前位置之間的碰撞?,因為主要問題已經在其他文章中得到解答,但仍有其他問題需要解答。 另外,在我的代碼結構中,沖突檢查將在checkDead()中

最后,Tron是一款基於格網的游戲,因此一個簡單的解決方案是僅保留“已獲得”欠款的點/平鋪列表,然后檢查玩家是否嘗試移至已獲得的圖塊。

...
painted = set()
...
class character(object):
    ...
    #returns True if the character should be dead
    def checkDead(self, radius, screenWidth, screenHeight, painted):
        #check if the character is out of bounds
        if (self.x < 0) or (self.x + radius > screenWidth) or (self.y < 0) or (self.y + radius > screenWidth):
            return True

        #check if the character has collided WIP
        return (char.x / radius, char.y / radius) in painted

...
while run:
    ...
    #closes the window, if there are no characters left in 'chars'
    if len(chars) > 0:
        #runs all object functions of every character in 'chars'
        for char in chars:
            char.changeDirection(keys)
            char.move(vel)
            #removes the character from 'chars' if checkDead returns True
            if char.checkDead(radius, screenWidth, screenHeight, painted):
                chars.pop(chars.index(char))

        for char in chars:
            painted.add((char.x / radius, char.y / radius))

        for char in chars:
            #draws a rectangle representing the charater
            pygame.draw.rect(win, char.color, (char.x, char.y, radius, radius))

請注意,這是因為每幀移動一個圖塊。 如果您決定讓玩家每幀移動不止一個瓷磚,那么您也必須將這些額外的瓷磚添加到已painted布景中。

當然,有許多不同的方法可以做到這一點。 例如,您可以檢查要繪制矩形的屏幕部分是否有非黑色像素。 或者,您可以將繪制到屏幕上的所有矩形存儲在列表中,並使用Rect.colliderect檢查碰撞(可能很慢)。 因此,讓我們保持簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM