AW: Grundlage eines sich drehenden und schießendes Towers
Hi JestaBlunt,
Nun ja, prinzipiell ist die Berechnung einfach. Um nachher nicht zusätzlich 90 Grad addieren zu müssen, sorge dafür, daß Turm und Geschoß am Anfang nach rechts zeigen. Der Grund liegt im Einheitskreis, auf den sich die trigonometrischen Funktionen beziehen: eine Drehung nach rechts entspricht einer Drehung von 0 Grad. Wenn also die grafischen Elemente innerhalb Deiner MCs nach rechts zeigen, haben sie eine Drehung von 0 Grad. Bei allen anderen Drehungen muß der abweichende Wert zusätzlich berücksichtigt werden (ist in Deinem Skript z.B. der Fall).
Wenn der Turm mehr als ein Rohr enthält, muß zusätzlich zur Drehung des Turmes auch die Drehung der Rohre relativ zum Turm berücksichtigt werden, um die Geschosse exakt an der Mündung positionieren zu können. Das geht zum Glück ebenfalls ziemlich einfach, da sich die Rohre relativ zum Turm nie anders positionieren, die entsprechende Drehung muß also nur einmal ermittelt werden. In meinem Beispiel gehe ich davon aus, daß sich der RegPunkt im Rohr aus Gründen der Vereinfachung an der Mündung befindet.
Anbei Beispielcode (sorry, sehr unsauber, soll nur die prinzipielle Funktionsweise demonstrieren), der in die Hauptzeitleiste gehört (daraus sollte man dann in einer realen App zumindest eine Dokumentklasse machen, korrekter wäre z.B. eine Klasse Tower, in der alles drin ist und die über die DokKlasse instanziiert wird). Der mc gun enthält zwei Rohre (barrel1 und barrel2), die relativ zum RegPunkt von gun den gleichen Abstand einhalten, lediglich vertikal versetzt, so daß sie parallel angeordnet sind. Die Berechnung ihres Winkels ist hier vereinfacht angegeben (var barrelAngle). Formal korrekter wäre die Berechnung des Winkels für beide Rohre, so daß sie innerhalb des mcs gun beliebig positioniert werden können. Das würde einfach über eine zweite var geschehen, die von den entsprechenden Werten für battel ausgehen würde. Um die Geschosse korrekt einzufügen, muß lediglich zum Drehwinkel des Turmes noch der betreffende Winkel der Rohre innerhalb des Turmes addiert werden (bzw einmal barrelAngle und einmal -barrelAngle).
PHP:
var bullets:Array = [];
var bulletHolder:Sprite = new Sprite();
var rad2grad:Number = 180 / Math.PI;
var grad2rad:Number = Math.PI / 180;
var barrelAngle:Number = Math.atan2(gun.barrel1.y,gun.barrel1.x) * rad2grad;
var speed:Number = 10;
function rotate(e:Event) {
var distX:Number = mouseX - gun.x;
var distY:Number = mouseY - gun.y;
var angle:Number = Math.atan2(distY,distX) * rad2grad;
gun.rotation = angle;
}
function moving(e:Event) {
if (bullets.length > 0) {
var index:int = bullets.length - 1;
for (var i:Number = index; i >= 0; i--) {
bullets[i].x += bullets[i].speedX;
bullets[i].y += bullets[i].speedY;
if (bullets[i].x > stage.stageWidth || bullets[i].x < 0 || bullets[i].y > stage.stageHeight || bullets[i].y < 0) {
var child:int = bullets[i].parent.getChildIndex(bullets[i]);
bullets[i].parent.removeChildAt(child);
bullets.splice(i,1);
}
}
}
}
function fire(e:MouseEvent) {
var angle:Number = gun.rotation;
var bullet:Bullet = new Bullet();
bullet.x = Math.cos((angle+barrelAngle) * grad2rad) * gun.barrel1.x+gun.x;
bullet.y = Math.sin((angle+barrelAngle) * grad2rad) * gun.barrel1.x+gun.y;
bullet.rotation = angle;
bullet.speedX = Math.cos(angle * grad2rad) * speed;
bullet.speedY = Math.sin(angle * grad2rad) * speed;
bulletHolder.addChild(bullet);
bullets.push(bullet);
bullet = new Bullet();
bullet.x = Math.cos((angle-barrelAngle) * grad2rad) * gun.barrel1.x+gun.x;
bullet.y = Math.sin((angle-barrelAngle) * grad2rad) * gun.barrel1.x+gun.y;
bullet.rotation = angle;
bullet.speedX = Math.cos(angle * grad2rad) * speed;
bullet.speedY = Math.sin(angle * grad2rad) * speed;
bulletHolder.addChild(bullet);
bullets.push(bullet);
}
addChild(bulletHolder);
stage.addEventListener(MouseEvent.MOUSE_MOVE,rotate);
stage.addEventListener(MouseEvent.CLICK,fire);
bulletHolder.addEventListener(Event.ENTER_FRAME,moving);
Nochmals: ist unsauber, müßte also optimiert werden, gibt aber hoffentlich die richtige Richtung an.
Viel Spaß