Pygame Raycasting用于视线

时间:2016-07-08 20:58:21

标签: python pygame raycasting

我正在做一个2d自上而下的射击游戏,理想情况下我希望敌人只有在看到他/她时才会向玩家开枪(所以玩家可以躲在箱子后面等等)。

我做过研究,我认为最好的方法是做光线投射。我无法在pygame中找到一个很好的光线投射示例。

或者,我在另一个stackoverflow问题(Pygame Line of Sight from Fixed Position

上看到了这段代码
def isInLine(player, person):
    deltaX = person[0] - player[0]
    deltaY = person[1] - player[1]

    if (person[0] == player[0]) or (person[1] == player[1]) or (abs(deltaX) == abs(deltaY)):
       return true

但我不确定它是否会实现我想要的那种东西,如果它是我不确定我将如何实现它。

我首先要问的是,我使用的代码是否会实现我想要做的事情,如果是这样,我将如何实现它,是否有更好的方法来实现它。

1 个答案:

答案 0 :(得分:1)

我假设变量' player'和' person'是玩家和敌人的位置?如果是这样,您添加的代码将检查是否有两个对象:

  • 位于相同的x位置(person [0] == player [0])
  • 处于相同的y位置(person [1] == player [1])
  • 具有相等的x和y差异,即物体彼此成45度(abs(deltaX)== abs(deltaY))。

然而,这并不像你想要的那样。

如果您检查是否可能有效:

  • 敌人和障碍物之间的角度等于敌人和玩家之间的角度。一种方法是使用tan(角度)=反向/相邻,或deltaY / deltaX。

  • 敌人离玩家更远,而不是从街垒。这可以使用毕达哥拉斯来完成。

这是一个可能有用的功能:

import math

def isInLine(enemy_pos, player_pos, barrier_pos):
   # get x and y displacements from enemy to objects
   playerDX = player_pos[0] - enemy_pos[0]
   playerDY = player_pos[1] - enemy_pos[1]
   barrierDX = barrier_pos[0] - enemy_pos[0]
   barrierDY = barrier_pos[1] - enemy_pos[1]

   # have to convert to degrees, as math uses radians
   playerAngle = math.degrees( math.atan(playerDY / playerDX) )
   barrierAngle = math.degrees( math.atan(barrerDY / barrierDX) )

   # use pythagoras to find distances
   playerDist = math.sqrt( (playerDX)**2 + (playerDY)**2 )
   barrierDist = math.sqrt( (barrierDX)**2 + (barrierDY)**2 )

   return (playerAngle == barrierAngle) and (playerDist > barrierDist)

因此,如果玩家和敌人与敌人的角度相等,那么它们就在同一条线上。如果敌人离玩家更远,而不是来自街垒,那么玩家就会在敌人后面的路障后面。

编辑:实际上,只有从敌人到障碍物的线与从敌人到玩家的线完全相等时,这才有效。这可能需要编辑以考虑障碍的范围。