[英]Pygame collision with rectangles in list not working right
我正在制作 python pygame 迷宫游戏。 移动适用于移动的墙壁,但不适用于玩家,因为玩家永远不会逃离屏幕。 目前我正在努力在 X 轴上移动,但出了点问题。 当玩家与左墙碰撞时,它通常不会让它 go 更靠左。 但是当向右移动时,它会略微忽略碰撞并向右移动更多。
可重现的例子:
import pygame
import math
pygame.init()
surface = pygame.display.set_mode((1000,600))
clock = pygame.time.Clock()
surfrect = surface.get_rect()
player=pygame.Rect((0,0), (35,35))
player.center=surfrect.w/2,surfrect.h/2
touched = False
levelR=[]
control=pygame.Rect((0,0), (50,50))
controld=[]
yspeed,xspeed=0,0
for i in range(-1,2):
oxr=surfrect.w/2-75*3/2
oyr=surfrect.h/2-75*3/2+75*3*i
yr,xr=oyr,oxr
gf=[]
for y in '#-#n#-#n#-#'.split('n'):
for x in y:
if x=='#':
gf.append(pygame.Rect((xr, yr), (75,75)))
xr+=75
yr+=75
xr=oxr
levelR.append([gf,pygame.Rect((oxr,oyr),(75*3,75*3))])
while True:
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
elif ev.type == pygame.MOUSEBUTTONDOWN:
touched = True
elif ev.type == pygame.MOUSEBUTTONUP:
touched = False
surface.fill((0,0,0))
for sd in levelR:pygame.draw.rect(surface,(35,35,35),sd[1])
pygame.draw.circle(surface, (200,200,200), player.center, player.width/2-player.width/19, player.width)
for sd in levelR:
for rect in sd[0]:
scale=0.6
recti=pygame.Rect((rect.x,rect.y), (rect.width*scale,rect.height*scale))
recti.center=rect.center
pygame.draw.rect(surface,(255,255,255),rect)
pygame.draw.rect(surface,(0,0,0),recti)
if touched and not controld:
controld=pygame.mouse.get_pos()
control.center=controld
elif touched and controld:
radius = 150
x,y=pygame.mouse.get_pos()
distance=math.dist((x, y),controld)
if distance < radius:
pos=(x, y)
else:
dx=x-controld[0]
dy=y-controld[1]
ratio=radius/distance
pos=controld[0]+ratio*dx, controld[1]+ratio*dy
control.center=pos
try:xmd=(x-controld[0])/abs(x-controld[0])
except:xmd=0
try:ymd=(y-controld[1])/abs(y-controld[1])
except:ymd=0
sr=0.02*(150/radius)
xspeed=xmd*abs(control.centerx-controld[0])*sr
yspeed=ymd*abs(control.centery-controld[1])*sr
collisiont=5
for sd in levelR:
for block in sd[0]:
block.x-=xspeed
sd[1].x-=xspeed
for rect in [i for sd in levelR for i in sd[0]]:
if player.colliderect(rect):
for sd in levelR:
for block in sd[0]:
block.x+=xspeed
sd[1].x+=xspeed
break
pygame.draw.circle(surface, (255,255,255), control.center, control.width,control.width)
pygame.draw.circle(surface, (255,255,255), controld, radius, 5)
elif not touched and controld:controld=()
pygame.display.flip()
clock.tick(60)
我尝试调试碰撞并发现当与墙壁碰撞时向右移动会阻止玩家向右移动更多但玩家会稍微向右移动。
当玩家与墙壁碰撞时,我预计墙壁不会移动。
碰巧当玩家与墙壁碰撞时向右移动并没有直接阻止它。
由于pygame.Rect
应该代表屏幕上的一个区域,所以pygame.Rect
object 只能存储整数数据。
Rect 对象的坐标都是整数。 [...]
当Rect object 的 position 改变时,坐标的小数部分丢失。 在您的情况下,这意味着向左和向右的移动行为不同,并且block.x += xspeed
不是block.x -= xspeed
的逆运算。 考虑一下, 5 - 0.1
是4
,但4 + 0.1
仍然是4
。
您可以通过在实际移动之前测试 object 是否发生碰撞来解决此问题,如果检测到碰撞则根本不移动 object:
collide = False
for rect in [i for sd in levelR for i in sd[0]]:
text_rect = rect.copy()
text_rect.x -= xspeed
if player.colliderect(text_rect):
collide = True
break
if not collide:
for sd in levelR:
for block in sd[0]:
block.x-=xspeed
sd[1].x-=xspeed
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.