Pygame 中的 Tilemaps 中没有坐标的碰撞检测
Collision Detection without Coordinates in Tilemaps in Pygame
我正在编写一个炸弹人游戏,现在我没有任何精灵,但我使用了矩形。
这是我的代码:
import pygame
pygame.init()
WinWidth = 800
WinHeight = 608
p1x = 32
p1y = 32
vel = 1
clock = pygame.time.Clock()
win = pygame.display.set_mode((WinWidth, WinHeight))
def player():
pygame.draw.rect(win, (0, 200, 200), (p1x, p1y, 32, 32))
player_rect = pygame.Rect(p1x, p1y, tlw, tlh)
class Wall:
def __init__(self, x, y):
self.x = x
self.y = y
pygame.draw.rect(win, (50, 50, 50), (x, y, 32, 32))
class Breakable:
def __init__(self, x, y):
self.x = x
self.y = y
pygame.draw.rect(win, (200, 150, 100), (x, y, 32, 32))
game_map1 = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 0, 0, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 0, 0, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
run = True
while run:
pygame.init()
clock.tick(100)
win.fill((0, 255, 200))
y = 0
for layer in game_map1:
x = 0
for tile in layer:
if tile == 0:
Wall(x * 32, y * 32)
wall_rect = pygame.Rect(x * 32, y * 32, tlw, tlh)
if tile == 10:
pygame.Rect(x * 32, y * 32, 32, 32)
if tile == 2:
Breakable(x * 32, y * 32)
x += 1
y += 1
player()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1x += vel
elif event.key == pygame.K_a:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1x -= vel
if event.key == pygame.K_s:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1y += vel
elif event.key == pygame.K_w:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1y -= vel
pygame.display.update()
x
和 y
位于播放器矩形的左上角 - 它们是 p1x
和 p1y
。
宽度和高度分别为 tlw
和 tlh
。
The Wall 和 Breakable 也在使用 tlw
和 tlh
,它们没有像玩家那样的特定坐标。
sooo...我看了教程 (https://www.youtube.com/watch?v=HCWI2f7tQnY&t=2s),甚至尝试自己进行碰撞检测。但我就是做不到。我没有 tilemap 中矩形的坐标,而且 tilemap 中也有很多矩形。如何使用没有坐标且有许多矩形的瓦片地图进行碰撞检测?是的,游戏目前没有太多内容......我尝试使用 pygame.Rect 的 player_rect
和 wall_rect
然后使用 (colliderect)
但是它没有用,你怎么能让 player_rect 与所有 wall_rect 发生碰撞,而不仅仅是与一个发生碰撞。
我的问题是:如何使用 colliderect 对瓦片地图进行碰撞检测?
我已经重构了整个代码,因为你发布的代码抛出了一个错误,我无法测试我的代码。我们在这里实现碰撞检测的方法有效但不是很有效。如果你想知道哪一侧发生碰撞以便实现游戏逻辑,那么 colliderect
就毫无意义了。我建议你问一个关于如何构建自定义碰撞检测的新问题,因为这是一个全新的主题,但下面的代码解决了如何使用 colliderect 实现碰撞检测的原始问题。下面的示例还展示了绘制函数应该如何成为一个单独的方法,这是更好的方法。顺便说一句,如果 tile == 10
你在你的问题中输入了 pygame.Rect(x * 32, y * 32, 32, 32)
基本上什么都不做,所以我输入 pass
。如果你想让它成为一种新型的墙,你可以制作一个类似于Breakable
和Wall
的新class。最后的回答,希望对你有帮助:).
import pygame
pygame.init()
WinWidth = 800
WinHeight = 608
clock = pygame.time.Clock()
win = pygame.display.set_mode((WinWidth, WinHeight))
class Player:
def __init__(self):
self.x = 32
self.y = 32
self.width = 20
self.height = 20
self.vel = 0.1
def draw(self):
pygame.draw.rect(win, (0, 200, 200), (self.x, self.y, 32, 32))
def getRect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
class Wall:
def __init__(self, rect):
self.rect = rect
self.x = rect.x
self.y = rect.y
def draw(self):
pygame.draw.rect(win, (50, 50, 50), self.rect)
def getRect(self):
return pygame.Rect(self.x, self.y, 32, 32)
class Breakable:
def __init__(self, rect):
self.rect = rect
self.x = rect.x
self.y = rect.y
def draw(self):
pygame.draw.rect(win, (200, 150, 100), self.rect)
def getRect(self):
return pygame.Rect(self.x, self.y, 32, 32)
game_map1 = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 0, 0, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 0, 0, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
walls = []
y = 0
for layer in game_map1:
x = 0
for tile in layer:
if tile == 0:
walls.append(Wall(pygame.Rect([x*32, y*32, 32, 32])))
if tile == 10:
pass
if tile == 2:
walls.append(Breakable(pygame.Rect([x*32, y*32, 32, 32])))
x += 1
y += 1
player = Player()
pygame.init()
run = True
while run:
clock.tick(100)
win.fill((0, 255, 200))
for i in range(len(walls)):
walls[i].draw()
player.draw()
for wall in walls:
if player.getRect().colliderect(wall.getRect()): #getRect is the method we added to wall class earlier
print("they are colliding")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
run = False
if event.type == pygame.KEYDOWN:
for wall in walls:
wall_rect = wall.getRect()
if event.key == pygame.K_d:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.x += player.vel
elif event.key == pygame.K_a:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.x -= player.vel
if event.key == pygame.K_s:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.y += player.vel
elif event.key == pygame.K_w:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.y -= player.vel
pygame.display.update()
关于你的最后一个问题:
#Checks if right side of rect1 is colliding with left side of rect2
def rightCheck(rect1, rect2):
if rect1.x + rect1.width > rect2.x:
if (rect1.y > rect2.y and rect1.y < rect2.y + rect2.height) or (rect1.y + rect1.height < rect2.y + rect2.height and rect1.y + rect1.height> rect2.y):
if rect1.x < rect2.x:
return True
return False
#Checks if top side of rect1 is colliding with bottom side of rect2
def topCheck(rect1, rect2):
if rect1.y < rect2.y + rect2.height:
if (rect1.x > rect2.x and rect1.x < rect2.x + rect2.width) or (rect1.x + rect1.width > rect2.x and rect1.x + rect1.width < rect2.x + rect2.width):
if rect1.y > rect2.y:
return True
return False
#Checks if bottom side of rect1 is colliding with top side of rect2
def botCheck(rect1, rect2):
if rect1.y + rect1.height > rect2.y:
if (rect1.x > rect2.x and rect1.x < rect2.x + rect2.width) or (rect1.x + rect1.width > rect2.x and rect1.x + rect1.width < rect2.x + rect2.width):
if rect1.y < rect2.y:
return True
return False
这些是您可以使用的自定义碰撞检测函数。我还没有播放器左侧 (rect1) 的那个,但我稍后会尝试制作它,或者您也可以尝试制作一个。您也可以尝试改进我提供的内容以适合您的游戏。使用这些你可以准确地找出哪一侧发生碰撞,并添加有用的逻辑。示例:
#have different velocities for every side
player_right_speed = 2
player_left_speed = 2
# Say that your player moves according to the following key presses
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
playerx += player_right_speed
if key[pygame.K_LEFT]:
playerx -= player_left_speed
#you can call the collision detection functions to check if they are colliding and if they are set the speed in that direction to 0
#notice these functions take pygame.Rect as an argument
right_colliding = rightCheck(playerRect, tileRect)
if right_colliding:
player_right_speed = 0
left_colliding = leftCheck(playerRect, tileRect)
if left_colliding:
player_left_speed = 0
我正在编写一个炸弹人游戏,现在我没有任何精灵,但我使用了矩形。 这是我的代码:
import pygame
pygame.init()
WinWidth = 800
WinHeight = 608
p1x = 32
p1y = 32
vel = 1
clock = pygame.time.Clock()
win = pygame.display.set_mode((WinWidth, WinHeight))
def player():
pygame.draw.rect(win, (0, 200, 200), (p1x, p1y, 32, 32))
player_rect = pygame.Rect(p1x, p1y, tlw, tlh)
class Wall:
def __init__(self, x, y):
self.x = x
self.y = y
pygame.draw.rect(win, (50, 50, 50), (x, y, 32, 32))
class Breakable:
def __init__(self, x, y):
self.x = x
self.y = y
pygame.draw.rect(win, (200, 150, 100), (x, y, 32, 32))
game_map1 = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 0, 0, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 0, 0, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
run = True
while run:
pygame.init()
clock.tick(100)
win.fill((0, 255, 200))
y = 0
for layer in game_map1:
x = 0
for tile in layer:
if tile == 0:
Wall(x * 32, y * 32)
wall_rect = pygame.Rect(x * 32, y * 32, tlw, tlh)
if tile == 10:
pygame.Rect(x * 32, y * 32, 32, 32)
if tile == 2:
Breakable(x * 32, y * 32)
x += 1
y += 1
player()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1x += vel
elif event.key == pygame.K_a:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1x -= vel
if event.key == pygame.K_s:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1y += vel
elif event.key == pygame.K_w:
if player_rect.colliderect(wall_rect):
p1x *= -1
p1y *= -1
else:
p1y -= vel
pygame.display.update()
x
和 y
位于播放器矩形的左上角 - 它们是 p1x
和 p1y
。
宽度和高度分别为 tlw
和 tlh
。
The Wall 和 Breakable 也在使用 tlw
和 tlh
,它们没有像玩家那样的特定坐标。
sooo...我看了教程 (https://www.youtube.com/watch?v=HCWI2f7tQnY&t=2s),甚至尝试自己进行碰撞检测。但我就是做不到。我没有 tilemap 中矩形的坐标,而且 tilemap 中也有很多矩形。如何使用没有坐标且有许多矩形的瓦片地图进行碰撞检测?是的,游戏目前没有太多内容......我尝试使用 pygame.Rect 的 player_rect
和 wall_rect
然后使用 (colliderect)
但是它没有用,你怎么能让 player_rect 与所有 wall_rect 发生碰撞,而不仅仅是与一个发生碰撞。
我的问题是:如何使用 colliderect 对瓦片地图进行碰撞检测?
我已经重构了整个代码,因为你发布的代码抛出了一个错误,我无法测试我的代码。我们在这里实现碰撞检测的方法有效但不是很有效。如果你想知道哪一侧发生碰撞以便实现游戏逻辑,那么 colliderect
就毫无意义了。我建议你问一个关于如何构建自定义碰撞检测的新问题,因为这是一个全新的主题,但下面的代码解决了如何使用 colliderect 实现碰撞检测的原始问题。下面的示例还展示了绘制函数应该如何成为一个单独的方法,这是更好的方法。顺便说一句,如果 tile == 10
你在你的问题中输入了 pygame.Rect(x * 32, y * 32, 32, 32)
基本上什么都不做,所以我输入 pass
。如果你想让它成为一种新型的墙,你可以制作一个类似于Breakable
和Wall
的新class。最后的回答,希望对你有帮助:).
import pygame
pygame.init()
WinWidth = 800
WinHeight = 608
clock = pygame.time.Clock()
win = pygame.display.set_mode((WinWidth, WinHeight))
class Player:
def __init__(self):
self.x = 32
self.y = 32
self.width = 20
self.height = 20
self.vel = 0.1
def draw(self):
pygame.draw.rect(win, (0, 200, 200), (self.x, self.y, 32, 32))
def getRect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
class Wall:
def __init__(self, rect):
self.rect = rect
self.x = rect.x
self.y = rect.y
def draw(self):
pygame.draw.rect(win, (50, 50, 50), self.rect)
def getRect(self):
return pygame.Rect(self.x, self.y, 32, 32)
class Breakable:
def __init__(self, rect):
self.rect = rect
self.x = rect.x
self.y = rect.y
def draw(self):
pygame.draw.rect(win, (200, 150, 100), self.rect)
def getRect(self):
return pygame.Rect(self.x, self.y, 32, 32)
game_map1 = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 0, 0, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 0, 0, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 10, 10, 10, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 0, 2, 2, 10, 2, 2, 0, 2, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 10, 10, 2, 2, 10, 2, 2, 10, 10, 2, 2, 2, 2, 0],
[0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
[0, 10, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 10, 0],
[0, 10, 10, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10, 10, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
walls = []
y = 0
for layer in game_map1:
x = 0
for tile in layer:
if tile == 0:
walls.append(Wall(pygame.Rect([x*32, y*32, 32, 32])))
if tile == 10:
pass
if tile == 2:
walls.append(Breakable(pygame.Rect([x*32, y*32, 32, 32])))
x += 1
y += 1
player = Player()
pygame.init()
run = True
while run:
clock.tick(100)
win.fill((0, 255, 200))
for i in range(len(walls)):
walls[i].draw()
player.draw()
for wall in walls:
if player.getRect().colliderect(wall.getRect()): #getRect is the method we added to wall class earlier
print("they are colliding")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
run = False
if event.type == pygame.KEYDOWN:
for wall in walls:
wall_rect = wall.getRect()
if event.key == pygame.K_d:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.x += player.vel
elif event.key == pygame.K_a:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.x -= player.vel
if event.key == pygame.K_s:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.y += player.vel
elif event.key == pygame.K_w:
if player.getRect().colliderect(wall_rect):
player.x *= -1
player.y *= -1
else:
player.y -= player.vel
pygame.display.update()
关于你的最后一个问题:
#Checks if right side of rect1 is colliding with left side of rect2
def rightCheck(rect1, rect2):
if rect1.x + rect1.width > rect2.x:
if (rect1.y > rect2.y and rect1.y < rect2.y + rect2.height) or (rect1.y + rect1.height < rect2.y + rect2.height and rect1.y + rect1.height> rect2.y):
if rect1.x < rect2.x:
return True
return False
#Checks if top side of rect1 is colliding with bottom side of rect2
def topCheck(rect1, rect2):
if rect1.y < rect2.y + rect2.height:
if (rect1.x > rect2.x and rect1.x < rect2.x + rect2.width) or (rect1.x + rect1.width > rect2.x and rect1.x + rect1.width < rect2.x + rect2.width):
if rect1.y > rect2.y:
return True
return False
#Checks if bottom side of rect1 is colliding with top side of rect2
def botCheck(rect1, rect2):
if rect1.y + rect1.height > rect2.y:
if (rect1.x > rect2.x and rect1.x < rect2.x + rect2.width) or (rect1.x + rect1.width > rect2.x and rect1.x + rect1.width < rect2.x + rect2.width):
if rect1.y < rect2.y:
return True
return False
这些是您可以使用的自定义碰撞检测函数。我还没有播放器左侧 (rect1) 的那个,但我稍后会尝试制作它,或者您也可以尝试制作一个。您也可以尝试改进我提供的内容以适合您的游戏。使用这些你可以准确地找出哪一侧发生碰撞,并添加有用的逻辑。示例:
#have different velocities for every side
player_right_speed = 2
player_left_speed = 2
# Say that your player moves according to the following key presses
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
playerx += player_right_speed
if key[pygame.K_LEFT]:
playerx -= player_left_speed
#you can call the collision detection functions to check if they are colliding and if they are set the speed in that direction to 0
#notice these functions take pygame.Rect as an argument
right_colliding = rightCheck(playerRect, tileRect)
if right_colliding:
player_right_speed = 0
left_colliding = leftCheck(playerRect, tileRect)
if left_colliding:
player_left_speed = 0