Python 玩家赢了';由于重力把他推到地上,他不能正确移动
我用pygame ad制作了一个tilemap平台,我为玩家定义了X和Y方向的运动,也定义了一个Y方向的力,代表重力,使其正确跳跃。然而,当我的玩家从地上摔下来,游戏开始时,由于重力不断地将他推到下方,它无法正确地向右或向左移动。除此之外,当玩家跳跃时,我将其移动到右侧,就好像它无法识别与墙的底部矩形的碰撞(请参见下面的gif以获得视觉解释) 我试着在玩家触地时禁用重力,在玩家跳跃时启用重力,但它没有按预期工作,而且我在管理碰撞时遇到了问题(同样,禁用重力也没有意义,对吧?) 这是我的玩家课程:Python 玩家赢了';由于重力把他推到地上,他不能正确移动,python,pygame,collision-detection,Python,Pygame,Collision Detection,我用pygame ad制作了一个tilemap平台,我为玩家定义了X和Y方向的运动,也定义了一个Y方向的力,代表重力,使其正确跳跃。然而,当我的玩家从地上摔下来,游戏开始时,由于重力不断地将他推到下方,它无法正确地向右或向左移动。除此之外,当玩家跳跃时,我将其移动到右侧,就好像它无法识别与墙的底部矩形的碰撞(请参见下面的gif以获得视觉解释) 我试着在玩家触地时禁用重力,在玩家跳跃时启用重力,但它没有按预期工作,而且我在管理碰撞时遇到了问题(同样,禁用重力也没有意义,对吧?) 这是我的玩家课程
class Player(pg.sprite.Sprite):
def __init__(self, game, x, y):
self.groups = game.sprites
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.Surface((TILESIZE, TILESIZE))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.move_left = self.move_right = False
self.pos = pg.math.Vector2(x, y)
self.acc = pg.math.Vector2(0, GRAVITY)
self.vel = pg.math.Vector2(0, 0)
def jump(self):
self.vel.y -= 3
def update(self):
self.vel.x = 0
if self.move_left:
self.vel.x = -PLAYER_SPEED
if self.move_right:
self.vel.x = PLAYER_SPEED
self.vel += self.acc
self.pos += self.vel
self.rect.x = self.pos.x * TILESIZE
self.rect.y = self.pos.y * TILESIZE
if self.vel.y > 0.5:
self.vel.y = 0.5
hits = pg.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.vel.x > 0:
self.pos -= self.vel
self.rect.right = hits[0].rect.left
self.vel.x = 0
if self.vel.x < 0:
self.pos -= self.vel
self.rect.left = hits[0].rect.right
self.vel.x = 0
hits = pg.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.vel.y > 0:
self.pos -= self.vel
self.rect.bottom = hits[0].rect.top
self.vel.y = 0
if self.vel.y < 0:
self.pos -= self.vel
self.rect.top = hits[0].rect.bottom
self.vel.y = 0
职业玩家(pg.sprite.sprite):
定义初始化(self,game,x,y):
self.groups=game.sprite
pg.sprite.sprite.\uuuu init\uuuu(self,self.groups)
self.game=游戏
self.image=pg.Surface((瓷砖大小,瓷砖大小))
self.image.fill(绿色)
self.rect=self.image.get_rect()
self.move\u left=self.move\u right=False
self.pos=pg.math.Vector2(x,y)
self.acc=pg.math.Vector2(0,重力)
self.vel=pg.math.Vector2(0,0)
def跳转(自):
自我水平y-=3
def更新(自我):
self.vel.x=0
如果self.move_向左移动:
self.vel.x=-玩家速度
如果self.move_向右移动:
self.vel.x=玩家速度
self.vel+=self.acc
self.pos+=self.vel
self.rect.x=self.pos.x*波浪大小
self.rect.y=self.pos.y*瓷砖大小
如果自身水平y>0.5:
自身水平y=0.5
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
如果self.vel.x>0:
self.pos-=self.vel
self.rect.right=点击[0]。rect.left
self.vel.x=0
如果自身水平x<0:
self.pos-=self.vel
self.rect.left=点击[0]。rect.right
self.vel.x=0
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
如果自身水平y>0:
self.pos-=self.vel
self.rect.bottom=点击[0]。rect.top
自我水平y=0
如果自身水平y<0:
self.pos-=self.vel
self.rect.top=点击[0]。rect.bottom
自我水平y=0
问题是调用spritecollide
两次,同时更新位置:
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
#如果其中一个条件为真,则位置将更新,
#继续先前的速度,即穿过屋顶。
如果self.vel.x>0:
self.pos-=self.vel
# [...]
如果自身水平x<0:
self.pos-=self.vel
# [...]
#穿过屋顶后,就不会再有碰撞了。。。
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
如果自身水平y>0:
self.pos-=self.vel
# [...]
自我水平y=0
两种情况,当前代码为:
- 如果您在没有x-speed的情况下跳跃,则不会更新位置(也称为穿过屋顶)。因此,第二次调用spritecollide会返回一个非空的
,您将在屋顶上弹跳hits
- 如果x-speed为非空,则更新穿过车顶的位置,如果hits:第二个
为假
解决方案:只调用
hits=pg.sprite.spritecollide(self,self.game.walls,False)
一次,在更新所有速度之前不要更改位置。问题是调用spritecollide
两次,同时更新位置:
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
#如果其中一个条件为真,则位置将更新,
#继续先前的速度,即穿过屋顶。
如果self.vel.x>0:
self.pos-=self.vel
# [...]
如果自身水平x<0:
self.pos-=self.vel
# [...]
#穿过屋顶后,就不会再有碰撞了。。。
hits=pg.sprite.spritecollide(self,self.game.walls,False)
如果点击:
如果自身水平y>0:
self.pos-=self.vel
# [...]
自我水平y=0
两种情况,当前代码为:
- 如果您在没有x-speed的情况下跳跃,则不会更新位置(也称为穿过屋顶)。因此,第二次调用spritecollide会返回一个非空的
,您将在屋顶上弹跳hits
- 如果x-speed为非空,则更新穿过车顶的位置,如果hits:第二个
为假
解决方案:只调用一次
hits=pg.sprite.spritecollide(self,self.game.walls,False)
并且在所有速度更新之前不要更改位置。你不应该在屋顶、墙壁(地面)上有不同类型的碰撞吗?我应该吗?实际上,我正在关注一些关于YT的教程系列,它们似乎都使用组来检测碰撞。你不应该有不同类型的碰撞,在屋顶上,在墙上(,在地面上)?我应该吗?实际上,我正在关注一些关于YT的教程系列,它们似乎都使用组来检测冲突。正如您所看到的,我更改了代码,但现在似乎无法识别任何冲突。秘密解决方案