2016-07-08 5 views
0

Ich mache ein 2d Top-Down-Shooter-Spiel und im Idealfall möchte ich, dass die Gegner nur auf den Spieler schießen, wenn sie ihn sehen (damit sich der Spieler hinter einer Kiste verstecken kann etc.)Pygame Raycasting für Sichtlinie

Ich habe Forschung gemacht und ich denke, der beste Weg, dies zu tun wäre Raycasting. Ich konnte kein gutes Beispiel für Raycasting in Pygame finden.

Alternativ habe ich diesen Teil des Codes auf einer anderen Frage 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 

aber ich bin nicht sicher, ob es die Art der Sache accomplsih würde ich will und wenn es ich bin, ist, nicht sicher, wie ich es umsetzen würde.

Was ich zuerst frage ist, würde der Code, den ich verwende, erreichen, was ich tun wollte, und wenn ja, wie würde ich es implementieren und gibt es einen besseren Weg, es zu tun.

+2

Was genau fragen Sie? Ihr Beitrag ist eine Reihe von Aussagen, es gibt keine Frage. – MattDMo

+0

Erstens: Würde der von mir hinzugefügte Code funktionieren, wie würde ich ihn verwenden und ob es einen besseren Weg gibt, dies zu tun? – randomtoenailmonkey

Antwort

1

Ich nehme an, die Variablen "Spieler" und "Person" sind die Positionen des Spielers und des Gegners? Wenn ja, überprüfen Sie den Code hinzugefügt haben, wenn entweder die beiden Objekte:

  • in der gleichen x-Position sind (Person [0] == Spieler [0])
  • in der gleichen y-Position sind (Person [1] == Spieler [1])
  • haben gleiche x und y Unterschiede, dh die Objekte sind bei 45 Grad zueinander (abs (deltaX) == abs (deltaY)).

Dies scheint jedoch nicht, was Sie wollen.

Was funktionieren kann, wenn Sie überprüfen, ob:

  • der Winkel zwischen dem Feind und Hindernisse für den Winkel zwischen dem Feind und dem Spieler gleich sind. Eine Möglichkeit, dies zu tun, ist die Verwendung von tan (Winkel) = gegenüberliegend/benachbart oder deltaY/deltaX.

  • Der Feind ist weiter vom Spieler entfernt als von der Barrikade. Dies kann mit Pythagoras geschehen.

Hier ist eine Funktion dafür, die helfen könnten:

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) 

So vor dem Feind, wenn die Winkel des Spielers und Barriere gleich sind, die entlang der gleichen Linie sind. Wenn der Feind auch weiter vom Spieler entfernt ist als von der Barrikade, ist der Spieler hinter der Barrikade im Vergleich zum Feind.

EDIT: Eigentlich funktioniert das nur, wenn die Linie vom Feind zur Barriere genau gleich der Linie vom Feind zum Spieler ist. Dies muss möglicherweise bearbeitet werden, um die Reichweite der Barriere zu berücksichtigen.