![](/img/trans.png)
[英]How do I detect collisions between one rectangle and a previous position of another rectangle? 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.