Selbstanimierende Bilder
Übersicht

XarBetreff: Selbstanimierende Bilder |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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... |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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]
|
||
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich habs jetzt so gemacht und es funktioniert prima, vielen Dank ![]() 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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das es ohne bei 50% ist liegt daran, dass nur ein Prozessorkern deines Dual-Core-prozessors genutzt wird ![]() |
||
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
ach? und kann ich das ändern? | ||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group