knittel - Mi 08.12.10 12:34
Titel: Winkel-Berechnung
Hallo allerseits,
Ich entwickle ein Strategie-Spiel. Dabei soll eine Einheit mehrere Waffen habe. Ich habe die Relativen Koordinaten zum Mittelpunkt (und der oberen linken Ecke). Wenn sich jetzt die Einheit dreht kommen die Schüsse immer noch von der selben position her, nicht mehr da wohin sich jetzt die Kanone gedreht hat.
Ich habe versucht dieses Problem zu lösen, aber irgendwie kommen die Schüsse jetzt nur noch zufällig irgendwoher. Könnte mir jemand helfen den Fehler zu finden?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| ListOfShots.Add(TShot.Create( (Xpos+Unitsize/2) + (cos(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse), (Ypos+Unitsize/2) - (sin(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse), (ToX / StepsNeeded),(ToY / StepsNeeded),QAngle, FWeapons[Weapon].UnitBullet, FWeapons[Weapon].ATK, OnUnit));
procedure TMilitaryUnitMultiWeapon.AlphaCalculation(); var Quotient: single; i: integer; begin for i:= 0 To FWeaponCount do begin FWeapons[i].RelX := round(FWeapons[i].RelX - Unitsize / 2); FWeapons[i].RelY := round(FWeapons[i].RelX - Unitsize / 2);
if FWeapons[i].RelY = 0 then begin if (FWeapons[i].RelX < 0) then FWeapons[i].SetAlpha:=180 else FWeapons[i].SetAlpha:=0; end else begin Quotient := FWeapons[i].RelY / FWeapons[i].RelX; if FWeapons[i].RelX < 0 then FWeapons[i].SetAlpha := round(arctan(Quotient)*180/Pi+180) else FWeapons[i].SetAlpha := round(arctan(Quotient)*180/Pi); end; FWeapons[i].Hypotenuse := sqrt((FWeapons[i].RelX * FWeapons[i].RelX) + (FWeapons[i].RelY * FWeapons[i].RelY)); end; end; |
Hier eine Erklärung der Variablen.
RelX: X Abstand vom Mittelpunkt zur Waffe
RelY: Y Abstand vom Mittelpunkt zur Waffe
Hypotenuse: Abstand zur Waffe und Radius des Kreises
Der Mittelpunkt: Xpos (Absolute Position der Einheit) + Unitsize (Einheitengröße insgeamt) / 2 (weil wir zum Mittelpunkt wollen.
SetAlpha: Der Winkel indem die Hypotenuse zur X-Achse steht.
Der Winkel unter dem sich die Einheit gedreht hat.
Den Punkt an dem der Schuss letztendlich erscheinen soll.
Wenn irgendjemand ein Problem sieht, bitte posten!
Tilo - Do 09.12.10 23:30
Irgendwie scheint der Wurm bei der Winkelberechnung drin zu sein:
Unter der Annahme das Tox und Toy Koordinatendifferenzen sind und die Weg richtung deines Fahrzeuges angeben folgendes auf leerer Form mit ein paar Labels in der Mitte folgendes in das OnMouseMove gesetzt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var Quotient: Real; ToX: Integer; ToY: Integer;
begin ToX:=x-Label1.Left; ToY:=Y-label1.Top; if ToX = 0 then begin if (ToY < 0) then QAngle:=180 else QAngle:=0; end else begin Quotient := ToY / ToX; if ToX < 0 then QAngle := round(arctan(Quotient)*180/Pi+180) else QAngle := round(arctan(Quotient)*180/Pi);
QAngle := QAngle + 180; end;
Label1.Caption:= Floattostr( QAngle); Label5.Caption:=inttostr(Tox); label6.Caption:=inttostr(ToY); end; |
Schiebe ich die Maus nach rechts steigt Tox,
Schiebe ich die Maus nach unten steigt Toy.
Irgenwie bekomme ich nun in der oberen Linken Ecke Werte um 400 und oberen rechts nie unter 90.
Ändere ich "QAngle := QAngle + 180;" auf "QAngle := QAngle + 90;" erhalte ich ein schönen Vollkreis mit 0° Oben und dann im Uhrzeigersinn steigend.
Vielleicht liegt dein Problem ja hier drin, oder ich hab bei meinen Beispiel das Koordiatensystem verbogen.
Ich denke letzteres dürfte der Fall sein. Ich denke dein Fehler liegt bei den Koordinatenberechnungen. Versuche mal statt
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| ListOfShots.Add(TShot.Create( (Xpos+Unitsize/2) + FWeapons[Weapon].RelX (cos(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse), (Ypos+Unitsize/2) + FWeapons[Weapon].RelY (sin(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse), (ToX / StepsNeeded),(ToY / StepsNeeded),QAngle, FWeapons[Weapon].UnitBullet, FWeapons[Weapon].ATK, OnUnit)); |
lieber dass hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| NewRelX:=(cos(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse) NewRelY:=(sin(FWeapons[Weapon].SetAlpha + QAngle) * FWeapons[Weapon].Hypotenuse) ListOfShots.Add(TShot.Create( (Xpos+Unitsize/2) + NewRelX, (Ypos+Unitsize/2) + NewRelY, (ToX / StepsNeeded),(ToY / StepsNeeded),QAngle, FWeapons[Weapon].UnitBullet, FWeapons[Weapon].ATK, OnUnit)); |
Begründung:
Die Alten Relativen Koordinaten X und Y stecken in Hypotenuse und altem Winkel. Du brauchst aber die neuen Relativen Koordinaten.
Um weiteren Fehlersuche lass dir doch mal die berechnten Koordinaten ausgeben, z.B. farbige Kreise dort setzten wo die Waffen sein sollten und dann gucken ob die Kreise sich mit dem Fahrezug korrekt mitbewegen.
1. Schritt: Fahrzeug horizontal und vertikal verschieben -> nicht drehen. Folgenden die Kreise korrekt ist die Mittelpunktberechnung korrekt.
2. Schritt Fahrzeug nur drehen -> Bewegung der Kreise korrekt -> Relativ koordinaten korrekt berechnet.
Noch ein kleiner Hinweis: Du hast Die doppelten Code. Für jeden Waffentyp berechnest du die Parameter separat.
Besser sind hier Zwischenvariablen vor der Case-Anweisung. Vorteil: Sollte in den Parameterberechnungen ein Fehler sein muss dieser nur an einer Stelle behoben werden.
Ich hoffe ich konnte helfen.