2016-07-08 3 views
0

Я делаю 2-й нисходящий шутер, и в идеале я хотел бы, чтобы враги стреляли только в игрока, когда они его видели (чтобы игрок мог спрятаться за ящиком и т. Д.),Pygame Raycasting для линии видимости

Я сделал исследование, и я думаю, что лучший способ сделать это - это расование. Я не смог найти хороший пример raycasting в 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 

, но я не уверен, что если бы это accomplsih вид, что я хочу, и если это я не знаю, как я его реализую.

Что я прошу, во-первых, будет ли код, который я использую, выполнить то, что я хотел сделать, и если да, то каким образом я его реализую и есть лучший способ сделать это.

+2

Что именно вы спрашиваете? Ваш пост - это серия заявлений, нет сомнений. – MattDMo

+0

Во-первых, добавит ли код, который я добавил, как я его использую, и если есть лучший способ сделать это. – randomtoenailmonkey

ответ

1

Я принимаю переменные «игрок» и «человек» - это позиции игрока и врага? Если да, то вы добавили код проверит, либо два объекта:

  • находятся в том же положении х (человек [0] == игрок [0])
  • находятся в том же положении, у (person [1] == player [1])
  • имеют равные x и y различия, т.е. объекты находятся под углом 45 градусов друг к другу (abs (deltaX) == abs (deltaY)).

Это не похоже на то, что вы хотите.

Что может работать, если вы проверяете, если:

  • угла между врагом и барьером равен углу между противником и игроком. Один из способов сделать это - использовать tan (angle) = противоположный/смежный или deltaY/deltaX.

  • Враг находится в стороне от игрока, чем от баррикады. Это можно сделать с помощью pythagoras.

Вот функция для этого, которое могло бы помочь:

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) 

Таким образом, если углы игрока и барьера от противника, равны, то есть по той же линии. Если противник также находится дальше от игрока, чем от баррикады, игрок находится за баррикадой по сравнению с противником.

EDIT: На самом деле это будет работать, только если линия от врага до барьера точно равна линии от врага к игроку. Это может потребовать редактирования, чтобы учесть диапазон барьера.