繁体   English   中英

Pygame 与列表中的矩形碰撞无法正常工作

[英]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.14 ,但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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM