Scripte - so oder besser anders?
Übersicht BlitzMax, BlitzMax NG Beginners-Corner
M0rgensternBetreff: Scripte - so oder besser anders? |
Di, Mai 03, 2011 23:25 Antworten mit Zitat |
|
---|---|---|
Hallo Leute,
Ich habe eine Frage, die vielleicht ein wenig seltsam anmutet. Ich bin dabei einen Shooter zu schreiben, mit vertikalem Scrolling. Das ganze soll also ein bisschen Retro sein (ich weiß im Moment leider kein Beispiel). Jedenfalls kann ich mich entsinnen, dass die Gegner immer irgendwielche Muster geflogen sind. Da ich aber nicht jedes Muster im Code eigens anlegen wollte, habe ich mir überlegt eine kleine Scriptsprache für die Muster zu schreiben. Leider habe ich mich damit noch nie beschäftigt und wusste daher anfangs nicht wie ich es machen soll. Ich habe jetzt mal ein Programm geschrieben, das so funktioniert, wie ich möchte. Meine Frage ist jetzt, ob die Lösung in Ordnung ist, also ob das allgemein so ungefähr gemacht wird oder ob meine Lösung eher ungünstig ist. Wäre wirklich super, wenn sich das jemand mal anschauen würde und mir Rückmeldung geben könnte, da ich mir wirklich unsicher bin. Ich habe meinen Code komplett kommentiert, ihr könnt mich aber auch noch genau fragen, wenn Stellen unklar sein sollten. Hier ist der Code: BlitzMax: [AUSKLAPPEN] Type TEnemy 'Gegnerklasse Und so sieht ein Script zum Beispiel aus: Zitat: /S
L:20 F:10 B:40 R:30 /E Lg, M0rgenstern |
||
XeresModerator |
Di, Mai 03, 2011 23:52 Antworten mit Zitat |
|
---|---|---|
Genaue Definitionen habe ich nicht im Kopf, aber es sieht mir auf den ersten Blick wie eine Dateiformat mit relativ komplizierter Lade-Routine aus.
Ein Simpel zu lesendes Format (für Mensch & Maschine) wäre z.B. XML, eine echte Skriptsprache ist mit Lua direkt eingebaut. Mit dieser Lösung sehe ich aber auch kein Problem, ganz ähnlich habe ich auch schon Level gespeichert. Was du genau verwendest, hängt eigentlich von deinem Geschmack ab - und wie leicht es sich in zukünftigen Projekten wiederverwenden lässt. |
||
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) |
BladeRunnerModerator |
Mi, Mai 04, 2011 8:43 Antworten mit Zitat |
|
---|---|---|
Du musst Dir nur eine einfache Frage beantworten: erfüllt es seinen Zweck, also deine damit verbundenen Erwartungen? Wenn ja: go for it. Wenn nein: machs neu, Sam! | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Midimaster |
Mi, Mai 04, 2011 9:22 Antworten mit Zitat |
|
---|---|---|
Ein Problem könnte werden, dass den verschiedenen Mustern eine Art "Unterscheidungsmerkmal" fehlt. So etwas wie eine Name oder eine Überschrift. Das Modell der INI-Dateien sieht hier vor, dass es noch Überschriften gibt:
Zitat: [Muster 1]
L=20 F=10 B=40 R=30 [Muster 2] L=20 F=10 B=40 R=30 [Ende] Somit könnten verschiedenste Gegner die Daten aus der gleichen INI-Datei holen: Zitat: [Alien-Muster 1]
L=20 F=10 B=40 R=30 [Alien-Muster 2] L=20 F=15 B=45 R=22 [Monster-Muster 1] L=2 F=1 B=4 R=3 [Monster-Muster 2] L=6 F=5 B=4 R=3 [Ende] |
||
M0rgenstern |
Mi, Mai 04, 2011 10:06 Antworten mit Zitat |
|
---|---|---|
@BladeRunner: Bisher erfüllt es seinen Zweck, also werd ich es mal so stehen lassen.
@Minimaster: Es ist auch eigentlich so gedacht, dass alle Muster in einer Datei stehen. Das Programm weiß wo ein SCript aufhört und wo eines anfängt und ich habe mir überlegt die Muster in der Datei nach Schwierigkeitsgraden zu ordnen, so, dass die Muster die als letzte in den Speicher geladen werden auch für die schwersten Gegner gelten, so dass ich immer nur Gegner.Level SChritte in die Lister laufen muss um ein entsprechendes Muster zu finden. Aber deine Lösung wäre eigentlich besser und relativ schnell eingebaut. Mein Problem ist im Moment mit der ganzen Sache einfach: Wenn ich die "Sprache" erweitere und Dinge wie Verknüpfungen etc mit reinbringe (also Vorwärts UND Links), dann weiß ich nicht wie vorteilhaft select case in diesem Fall wäre. Also, ob ich da einfach nen riesiegen Select-Case Block stehen haben soll oder ob man das anders lösen könnte. Lg, M0rgenstern |
||
BladeRunnerModerator |
Mi, Mai 04, 2011 10:36 Antworten mit Zitat |
|
---|---|---|
im Endeffekt ist ein Compiler / Interpreter nichts anderes als ein sich selbst fütternder endlicher Automat ( http://de.wikipedia.org/wiki/Endlicher_Automat ), und genau das kannst Du mit select-case schön realisieren.
Es wird halt je flexibler Du das gestalten willst immer komplexer, aber das liegt in der Natur der Sache. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Midimaster |
Mi, Mai 04, 2011 19:25 Antworten mit Zitat |
|
---|---|---|
aha, erst jetzt verstehe ich deine Abkürzungen R L B F.
bedeutet... Zitat: /S
L:20 F:10 B:40 R:30 /E ..., dass erst 20 schritte nach links, dann 10 nach vorne, dann 40 zurück und dann wieder 30 nach rechts gelaufen werden? Dann wäre ja auch längere Ketten denkbar, oder, z.b. Zitat: /S
L:20 F:10 B:40 F:10 R:30 F:10 /E Brächte es etwas, das Ganze auch um Diagonalen zu erweitern? Code: [AUSKLAPPEN] A B C
| D - X - F | G H I Zitat: /S
H:1 A:1 B:2 I:1 D:5 X:8 /E So könnten Sie sogar 8 Sekunden stehenbleiben. Oder du könntest gleich immer pro Buchstabe nur 1 Schritt beschreiben: "HABBIDDDDDXXXXX" so erhältst du sehr komplexe Bewegungen. |
||
M0rgenstern |
Mi, Mai 04, 2011 19:41 Antworten mit Zitat |
|
---|---|---|
Genau Midimaster, das ist der Sinn der Sache.
Ja, es können beliebig lange Ketten gebildet werden. Und ja, diagonale Bewegung ist nun möglich, da ich einen Befehl, oder besser eine Verknüpfung eingebaut habe. Die sieht dann so aus: Zitat: (L AND B):20
Damit würde man nach links oben, also diagonal 20 Ausführungen lang laufen. Natürlich wird bei der Ausführung des Scripts eine Anweisung übersprungen, die zwei entgegengesetzte Richtungen verknüpft. Stimmt, einfach stehen zu bleiben habe ich noch gar nicht beachtet, das wäre noch eine interessante Sache. Die Zahlen sind nicht direkt Schritte, sondern diese Zahlen geben an, wie oft diese Zeile ausgeführt werden soll. Lg, M0rgenstern |
||
ToeB |
Mi, Mai 04, 2011 20:16 Antworten mit Zitat |
|
---|---|---|
Aber was ist wenn du sie schöne Formvollendete Kurven fliegen lassen möchtest ? würde ich mir auch noch überlegen, einen "Befehl" dafür zu schreiben, wie
Code: [AUSKLAPPEN] TURN(-30;0):90
Würde heißen, das der Bezugspunkt bzw. Kreismittelpunkt der Drehung bei X-30 und Y+0 liegt (also relative Angabe). 90 heißt, er soll sich um 90° wenden. Oder so ähnlich. Würde auf jeden Fall ne Menge Script-Code sparen und auch schön ausehen ! mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
M0rgenstern |
Do, Mai 05, 2011 12:12 Antworten mit Zitat |
|
---|---|---|
Hey ToeB:
An Kreise etc habe ich auch schon gedacht. Meine Überlegung ist momentan dazu einfach Sin als Scriptbefehl mit reinzupacken. Lg, M0rgenstern |
||
kriD |
Do, Mai 05, 2011 17:44 Antworten mit Zitat |
|
---|---|---|
Ich denke, das der Vorschlag von Toeb am besten das beinhaltet, was du suchst.
Du kannst denn eine kurven flieg Funktion, eine gerade bewegungs funktion und was du sonst noch brauchst (teleportieren etc. blabla, da sind dir denn ja keine Grenzen gesetzt) machen. In der Ini schreibst du dann einfach nur die Funktionen mit den Parametern nacheinander weg und hast dadurch deine zeitliche Abfolge. lg kriD |
||
Wenn ich du wäre, wäre ich lieber ich! |
M0rgenstern |
Fr, Mai 06, 2011 15:00 Antworten mit Zitat |
|
---|---|---|
Hey kriD, ich glaube du hast Recht.
Ich werd das ganze wohl ein wenig umschreiben. Lg, M0rgenstern |
||
M0rgenstern |
Fr, Mai 06, 2011 18:50 Antworten mit Zitat |
|
---|---|---|
Sorry für Doppelpost, aber es hat sich ein Problem ergeben:
Zitat: Aber was ist wenn du sie schöne Formvollendete Kurven fliegen lassen möchtest ? würde ich mir auch noch überlegen, einen "Befehl" dafür zu schreiben, wie
Code: TURN(-30;0):90 Würde heißen, das der Bezugspunkt bzw. Kreismittelpunkt der Drehung bei X-30 und Y+0 liegt (also relative Angabe). 90 heißt, er soll sich um 90° wenden. Oder so ähnlich. Würde auf jeden Fall ne Menge Script-Code sparen und auch schön ausehen ! Könnte mir bitte jemand erklären, wie man sowas in Code umsetzen könnte? Also, das mit den relativen Angaben und der Kreisbewegung um diese Angaben? Wäre wirklich super, komme nämlich nicht weiter. Lg, M0rgenstern |
||
mpmxyz |
Fr, Mai 06, 2011 19:15 Antworten mit Zitat |
|
---|---|---|
Ich würde es zunächst einmal so machen:
1. Bestimme die absoluten Koordinaten des Drehpunktes. Je nachdem, wie du es haben möchtest, musst du die relativen Koordinaten um den Ausrichtungswinkel des Objektes drehen und auf die Objektposition hinzuaddieren. 2. Ziehe die absolute Position des Drehpunktes von der Objektposition ab. 3. Drehe diese zum Drehpunkt relative Position mit dem im Script bestimmten Winkel um den (relativen) Ursprung. 4. Addiere die Drehpunktposition wieder auf die Objektposition. Man kann das Ganze aber noch ein wenig vereinfachen. Code: [AUSKLAPPEN] Pabs: absolute Position des Objektes
ROTcur: Rotationsmatrix zum Objekt Drel: die relative Position des Drehpunktes Mrot: Rotationsmatrix zur jetzt stattfindenen Drehung des Objektes PabsNeu: neue Position 1. Dabs=Pabs+ROTcur*Drel 2. Prel=Pabs-Dabs=-ROTcur*Drel '<-Vereinfachung der Berechnung 3. PrelNeu=Mrot*Prel 4. PabsNeu=PrelNeu+Dabs (Kurzzusammenfassung: Schritt 2 wird zu: "Die Objektposition wird auf die negierte und gedrehte, relative Drehpunktposition gesetzt." <- Großer Name!) Kannst du mit linearer Algebra umgehen? (Rotationsmatrizen erzeugen, Vektoren und Matrizen multiplizieren und Vektoren addieren) Ich liefere ansonsten gerne noch etwas Code nach. mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
ToeB |
Fr, Mai 06, 2011 19:22 Antworten mit Zitat |
|
---|---|---|
Also mit den Bezugs-Punkt musst du vor dem Drehen Abspeichern (Variablen), da sich ja die Position des Gegners beim Drehen verändert. Also So :
Code: [AUSKLAPPEN] Bezugspunkt_X = GegnerX + Script_Parameter_X
Bezugspunkt_Y = GegnerY + Script_Parameter_Y Dann rechnest du den Radius und den Winkel dazu aus, geht mit BlitzBasic: [AUSKLAPPEN] Winkel = ATan2( Script_Parameter_Y, Script_Parameter_X ) Wenn du das Hast, setzt du eine Turn-Variable auf True, sodass das Programm jetzt weis das der Gegner sich jetzt drehen kann. Jetzt musst du nur noch pro Schritt (hinter dem ":") einmal den Winkel hochzählen, in dem Fall von 1 bis 90. Dann Positionierst du den Gegner von dem Abgespeicherten Bezugspunkt aus in dem Winkel (Sin ´/ Cos ) BlitzBasic: [AUSKLAPPEN] GegnerX = BezugspunktX + Cos( Winkel + WinkelSchrittZahl ) * Radius Damit kannst du Beliebige Drehungen, mit beliebingen Radien und Winkel etc. Problemlos mit dieser kleinen Zeile darstellen. mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
M0rgenstern |
Fr, Mai 06, 2011 22:47 Antworten mit Zitat |
|
---|---|---|
@ToeB:
Bei deiner Möglichkeit erhalte ich irgendwie nur eine Bewegung auf einer Geraden. Wenn ich den Bezugspunkt vor jeder Bewegung festlege ist es eine Gerade, wenn ich den Bezugspunkt ganz am Anfang festlege und dann nie mehr ändere, dann bewegt es sichgar nicht. @mpmxyz: Also, lineare Algebra ist bei mir der Oberstufenstoff. Ich kann mit Vektoren, Ebenen, Geraden umgehen, aber leider nicht mit Matrizen, wobei das hier ja ein zweidimensionales Array sein müste oder? Kurz: Es wäre wirklich nett, wenn du ein wenig mehr Infos liefern würdest. |
||
ToeB |
Fr, Mai 06, 2011 23:24 Antworten mit Zitat |
|
---|---|---|
Ja also, du gibst ja z.B. an er soll 90° drehen, also 90 mal 1° drehen.
Hier die Position des Gegners (Schwarz), die Relative Position des Bezugspunktes (Rot) und die Absolute Position des Punktes (DunkelRot). Zu diesem Punkt muss jetzt vor dem erstmaligen Bewegen der Winkel und der Abstand ausgerechnet werden, damit dieser Übernommen werden kann. Dann Musst du nur noch beim Drehen den Gegner im ausgerechneten Abstand un Winkel mit Sin&Cos + den Schritt-Winkel (1-90). Also in dem Fall wäre der winkel 0° (vom Bezugspunkt zum Gegner). So wie ich es dir geschrieben habe, sollte es klappen sofern du es auch sinngemäß deinem Programm angepasst hast (ist ja nur pseudocode). mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
mpmxyz |
Sa, Mai 07, 2011 13:08 Antworten mit Zitat |
|
---|---|---|
(Wenn dich nur die fertige Formel für den um den Uhrsprung gedrehten Vektor interessiert, sieh dir die fette Formel an!)
Zuerst einmal zur Drehmatrix: Diese ist so aufgebaut: Zitat: (Cos(w) -Sin(w))
(Sin(w) Cos(w)) Wenn man diese Drehmatrix mit einem Vektor multipliziert, wird dieser Vektor um den Ursprung gedreht. (um den Winkel w im Uhrzeigersinn) Der Spezialfall für w=0 ist die so genannte Einheitsmatrix, welche keine Veränderung bewirkt: Zitat: (1 0)
(0 1) Zitat: (1 0)*(0 1)=(? ?)
(0 2)_(1 2)_(? ?) Die Multiplikation von Matrizen findet allgemein so statt: 1. Man wählt eine Zeile der ersten Matrix und eine Spalte der zweiten Matrix. Zusammen ergeben diese Positionen den berechneten Eintrag in der neuen Matrix. Zitat: (1 0)*(0 1)=(? ?)
(0 2)_(1 2)_(? ?) 2. Nun geht man bei der ersten Matrix Schritt für Schritt jeden Eintrag in der ausgewählten Zeile durch und multipliziert diesen mit dem dazugehörigen Eintrag der ausgewählten Spalte der zweiten Matrix. Die Ergebnisse werden addiert. Zitat: (1 0)*(0 1)=(1*0+0*1 ?)
(0 2)_(1 2)_(? ______ ?) 3. So werden auch die anderen Felder der neuen Matrix berechnet. Zitat: (1 0)*(0 1)=(1*0+0*1 1*1+0*2)=(0 1)
(0 2)_(1 2)_(0*0+2*1 0*1+2*2)_ (2 4) In diesem Fall ist der Vektor eine 2x1-Matrix: Zitat: (xNeu)=(+Cos(w) -Sin(w))*(x)=(Cos(w)*x-Sin(w)*y)
(yNeu)_(+Sin(w) +Cos(w)) (y)_(Sin(w)*x+Cos(w)*y) Nun musst du nur noch diese Formel in das Programm einarbeiten:Code: [AUSKLAPPEN] Pabs: absolute Position des Objektes
ROTcur: Rotationsmatrix zum Objekt Drel: die relative Position des Drehpunktes Mrot: Rotationsmatrix zur jetzt stattfindenen Drehung des Objektes PabsNeu: neue Position 1. Dabs=Pabs+ROTcur*Drel 'Dabs: Absolute Position des Drehpunktes 2. Prel=Pabs-Dabs=-ROTcur*Drel 'Prel: relative Position des Objektes zum Drehpunkt (ohne Drehung) 3. PrelNeu=Mrot*Prel 'PrelNeu: die relative Position des Objektes nach der Drehung 4. PabsNeu=PrelNeu+Dabs Wenn du den Vektor (ROTcur*Drel) zwischenspeicherst, brauchst du die Matrixmultiplikation dabei nur zweimal anzuwenden. mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
M0rgenstern |
Sa, Mai 07, 2011 16:12 Antworten mit Zitat |
|
---|---|---|
Hey.
Ich habe jetzt beide Versionen ausprobiert, bzw. versucht. Zu mpmxyz: Sorry, aber ich komm mit der Rechnerei da irgendwie nicht richtig klar. Also damit bin ich nicht weiter gekommen. Zu ToeB: Dein Vorschlag hat prinzipiell funktioniert, aber jedesmal wenn er eine neue Kurve begonnen hat, ist er ein paar Pixel gesprungen, was irgendwie sehr seltsam war. Der Code dazu sieht so aus: BlitzMax: [AUSKLAPPEN] If bTurning Then Es sieht fast aus, als würde er zu dem Bezugspunkt springen und dann erst die Kurve fliegen. Habe ich vielleicht irgendwas falsch umgesetzt? Ich habe auch noch etwas anderes ausprobiert, aber da habe ich einfach das Problem, dass ich die Geschwindigkeit viel zu hoch ist. Und je größer der Abstand zum Bezugspunkt ist, umso größer desto größer ist auch die Geschwindigkeit (blöde Bahngeschwindigkeit eben). Lg, M0rgenstern |
||
mpmxyz |
Sa, Mai 07, 2011 17:23 Antworten mit Zitat |
|
---|---|---|
Ich habe meinen Ansatz nun in Code umgesetzt.
Die Position des Punktes ist hier aber absolut gegeben. BlitzMax: [AUSKLAPPEN] SuperStrict mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
Übersicht BlitzMax, BlitzMax NG Beginners-Corner
Powered by phpBB © 2001 - 2006, phpBB Group