Python 使用基于地图的碰撞检测滚动背景Pygame
我正在创建一个游戏,它使用一个地图来进行碰撞,在我尝试将滚动添加到游戏中之前,这一切都是有效的。它应该使背景移动,而不是播放器移动,但问题在于碰撞检测 每个碰撞点的大小从16乘16变为1乘1。 这已被证明是相当有问题的,任何帮助修复它将不胜感激 我已经尝试更改了玩家的碰撞值和屏幕大小,但最终我不确定问题的确切原因是什么,我最好的猜测是我移除了玩家的移动,而是让它保持在屏幕上的相同位置,这导致了假设碰撞如何随位置变化而发生的问题,但这并不能解释碰撞点的收缩Python 使用基于地图的碰撞检测滚动背景Pygame,python,pygame,Python,Pygame,我正在创建一个游戏,它使用一个地图来进行碰撞,在我尝试将滚动添加到游戏中之前,这一切都是有效的。它应该使背景移动,而不是播放器移动,但问题在于碰撞检测 每个碰撞点的大小从16乘16变为1乘1。 这已被证明是相当有问题的,任何帮助修复它将不胜感激 我已经尝试更改了玩家的碰撞值和屏幕大小,但最终我不确定问题的确切原因是什么,我最好的猜测是我移除了玩家的移动,而是让它保持在屏幕上的相同位置,这导致了假设碰撞如何随位置变化而发生的问题,但这并不能解释碰撞点的收缩 import pygame, sys
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)
import pygame,sys
clock=pygame.time.clock()
从pygame.locals导入*
pygame.init()启动pygame
pygame.display.set_标题('游戏')
窗口大小=(600400)
screen=pygame.display.set_模式(窗口大小,0,32)
display=pygame.Surface((300200))
向右移动=错误
向左移动=错误
向上移动=错误
向下移动=错误
游戏地图=['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','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(100100,16,16)
黑色=(45,45,45)
黑色1=(60,60,60)
def碰撞测试(矩形、平铺):
点击列表=[]
对于瓷砖中的瓷砖:
如果矩形碰撞矩形(平铺):
点击列表。追加(平铺)
返回命中列表
def移动(矩形、移动、平铺):
冲突类型={'top':False,'bottom':False,'right':False,'left':False}
矩形x+=移动[0]
点击列表=碰撞测试(矩形、平铺)
对于hit_列表中的磁贴:
如果移动[0]>0:
rect.right=tile.left
碰撞类型['right']=True
elif移动[0]<0:
rect.left=tile.right
碰撞类型['left']=True
矩形y+=移动[1]
点击列表=碰撞测试(矩形、平铺)
对于hit_列表中的磁贴:
如果移动[1]>0:
rect.bottom=tile.top
碰撞类型['bottom']=True
elif移动[1]<0:
rect.top=tile.bottom
碰撞类型['top']=True
返回rect,冲突类型
尽管如此:
显示。填充((155155))
平铺矩形=[]
y=0
对于游戏地图中的图层:
x=0
对于层中的瓷砖:#瓷砖
如果平铺==“2”:
pygame.draw.rect(显示,黑色,(x*16-player_-rect.x,y*16-player_-rect.y,16,16))
如果瓷砖!='0':
tile_-rects.append(pygame.Rect(x*16-player_-Rect.x,y*16-player_-Rect.y,16,16))
x+=1
y+=1
玩家移动=[0,0]
如果向右移动=真:
玩家移动[0]+=2
如果向左移动=真:
玩家移动[0]-=2
如果上移=真:
玩家移动[1]-=2
如果向下移动=真:
玩家移动[1]+=2
玩家移动,碰撞=移动(玩家移动,玩家移动,平铺)
pygame.draw.rect(display,black1,(142100,16,16))#将142和100替换为rect.x和y,并从平铺中移除rect.x和y,将使其与原来的一样工作
对于pygame.event.get()中的事件:#事件循环
如果event.type==退出:
pygame.quit()
sys.exit()
如果event.type==KEYDOWN:
如果event.key==K_RIGHT:
向右移动=真
如果event.key==K_LEFT:
向左移动=真
如果event.key==K_UP:
向上移动=真
如果event.key==K_DOWN:
向下移动=真
如果event.type==KEYUP:
如果event.key==K_RIGHT:
向右移动=错误
如果event.key==K_LEFT:
向左移动=错误
如果event.key==K_UP:
向上移动=错误
如果event.key==K_DOWN:
向下移动=错误
屏幕.blit(pygame.transform.scale(显示,窗口大小),(0,0))
pygame.display.update()
时钟滴答(60)
我的预期结果是碰撞点不会改变,而是保持16乘16,不幸的是,平铺的碰撞点缩小到了1乘1,导致了许多问题。您的代码有点难以理解,但我知道问题出在哪里 在
move
功能中,更改player\u rect
的坐标以使其移动。但是当你画它的时候(pygame.draw.rect(display,black1,(142100,16,16))
)你在中间画它。所以你画的东西和运动测试的东西不匹配
老实说,如果不修改大量代码,我无法找到解决此问题的方法。如果你想保持背景滚动,考虑不要移动球员,而是移动相反方向的瓦片。我是说,我