Selbstanimierende Bilder

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

Xar

Betreff: Selbstanimierende Bilder

BeitragDo, Okt 15, 2009 8:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin noch relativ neu in der BlitzMax Welt (ca. 1 Woche) und habe mich wacker durch viele Tutorials und Foren geackert. Ich habe jetzt eine Routine geschrieben, welche folgendes anstellt:

Ich habe ein Spielfeld von 200x200 Feldern. Das Spielfeld zeichne ich in einem herkömmlichen Zeichnungsprogramm und speichere es in einer PNG Datei von 200x200 Pixeln. So ist das Erstellen von neuen Spielfeldern am einfachsten.

Im Programm lade ich dieses PNG als Pixmap und weiss dann anhand der Farbcodes der einzelnen Pixel, welches Feld welchem Terrain gehört (Wiese, Wald, Wasser usw.). Dabei entstehen viele Variationen, da es für an Wiese angrenzenden Wald z.B. eigene Images gibt, damit ein grafischer Übergang da ist. Sieht soweit klasse aus.

Ich zeige dann im Programm ein Feld von 15x15 Feldern à je 50x50 Pixeln (Ausschnitt). Die entsprechenden 50x50 Images für die Terrain Felder sind geladen und werden gesetzt, manche sind begehbar, manche nicht. Der Spieler befindet sich immer in der Mitte, mit jedem Schritt wird die Karte entsprechend neu aufgebaut. Dann einige kleine Effekte: Weiter entfernte Felder erscheinen (kreisförmig) immer dunkler, was den Spieler zu einer Art Lichtquelle macht. Nicht einsehbare Felder bleiben schwarz usw. Funzt alles prima.

Nun möchte ich aber, dass sich manche Felder in sich selbst bewegen, so dass man z.B. bei den Wasser-Feldern eine leichte, stetige Wellenanimation sieht oder sich die Bäume leicht im Wind bewegen.

Ich kann mit LoadAnimImage ein 150x150 Pixel Bild mit 3x3 Wasserfeldern (50x50) laden und dieses animieren, aber dann bleibt der Programmcode an dieser Stelle und das Spiel geht nicht weiter bzw. wenn ich die Schleife verlasse hört die Animation auf. So bewegt sich zudem auch nur ein einziges Feld. Ich müsste diese Anis irgendwie automatisieren, so dass sie sich unabhängig vom Programmverlauf selbst weiter in sich weiter bewegen solange sie sichtbar sind.

Also sozusagen ein Effekt wie bei einem animierten GIF, welches sich selbst automatisch in einem Loop durch seine einzelnen Frames bewegt (in einer zu bestimmenden Geschwindigkeit).

Geht das irgendwie?

Midimaster

BeitragDo, Okt 15, 2009 9:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Wahrscheinlich ist etwas an Deinem grudsätzlichen Aufbau der Main-Schleife falsch. So geht es nicht:

Code: [AUSKLAPPEN]

Repeat
    MaleSpielFeld
    Flip
    Spielereingabe=Waitkey()
    ReaktionSpieler
Forever

Programmiere eine Main-Schleife, die laufend das Spielfeld neu zeichnet und gelegentlich auf Usereingaben reagiert ohne anzuhalten:

Code: [AUSKLAPPEN]

Repeat
    MaleSpielFeld
    Flip
    Spielereingabe=Getkey()
    if SpielerEingabe>0 then
        ReaktionSpieler
    endif
Forever

jetzt kannst Du in der MaleSpielFeld timerabhängig die einzelnen Felder animieren:
Code: [AUSKLAPPEN]


Global FrameZeit%  ' enthält die Uhrzeit des letzten Bildaufbaus

Function MalenSpielFeld()
    if FrameZeit<Millisecs() then
        FrameZeit=Millisecs()+300
        FrameBild=FrameBild+1
        ....alles neu zeichnen
    endif
end Function


Noch schöner wäre natürlich, wenn Du für jedes einzelne Feld einen eigenen Timer verwaltest:

Code: [AUSKLAPPEN]


Global FrameZeit%[i,j]      ' Uhrzeit des letzten Framewechsels
Global FrameTempo%[i,j]  ' das individuelle FrameTempo
Global FrameAnzahl%[i,j] '  Anzahl der mögliches Frames für jeded Feld
Global AktuellesFrame%[i,j] 'aktuell dargestellte Frames für jeded Feld

Function MalenSpielFeld()
    For I%=0 to 199
        For j%= 0 to 199
            If ( FrameAnzahl[i,j] > 0 ) and ( FrameZeit[i,j] < Millisecs() )
                   FrameZeit[i,j]=Millisecs()+FrameTempo[i,j]
                   AktuellesFrame[i,j]=(AktuellesFrame[i,j] + 1 ) mod FrameAnzahl%[i,j]
                   NurDiesNeuZeichnen (I , J )
            endif
        Next
    next
end Function




Der Code soll natürlich nur symbolisch sein. Spätestens hier sollte man jetzt auch über Types reden. Damit sieht es eleganter aus. Hast Du damit schon Erfahrungen?
 

Xar

BeitragDo, Okt 15, 2009 9:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für deine Antwort, Midimaster

ja, ich habe mich mit Types beschäftigt, aber bisher erst sehr oberflächlich. Types und Methodes stellen für mich bisher die am schwersten zu verstehende Neuerung dar. meine ganzen Kenntnisse stammen von vor vielen Jahren aus der QBasic Zeit, noch ganz ohne OOP.

Aber ich glaube, die Schleifen sind schon einigermassen sinnvoll strukturiert. Ich habe einen MainLoop, der bisher nichts anderes macht als auf einen User Input zu warten und diesen dann auszuwerten, um die entsprechende Aktion auszuführen.

Wird eine Bewegungstaste gedrückt, rufe ich die Funktion "MaleDasSpielfeld" auf. Dort drin prüfe ich als erstes, ob das Zielfeld blockiert ist oder nicht. Wenn ja, gebe ich einen akustischen "Boings" Ton aus und kehre zum MainLoop zurück.

Wenn das Feld frei ist, wird die Position des Spielers innerhalb des Spielfeldes neu berechnet und anhand dieser Berechnung das Spielfeld neu gezeichnet. Dann wieder zum MainLoop zurück.

Das heisst, zu 99.9% befindet sich der Programmablauf in der MainLoop, wo ich auf eine Testeneingabe warte.

Das macht doch Sinn so, oder nicht?

Wenn ich dich richtig verstehe, würdest du also nicht in der MainLoop warten und nur bei einer Bewegung das Spielfeld neu zeichnen, sondern stetig immer wieder neu aufbauen? Hmm...das ist an sich schon mal ein interessanter Ansatz.

Und dann beim Zeichnen jeden Feldes prüfen, wann wurdest du das letzte mal animiert und entsprechend reagieren?

Intressanter Gedanke...

BladeRunner

Moderator

BeitragDo, Okt 15, 2009 14:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Nicht nur interessant sondern auch der Standardweg. Alles andere ist Mumpitz.
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

hazumu-kun

BeitragDo, Okt 15, 2009 14:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Darf ich dir persöhnlich noch empfehlen timer zu nutzen, wenn du mit millisecs arbeitest wird das programm die ganze zeit die schleife auf full-speed laufen lassen, deine cpu ist die ganze zeit damit beschäftig die schleife auf 250fps oder mehr durchzulaufen.

Ein Timer macht eine pause zwischendurch und gibt die rechenleitstung für andere prozesse frei:

BlitzBasic: [AUSKLAPPEN]

Global timer= CreateTimer(60)

While Not KeyHit(1)
Cls
MALEN
Benutzereingaben
Flip 0
WaitTimer (timer)
Wend
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent
 

Xar

BeitragDo, Okt 15, 2009 18:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habs jetzt so gemacht und es funktioniert prima, vielen Dank Razz

Das mit dem Timer hab ich mal ausprobiert. Es macht schon was aus, ja. Mit Timer ist die CPU Auslastung bei ca. 14%, ohne bei ca. 50%.

Super, danke euch für die Hilfe!

Nicdel

BeitragDo, Okt 15, 2009 18:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Das es ohne bei 50% ist liegt daran, dass nur ein Prozessorkern deines Dual-Core-prozessors genutzt wird Wink
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7
 

Xar

BeitragFr, Okt 16, 2009 8:13
Antworten mit Zitat
Benutzer-Profile anzeigen
ach? und kann ich das ändern?

Firstdeathmaker

BeitragFr, Okt 16, 2009 9:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Theoretisch ja, ich würde dir davon allerdings abraten (jedenfalls derzeit). Dazu müsstest du Multithreaded programmieren, was ein ziemlich fortgeschrittenes Thema ist.

Zudem ist es doch besser, wenn dein Program weniger Prozessorlast braucht als viel, oder? Denk dabei vor allem mal an die ganzen armen Laptopbesitzer deren Akku sonst allzuschnell flöten geht...
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group