python - 使用基于地图的碰撞检测 Pygame 滚动背景
问题描述
我正在创建一个使用地图进行碰撞的游戏,这一切都有效,直到我尝试将滚动添加到游戏中。它应该让背景而不是玩家移动,它确实如此,但问题在于碰撞检测。
每个碰撞点的大小从 16 x 16 变为 1 x 1。事实证明,这是非常有问题的,任何修复它的帮助将不胜感激
我尝试更改玩家的碰撞值、屏幕尺寸,但最后我不确定这个问题的确切原因是什么,我最好的猜测是我移除了玩家的移动,而是让它保持在相同的位置在屏幕上,已经导致碰撞如何随着位置的变化而发生问题,但这并不能解释碰撞点的缩小。
import pygame, sys
clock = pygame.time.Clock()
from pygame.locals import *
pygame.init() # initiates pygame
pygame.display.set_caption('The Game')
WINDOW_SIZE = (600,400)
screen = pygame.display.set_mode(WINDOW_SIZE,0,32)
display = pygame.Surface((300,200))
moving_right = False
moving_left = False
moving_up = False
moving_down = False
game_map = [['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'],
['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'],
['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'],
['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0']]
player_rect = pygame.Rect(100,100,16,16)
black = (45,45,45)
black1 = (60,60,60)
def collision_test(rect,tiles):
hit_list = []
for tile in tiles:
if rect.colliderect(tile):
hit_list.append(tile)
return hit_list
def move(rect,movement,tiles):
collision_types = {'top':False,'bottom':False,'right':False,'left':False}
rect.x += movement[0]
hit_list = collision_test(rect,tiles)
for tile in hit_list:
if movement[0] > 0:
rect.right = tile.left
collision_types['right'] = True
elif movement[0] < 0:
rect.left = tile.right
collision_types['left'] = True
rect.y += movement[1]
hit_list = collision_test(rect,tiles)
for tile in hit_list:
if movement[1] > 0:
rect.bottom = tile.top
collision_types['bottom'] = True
elif movement[1] < 0:
rect.top = tile.bottom
collision_types['top'] = True
return rect, collision_types
while True:
display.fill((155,155,155))
tile_rects = []
y = 0
for layer in game_map:
x = 0
for tile in layer: # tiles
if tile == '2':
pygame.draw.rect(display,black,(x*16-player_rect.x,y*16-player_rect.y,16,16))
if tile != '0':
tile_rects.append(pygame.Rect(x*16-player_rect.x,y*16-player_rect.y,16,16))
x += 1
y += 1
player_movement = [0,0]
if moving_right == True:
player_movement[0] += 2
if moving_left == True:
player_movement[0] -= 2
if moving_up == True:
player_movement[1] -= 2
if moving_down == True:
player_movement[1] += 2
player_rect,collisions = move(player_rect,player_movement,tile_rects)
pygame.draw.rect(display,black1,(142,100,16,16)) #replacing the 142 and 100 with the rect.x and y, and remove the rect.x and y from the tiles, will make it work like the original
for event in pygame.event.get(): # event loop
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
moving_right = True
if event.key == K_LEFT:
moving_left = True
if event.key == K_UP:
moving_up = True
if event.key == K_DOWN:
moving_down = True
if event.type == KEYUP:
if event.key == K_RIGHT:
moving_right = False
if event.key == K_LEFT:
moving_left = False
if event.key == K_UP:
moving_up = False
if event.key == K_DOWN:
moving_down = False
screen.blit(pygame.transform.scale(display,WINDOW_SIZE),(0,0))
pygame.display.update()
clock.tick(60)
我的预期结果是碰撞点不会改变并保持 16 x 16,不幸的是,瓷砖的碰撞点已经缩小到 1 x 1,导致很多问题。
解决方案
您的代码有点难以理解,但我知道问题出在哪里。
在您的move
函数中,您更改 的坐标player_rect
以使其移动。但是当你画它时 ( pygame.draw.rect(display,black1,(142,100,16,16))
) 你把它画在中心。因此,您绘制的内容与测试的运动内容之间存在不匹配。
老实说,如果不更改大量代码,我无法找到解决它的方法。
如果您想保持背景滚动,请考虑不要移动玩家,而是向相反方向移动瓷砖。我的意思是,如果玩家向左移动,则向右移动瓷砖,依此类推。
目前,您正在每次迭代创建切片。我建议在主循环之外创建它们,并在循环中移动它们(编辑它们的坐标rect
)。
推荐阅读
- python - 如何使用 Python 发出 URL 请求并返回重定向到的 URL?
- prolog - 如何在 ECLIPSE-CLP 或 Prolog 中实现这些 Sigma 符号
- electron - 如何将电子生成器与目标便携式设备一起使用?
- python - 打印语句的问题
- vb.net - 如何在 vb.net 的查询字符串中不通过 $expand 来扩展(odata-webapi)所有属性
- python - 如何在 Python 中以附加模式打开 /etc/hosts 文件?
- regex - 使正则表达式以懒惰的方式匹配,同时跳过一些单词
- java - 完成所有字段验证后如何重定向 zk 另一个页面?
- c# - 两个连接实体之间的 EF Core 查询
- javascript - 不带钩子更新文档标题