2D Schüsse Richtung COS#(),SIN#()
Übersicht

pinochinoBetreff: 2D Schüsse Richtung COS#(),SIN#() |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
TrockenÜbung für einen 2D Shooter!
Problem liegt derzeit bei den Schüssen, sie werden erstellt und Bewegt nur nie Korrekt. Aus dem Letzten BPS Habe ich die WegPunkt berechnung "gelernt" (x2-x1 / Schritte ,y2-y1 / Schritte). Diese ist nur nicht ganz anwendbar bei meinem Vorhaben. Es gibt ein Fadenkreuz und eine Spielfigur, alle Schüsse gehen von der Figur aus und sollen sich Richtung Fadenkreuz bewegen. Leider klappt das nicht So richtig. Hier ist mein TestCode! BlitzBasic: [AUSKLAPPEN] Const xmax=800, ymax=600, KEY_ESC=1 Der sollte "recht" Übersichtlich sein! ![]() Also wie berechne ich die Richtung für die Schüsse? Denke seit einigen Stunden darüber nach, warscheinlich ist die Lösung ganz simpel! ![]() lg pinO |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es gibt zwei Varianten: Du speicherst Richtung(Winkel) und Geschwindigkeit und benutzt Sin/Cos oder du speicherst X- und Y-Geschwindigkeit und addierst die zu den Koordinaten.
In jedem Fall musst du diese Infos im Type unterbringen, das "SaveMouseX" bringt nichts für mehrere Schüsse. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kommt drauf an welches mathematische Niveau du anlegst, aber so schwer ist es nicht. Vorallem wenn dir Vektoren einbegriff sind.
Ich nehme an du hast ein Start und ein Zielpunkt oder? Damit der Schuss vernünftig fliegt brauchen wir also eine normierte Länge, damit er in alle Richtungen gleichschnell ist. 1.) Es gilt hier der Satz des Pythagoras a^2+b^2=c^2. Nehmen wir für a den x - Abstand von Ziel und Start und für b den y - Abstand, dann ist c die tatsächliche Strecke wenn "direkt" gefolgen wird. Damit haben wir schon mal die Länge der Strecke bestimmt. 2.) Wir müssen den Anteil der X/Y Bewegung herausfinden, also normieren. Dazu teilst du die X bzw. Y Distanz durch durch die vorher ermittelte Länge. Da die Länge >= X,Y bekommst du also immer eine Zahl < 1. 3.) Als Letztes legst du noch die Geschwindigkeit fest. Dazu nimmst du Geschwindigkeit * X Anteil (bzw Y) und addierst das auf den urspünglichen Wert der Koordinate. Als Code ungefähr so Dabei ist s\x die X Koordinate des Starts und zx das ziel BlitzBasic: [AUSKLAPPEN] vx# = (sx - zx) * -1 |
||
Don't only practice your art,
but force your way into its secrets, for it and knowledge can raise human to divine |
pinochino |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zitat: Ich nehme an du hast ein Start und ein Zielpunkt oder?
Der Startpunkt liegt beim Spieler (BX,BY)! Der Zielpunkt wäre das Fadenkreuz (MouseX(),MouseY())! Das Fadenkreuz (mx,my) soll aber nur die Richtung vorgeben, der Schuss soll nicht am Zielpunkt 'kleben' bleiben! Sonst wäre die Berechnung ja einfach 'tp\x=tp\x+((mx-bx) / Schritte)' |
||
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
ich würd den Schusswinkel einfach mit atan2 bestimmen. Hier mal ein Beispielcode (Einzelschuesse mit rechter Maustaste, Dauerfeuer mit linker Maustaste) Code: [AUSKLAPPEN] Graphics 800,600,16,2
SetBuffer BackBuffer() SeedRnd MilliSecs() Local timer%=CreateTimer(60) Local player_X%=400 ; spieler x koordinate Local player_Y%=300 ; spieler y koordinate Local shots%=0 Local bulletspeed#=3.0 ; schussgeschwindigkeit Type shot Field X# Field Y# Field angle# End Type Global s.shot Repeat Color 255,0,0 Oval player_X,player_Y,10,10,1 Color 255,255,255 Oval MouseX(),MouseY(),10,10,1 If MouseDown(1) Or MouseHit(2) shots=shots+1 s.shot = New shot s\angle=ATan2(MouseY()-300,MouseX()-400) ; winkel spieler-maus s\X=400:s\Y=300 ; startkoordinaten schuss EndIf For s.shot = Each shot s\X=s\X+Cos(s\angle)*bulletspeed ; bewegung in x richtung s\Y=s\Y+Sin(s\angle)*bulletspeed ; bewegung in y richtung Oval s\X,s\Y,5,5,1 If s\X>800 Or s\X<0 Or s\Y>600 Or s\Y<0 Then Delete s.shot : shots=shots-1 ; schuss loeschen wenn ausserhalb screen Next Text 0,0,shots WaitTimer timer Flip 0 Cls Until KeyHit(1) End L8er, PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@pinochino
für die Schussberechnung ist weder SIN/COS notwendig, noch ATAN2! Es geht so, wie Ana schreibt. Mit Vektoren! Jetzt aber nicht erschrecken, das hört sich schwierig an, isses aber nicht. Du hast es auch schon verstanden, denn Dein Satz hier... Zitat: ...Sonst wäre die Berechnung ja einfach 'tp\x=tp\x+((mx-bx) / Schritte)...
..ist bereits die Lösung! Doch! So einfach ist es! Damit wird es funktionieren! Und die Kugel bleibt auch nicht stehen, wenn Du immer brav weiteraddierst... Vektoren: Wenn sich eine Kugel in eine bestimmte Richtung vorwärtsbewegt, dann legt sie jede 1/60sec die gleiche Strecke L zurück. Diese Strecke kann man über Winkel und Länge beschreiben aber des geht auch über ihren x- und y-Anteil. So wie die Strecke L während des Fluges pro 1/60sec gleich bleibt, so bleiben auch die x- und y-Anteile immer gleich. Du kommst also vom Startpunkt zum nächsten Kugelpunkt, wenn Du in die richtige Richtung L vorwärts gehst, aber eben auch, wenn du stattdessen in 2 schritten erst x dann y vorwärts gehst. Dieser x/y-Umweg... das nennt man einen Vektor. Seine beiden Kompontenten sind VektorX und VektorY Ist der Vektor erst einmal berechnet, so ist er völlig losgelöst vom Ziel. Er beschreibt ja nur noch was ab nun jede 1/60 sec mit der Kugel geschehen wird. Sie wird damit auch über das Ziel hinaus weiterfliegen. Ana's Berechnungen auf Deinen Code angewendet: BlitzBasic: [AUSKLAPPEN]
Durch den Trick mit dem Berechnen der Schritte mittels Pythagoras wird der Vektor in viele kleine Einzelschritte zerlegt. Mit Pythagoras ergibt sich für Schritte immer genau der Abstand zwischen Fadenkreuz und Spieler. Dank des Teilens durch Schritte dauert es genau Schritte mal, bis die Kugel beim Fadenkreuz ist! Beispiel. Das Fadenkreuz ist 11m weg. Dann wäre Schritte=11 und die Kugel würde 11 Einheiten brauchen um bis zum Fadenkreuz zu kommen. Ist das Fadenkreuz nun 22m weit weg, würde es 22 Einheiten dauern bis die Kugel dort wäre. Man sieht hier, dass die Kugel so für die doppelte Strecke die doppelte Zeit benötigt. Durch diesen Trick wird also erreicht, dass die Kugel konstant schnell fliegt. Diesen Trick nennt man "normalisieren" oder was man auch oft liest "auf 1 bringen". Jeder Teilflug ist genau 1m lang. Dein KugelTyp benötigt also zwei weitere Fields VektorX# und VektorY# BlitzBasic: [AUSKLAPPEN]
Beim Abfeuern passiert das: BlitzBasic: [AUSKLAPPEN] If MouseHit(1) Then Beim Kugelflug passiert das: BlitzBasic: [AUSKLAPPEN] For tp.Schuss = Each Schuss Die tp\Speed kannst du entweder gleich in die Berechnung des tp\Vektor... miteinbauen: BlitzBasic: [AUSKLAPPEN] tp\VektorX = DiffX / L / 10 oder erst im Flug verwenden: BlitzBasic: [AUSKLAPPEN] tp\x = tp\x + tp\VektorX * tp\Speed Ein Fehler in Deinem Gedanken Ich konnte nur einen Fehler in deinem Gedanken... Zitat: ...Sonst wäre die Berechnung ja einfach 'tp\x=tp\x+((mx-bx) / Schritte)...
...finden: Die Berechnung ist logisch richtig. Allerdings solltest Du (mx-bx) nicht mehr während des Fluges neu berechnen, sondern beim Abfeuern sofort berechnen und in einer Variablen festhalten. Denn später während des Fluges könnten sich die Position des Spielers und die des Fadenkreuzes ja ändern. Die Folge wäre, die Kugelberechnung einer bereits abgefeuerten Kugel würden mit anderen BX und MX erfolgen. Die Kugel würde "abbiegen". |
||
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
Midimaster hat Folgendes geschrieben: für die Schussberechnung ist weder SIN/COS notwendig, noch ATAN2! Stimmt. Find ich halt am einfachsten. Und vor allem am Übersichtlichsten. Ist aber Geschmackssache. Midimaster hat Folgendes geschrieben: Es geht so, wie Ana schreibt. Mit Vektoren! Jetzt aber nicht erschrecken, das hört sich schwierig an, isses aber nicht. Es geht so, wie es für denjenigen der's coded am einfachsten und verständlichsten ist ^^ Und mit sin/cos/tan zu arbeiten ist nicht schwerer als mit Vektoren. Ganz abgesehen davon sollte man sich beim coden mit Vektoren UND Winkeln auskennen. Kann man sich nicht frueh genug aneignen. Versuch am besten, beide Loesungsansaetze zu verstehen, und such Dir den fuer Dein Vorhaben Passenden aus. L8er, PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
PSY hat Folgendes geschrieben: Ganz abgesehen davon sollte man sich beim coden mit Vektoren UND Winkeln auskennen. Kann man sich nicht frueh genug aneignen.
Ohje, ja dem muss ich zustimmen. Sin/Cos war nie groß ein Thema für mich, aber hui (pfui,spuck!) war das ein Krampf, mal etwas wissen über Vektoren zu kriegen. Leider sind Vektoren immer so kompliziert dargestellt, Wikipedia hat mir den eindruckt verschafft, es wäre was kompliziertes. Und wieder eine Zustimmung: Ich bevorzuge auch Sin/Cos und evtl Atan2 ![]() Aber grade bei schüssen und einer schön Actionreichen schlacht wäre es zu schade, wenn wertvolle FPS durch massives gebrauchen von Sin/Cos/Atan2 verloren gehen. Naja, soviel kann das nicht ausmachen, aber ein umstieg auf Vektoren wäre mir das dann doch wert ![]() Immerhin wurden nun beide wege beschrieben ![]() Eine kleinere anmerkung noch zu Sin/Cos/Atan2 (aber nehm dann doch lieber Vektoren - sind ganz einfache dinger.. ansonsten: Nachfragen ![]() ATan2 bestimmt den Winkel zwischen Zwei Koordinaten. Code: [AUSKLAPPEN] ATan2 ( mausY, mausX )
würde zb den winkel von 0,0 zu MausX/MausY bestimmen. Merke: Y wird als erster parameter übergeben. (zumindest in Blitzmax - korrigiert mich, falls es hier anders sein sollte!) Code: [AUSKLAPPEN] ATan2 ( MausY - SpielerY, MausX - SpielerX )
würde den winkel zwischen Spieler und Mausposition berechnen. Ergo auch den Start-flugwinkel des geschosses. Code: [AUSKLAPPEN] Sin( winkel )
Gibt dir einen Y-faktor für einen Winkel - was Sin eigentlich ist, kannst du zb auf Wikipedia nachlesen ![]() Diesen Y-Faktor können wir nun mit unserer Schusskraft Multiplizieren. Code: [AUSKLAPPEN] Cos ( winkel )
Gibt dir einen X-faktor für einen Winkel - Cos kann ebenfalls auf Wiki gefunden werden^^ Wenn wir das nun also haben, machen wir im Prinzip folgendes (stichwortartig, keine ahnung von BB spezifischer syntax!) Code: [AUSKLAPPEN] - Schuss wird abgefeuert -> Winkel bestimmen und halten (ATan2 !) - Schuss kriegt ein updaten -> - Schuss/x = Schuss/x + ( Schusskraft * Cos( Schuss/Winkel )) - Schuss/y = Schuss/y + ( Schusskraft * Sin( Schuss/Winkel )) Mehr nicht ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group