如何将Pygame玩家精灵限制在自定义多边形边界内?
问题:将Pygame玩家精灵限制在多边形边界内
我已经实现了将玩家精灵限制在窗口矩形范围内,但不知道如何把它限制在动态多边形边界里。
现有代码
Player精灵类
class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.movex = 0 self.movey = 0 self.frame = 0 self.images = [] for i in range(1,5): img = pygame.image.load(os.path.join('assets/player', 'run-' + str(i) + '.png')).convert_alpha() self.images.append(img) self.image = self.images[0] self.rect = self.image.get_rect() def control(self,x,y): self.movex += x self.movey += y def update(self): self.rect.x = self.rect.x + self.movex self.rect.y = self.rect.y + self.movey
多边形边界定义
self.boundaries = [ [[(475,350),(575,350),(500,550),(300,550)],], [[(0,0),(100,100),(200,200)]], [[(0,0),(100,100),(200,200)]], ]
当前尝试的限制逻辑(未成功)
self.stages.level=0 self.stages_boundary_index=0 ##self.stages.player.rect.clamp_ip(pygame.display.get_surface().get_rect()) #Detection between sprite and a boundary """ x = self.stages.boundaries[self.stages.level][self.stages.boundary_index] print(x) elem=Rect(x[0],x[1],x[2],x[3]) self.stages.player.rect.clamp_ip(elem) """
编辑说明:尝试碰撞检测后存在边界偏移
我写了一套线与线、矩形与多边形的碰撞检测代码,但实际运行时发现边界有偏移问题:
def collideLineLine(l1_p1, l1_p2, l2_p1, l2_p2): # normalized direction of the lines and start of the lines P = pygame.math.Vector2(*l1_p1) line1_vec = pygame.math.Vector2(*l2_p1) - P R = line1_vec.normalize() Q = pygame.math.Vector2(*l2_p1) line2_vec = pygame.math.Vector2(*l2_p2) - Q S = line2_vec.normalize() # normal vectors to the lines RNV = pygame.math.Vector2(R[1], -R[0]) SNV = pygame.math.Vector2(S[1], -S[0]) RdotSVN = R.dot(SNV) if RdotSVN == 0: return False # distance to the intersection point QP = Q - P t = QP.dot(SNV) / RdotSVN u = QP.dot(RNV) / RdotSVN return t > 0 and u > 0 and t*t < line1_vec.magnitude_squared() and u*u < line2_vec.magnitude_squared() def colideRectLine(rect, p1, p2): return (collideLineLine(p1, p2, rect.topleft, rect.bottomleft) or collideLineLine(p1, p2, rect.bottomleft, rect.bottomright) or collideLineLine(p1, p2, rect.bottomright, rect.topright) or collideLineLine(p1, p2, rect.topright, rect.topleft)) def collideRectPolygon(rect, polygon): for i in range(len(polygon)-1): if colideRectLine(rect, polygon[i], polygon[i+1]): return True return False class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.movex = 0 self.movey = 0 self.frame = 0 self.images = [] for i in range(1,5): img = pygame.image.load(os.path.join('assets/player', 'run-' + str(i) + '.png')).convert_alpha() self.images.append(img) self.image = self.images[0] self.rect = self.image.get_rect() def control(self,x,y): self.movex += x self.movey += y def update(self,boundary): if self.movex > 0: self.image = self.images[self.frame//ani] if self.movey !=0: if collideRectPolygon(self.rect, boundary): self.rect.x+=self.movex self.rect.y+=self.movey else: self.rect.x-=self.movex self.rect.y-=self.movey self.movex=0 self.movey=0 else: if collideRectPolygon(self.rect, boundary): self.rect.x+=self.movex else: self.rect.x-=self.movex self.movex=0 elif self.movex < 0: self.image = pygame.transform.flip(self.images[self.frame // ani], True, False) if self.movey !=0: if collideRectPolygon(self.rect, boundary): self.rect.x+=self.movex self.rect.y+=self.movey else: self.rect.x-=self.movex self.rect.y-=self.movey self.movex=0 self.movey=0 else: if collideRectPolygon(self.rect, boundary): self.rect.x+=self.movex else: self.rect.x-=self.movex self.movex=0 else: self.image = self.images[self.frame//ani] if self.movey !=0: if collideRectPolygon(self.rect, boundary): self.rect.y+=self.movey else: self.rect.y-=self.movey self.movey=0 else: pass
内容的提问来源于stack exchange,提问作者Arundeep Chohan
相关产品推荐
相关产品推荐

