relativer Positionswinkel im 2D-Shooter
-
Also ich bastle einen kleinen 2D-Spaceshooter Dabei muss meine Gegner-KI natürlich wissen, wo sich der Spieler befindet. Der Einfachheit halber (und wegen der vorgenerierten Bilder) habe ich bei Drehungen eine Schrittweite von 45°, entsprechend 8 verschiedene Bereiche. Oben ist dabei 0, Links oben 7.
Jetzt soll meine KI wissen, in welche Richtung sie sich drehen muss, um den Spieler vorn zu haben. Hierzu habe ich folgende Funktion zur Winkelberechnung gestrickt.
/** * calculates the direction an object is found at * @param him * @return */ public int getObjectDirection(Point him) { // Errechne eine Linie zwischen Objekt und Ziel Point line = new Point(him); Point me = getPosition(); line.offset(-me.x, -me.y); // Erstelle die Achse für die Null-Position Point zero = new Point(0, -1); // länge von zero ist 1, deshalb fällt es aus der Rechnung double len = Math.sqrt(Math.pow(line.x, 2) + Math.pow(line.y, 2)); // Errechne das Skalarprodukt der beiden Vektoren double scalar = line.x * zero.x + line.y * zero.y; // errechne den Winkel zwischen den Vektoren in ° double angle = (Math.acos(scalar / len)) * (360 / Math.PI); Log.d(getClass().getSimpleName(), " + len:" + len + ", scalar:" + scalar + ", angle:" + angle ); // errechne die relative Position return (int) ((angle + 22.5) / 45.0); }
irgendwie kommt da allerdings sehr spannendes Zeugs bei raus, aber nicht wirklich der richtige Winkel.
Hat diese Rechnung irgendwo ne Macke ooder was oder wie?
-
Kurze Frage, wie unterscheidest du links und rechts? Was macht Point::offset?
-
-
das sieht nicht wie c++ aus, wohl eher Java?
-
acos gibt nur winkel von 0 bis 180 Grad zurück -> kann gar nicht klappen. Was du versuchen solltest, ist die Funktion atan2 (welche bestimmt auch in Java vorhanden ist). Dort kannst du x und y-Offset übergeben und die Funktion gibt dir den Winkel von 00 zu dieser Position zurück.
Weiterhin ist deine Umrechnung von bogenmaß auf grad falsch, rad * 180 / PI ist richtig
-
-
var dir:Point = moveVector.clone(); dir.normalize(1.0); var rotation:Number = Math.atan2(dir.x, -dir.y) * 180 / Math.PI;
Hab ich schnell aus meinem Flash-Shooter kopiert, daher ActionScript. Sollte aber kein Problem sein, oder?