我正在制作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()
中进行答案 0 :(得分:1)
最后,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
检查是否存在碰撞(可能很慢)。因此,让我们保持简单。