Von Multitreading und Sequenzproblemen.....

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Skabus

Betreff: Von Multitreading und Sequenzproblemen.....

BeitragSa, Mai 12, 2007 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
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! Wink
Falls noch was unklar ist, einfach Fragen!^^

MfG Ska
 

Dreamora

BeitragSa, Mai 12, 2007 15:40
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Mai 12, 2007 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
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....Confused


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

BeitragSa, Mai 12, 2007 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Mai 12, 2007 17:18
Antworten mit Zitat
Benutzer-Profile anzeigen
$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! Very Happy

MfG Ska
 

$tankY

BeitragSa, Mai 12, 2007 17:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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).

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group