我正在制作python pygame迷宫游戏。移动可以和移动的墙壁一起工作,但不能和玩家一起工作,因为玩家永远不会逃离屏幕。目前我正在X轴上移动,但是出了问题。当玩家和左边的墙壁碰撞时,它通常不会让它向左移动。但是当向右移动时,它会稍微忽略碰撞而向右移动。
可重现示例:
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)
我试着调试碰撞,发现当与墙壁碰撞时向右移动会阻止玩家向右移动,但玩家会稍微向右移动。
我期望当玩家与墙壁碰撞时墙壁不会移动。
碰巧的是,当玩家撞到墙壁时向右移动并没有直接阻止它。
1条答案
按热度按时间e4yzc0pl1#
由于
pygame.Rect
应该表示屏幕上的一个区域,因此pygame.Rect
对象只能存储整数数据。Rect对象的坐标都是整数。[...]
当 Rect 对象的位置变更时,坐标的小数部分会遗失。在您的案例中,这表示向左和向右移动的行为不同,而且
block.x += xspeed
不是block.x -= xspeed
的逆运算。请考虑一下,5 - 0.1
是4
,但4 + 0.1
仍然是4
。可以通过在实际移动对象之前测试对象是否存在碰撞来解决此问题,如果检测到碰撞,则根本不移动对象: