Von Multitreading und Sequenzproblemen.....
Übersicht

![]() |
SkabusBetreff: Von Multitreading und Sequenzproblemen..... |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo alle zusammen!^^
Ich bin vor kurzem in die BlitzBasic-Szene eingestiegen da ich für mein Spieleprojekt eine geeignete Platform gesucht habe. Ich bin ein recht erfahrener C++-Programmierer und habe auch schon in anderen Bereichen viel Erfahrungen gesammelt. Der Einstieg in Blitz Basic war dahingehend nicht sonderlich schwierig.Nachdem ich einige Übungen und ein paar Minispiele recht problemfrei zusammengeschustert habe(naja mehr oder weniger problemfrei XD) habe ich mich nun an mein Projekt gemacht. Da ich das Programmieren mit C++ und DirectX erstmal aufgegeben habe um mich mehr meinem Spiel als dem Lernen von DirectX-Befehlen und Initialisierung von "Presentation Parameters" "Displaymode" "Direct3D" und der damit verbundenen Problematik zuwenden wollte habe ich mit Blitz Basic begonnen.Anfangs gestaltete sich dies auch relativ einfach, nun bin ich da aber auf ein kleines Problem gestoßen welches ich nicht recht beheben kann: Wer den Rpgmaker 2000 oder den Rpgmaker XP kennt,oder eben schonmal SNES-RPG´s gespielt hat kennt sicher die typische Bewegungsart des Protagonisten oder der Characktere im Spiel an sich. Ich spreche hier von der simplen Bewegung des Charackters in 4 Richtungen(links,rechts,oben,unten) und einer dreiteiligen Animation die beim Bewegen in diese Richtung abläuft(Linkes Bein vor, beide Beine zusammen, rechtes Bein vor und wieder von vorne). So, soweit so gut.Ich habe dies auch bereits programmiert und es funktioniert eigentlich ohne Probleme.Jedoch mag die Sequenz nicht 100%tig stimmen.Hier mal mein(noch uneleganter) Test-Code: Code: [AUSKLAPPEN] ;Konstanten Const links = 203 Const rechts = 205 Const oben = 200 Const unten = 208 ;Globale Variablen Global leaveGame = 0 ;Variable die das Beenden des Spiels prüft Global px = 160 ;Startposition des Spielers auf der Abzisse Global py = 120 ;Startposition des Spielers auf der Ordinate Global pDirect = unten ;Blickrichtung des Spielers(zu Anfang nach unten) Global pDirStatus = 0 ;Frame der Bewegungsanimation ;Programminitialisierung Graphics 320,240,16,1 ;Initialisierung des Grafikmodus SetBuffer BackBuffer() ;Stellt die Ausgabe auf BackBuffer ;Laden des Charackteraussehens testchar = LoadAnimImage("source\chars\test.bmp",24,32,0,96) ;Hauptschleife, läuft bis leaveGame = 1 ist While leaveGame = 0 ;Hellblauer Hintergrund und Bild löschen ClsColor 0,255,255 Cls ;Setzt die Transparenzfarbe auf Pink MaskImage testchar,255,0,255 ;Animationsanfrage, noch nicht sehr hübsch aber funktionsfähig If pDirect = links Then ;Zur Erklärung: 0 ist das Standeinzelbild, 1 das rechte Bein 2 das linke If pDirStatus = 0 Then DrawImage testchar,px,py,37 ElseIf pDirStatus = 1 Then DrawImage testchar,px,py,38 ElseIf pDirStatus = 2 Then DrawImage testchar,px,py,36 EndIf ElseIf pDirect = rechts Then If pDirStatus = 0 Then DrawImage testchar,px,py,13 ElseIf pDirStatus = 1 Then DrawImage testchar,px,py,14 ElseIf pDirStatus = 2 Then DrawImage testchar,px,py,12 EndIf ElseIf pDirect = oben Then If pDirStatus = 0 Then DrawImage testchar,px,py,1 ElseIf pDirStatus = 1 Then DrawImage testchar,px,py,0 ElseIf pDirStatus = 2 Then DrawImage testchar,px,py,2 EndIf ElseIf pDirect = unten Then If pDirStatus = 0 Then DrawImage testchar,px,py,25 ElseIf pDirStatus = 1 Then DrawImage testchar,px,py,24 ElseIf pDirStatus = 2 Then DrawImage testchar,px,py,26 EndIf EndIf ; Bewegung des Spielers und speichern der Blickrichtung sowie der ;Animationsstatus If KeyDown(links) Then px = px - 5 pDirect = links pDirStatus = pDirStatus + 1 ;warum ist hier pDirStatus += 1 nicht möglich? If pDirStatus > 2 Then pDirStatus = 0 ;wenn die Animation durchgelaufen ;ist wird sie wieder auf 0 gesetzt ElseIf KeyDown(rechts) Then px = px +5 pDirect = rechts pDirStatus = pDirStatus + 1 If pDirStatus > 2 Then pDirStatus = 0 ; wenn die Animation durchgelaufen ;ist wird sie wieder auf 0 gesetzt ElseIf KeyDown(oben) Then py = py - 5 pDirect = oben pDirStatus = pDirStatus + 1 If pDirStatus > 2 Then pDirStatus = 0 ; siehe oben ElseIf KeyDown(unten) Then py = py + 0.1 pDirect = unten pDirStatus = pDirStatus + 1 If pDirStatus > 2 Then pDirStatus = 0 ;siehe oben Else pDirStatus = 0 EndIf If KeyHit(1) Then leaveGame = 1 ; wenn ESC gedrückt wird, wird das Spiel ;verlassen Flip ;Backbuffer anzeigen If leaveGame = 1 Then FreeImage testchar ;Ressourcen wieder freigeben EndIf Delay 50 ;KNACKPUNKT: Sequenzabhänig, wartet 0,05 Sekunden Wend Der Code mag nicht sonderlich hübsch sein, aber da es zunächst als Test gedacht war habe ich bewusst Typen bzw. Klassen weggelassen. Es funktioniert eigentlich alles wie gewünscht, doch wenn man das ganze mal startet fällt einem sofort auf, dass die Bewegung der Spielerfigur sehr abgehackt aussieht. Grund ist die Logik: Die Sequenzwartezeit t verhält sich quozential zur Bewegungsgeschwindigkeit( 5 Pixel alle 0,05 Sekunden). Das heißt das alle 0,05 Sekunden der Spieler bei gedrückter Richtungstaste 5 Pixel bewegt wird.Gleichzeitig wird aber auch der Frame alle 0,05 Sekunden gewechselt.Eine komplette Animation dauert also nur 0,05 * 3(da 3 Einzelbilder) also nur 0,15 Sekunden.Der Spieler muss flüssig laufen können damit seine Bewegung nicht abgehackt aussieht, leider sind Bewegungsgeschwindigkeit und Animationszeitraum proportional.(v vom Spieler * t der Animation).Ich habe bereits massenhaft rumprobiert aber bissher bleibt das Ergebnis gleich: Wenn die Bewegung des Spielers flüssig ist, ist die Animation zu schnell. Wenn die Animation eine ordentliche Zeitspanne hat sieht die Bewegung des Spielers abgehackt aus. Als Lösungansatz dachte ich mir das ich die Bewegungsanimation in einen Tread packe und die Bewegung in der Hauptschleife lasse.Also machte ich mich auf durchs WWW und suchte nach einer Erklärung ob Multitreading mit Blitz Basic möglich ist(wie das ganze in C++ und dem Windows SDK funktioniert weiss ich bereits seit ein paar Jahren). Ich bin auf dieses Forum gestoßen und suchte hier nach Beiträgen dazu. Leider habe ich keine wirklichen Hilfen gefunden, lediglich den Hinweis das Multitreading scheinbar nicht möglich ist, da sonst die Stabilität nicht gewährleistet ist. Daher nun meine Frage: Gibt es für mein Problem eine alternative, befriedigende Lösung in BB?Oder gibt es eine Möglichkeit Multitreading mit BB zu bewerkstelligen? Ich danke für jegliche Hilfen! P.S.: Sorry das ich nen halben Roman geschrieben habe.Ich will nur nicht das unklarheiten auftreten.Ich bitte dies zu entschuldigen! ![]() Falls noch was unklar ist, einfach Fragen!^^ MfG Ska |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nein, keine Blitz Sprache unterstützt Multithreading.
Da musst du mit anderen Mechanismen arbeiten wie tick basierter Simulation und dergleichen um "pseudo parallelität" innerhalb eines einzelnen Threads zu erhalten. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm das sagt mir jetzt zwar oberflächlich was aber ich kann mir
kein wirklichen Lösungsansatz draus formen. Hast du da vielleicht nen Ansatz für mich? Ich habs bereits mit Zeitverzögerung innerhalb der Frameabfrage probiert aber das verlangsamt wie Delay die ganze Hauptschleife.Externe Funktionen die dann vonner Hauptschleife aufgerufen werden gehen auch nicht, da darin enthaltene Schleifen ja ebenfalls erst durchlaufen bis die Hauptschleife weiterläuft.... Daher bin ich etwas ratlos.Gibt es vielleicht Codes die ein ähnliches Problem bereits gelöst haben?Ich kann mir nicht vorstellen das es nicht möglich ist Bewegungsanimation und Bewegung des Spielers so zu syncronisieren das es flüssig läuft.... ![]() MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
$tankY |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So wie ich das Verstanden habe, willst du eine Bewegung machen und dabei eine Animation.
Ich löse das so: Code: [AUSKLAPPEN] Schleife
Wenn Taste gedrückt Dann Wenn Letzte_Bewegung + 100 < aktuelle Laufzeit (Millisecs()) Dann Ändere Animation Letzte_Bewegung = aktuelle Laufzeit Wenn Anweisung beenden Bewege Figur um 1 Pixel Wenn Anweisung beenden Schleifenende Hier bewegt er die Figur in jedem Schleifendurchlauf um 1 Pixel (wenn die entsprechende Taste gedrückt ist) und wechselt alle 100 Millisekunden die Animation um eine Sequenz. |
||
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
$tankY hat Folgendes geschrieben: So wie ich das Verstanden habe, willst du eine Bewegung machen und dabei eine Animation.
Ich löse das so: Code: [AUSKLAPPEN] Schleife
Wenn Taste gedrückt Dann Wenn Letzte_Bewegung + 100 < aktuelle Laufzeit (Millisecs()) Dann Ändere Animation Letzte_Bewegung = aktuelle Laufzeit Wenn Anweisung beenden Bewege Figur um 1 Pixel Wenn Anweisung beenden Schleifenende Hier bewegt er die Figur in jedem Schleifendurchlauf um 1 Pixel (wenn die entsprechende Taste gedrückt ist) und wechselt alle 100 Millisekunden die Animation um eine Sequenz. Ah genau!Darauf bin ich nicht gekommen.So lässt sich das Ganze einwandfrei steuern!Und das ganz ohne den umständlichen Gebrauch von Multitreading oder sonstigem Quark! Ich danke dir ganz herzlich!Nu kanns weitergehen! ![]() MfG Ska |
||
$tankY |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Noch ein Verbesserungsvorschlag zu Frames:
Wenn du zB ein Bild mit 12 Animationen hast (3 Animationen in 4 Reihen), dann kannst du den aktuellen Frame so berechnen: Frame (Wert zwischen 1 und 3) + Richtung (0-3) * 3 (Anzahl der Frames pro Reihe) Probiers einfach mal (dann musst du nur beim entsprechenden Tastendruck die Richtungsvariable ändern und den Frame um 1 erhöhen pro Animationsschritt und wenn der Frame > 3 ist, dann einfach Frame = 1). |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group