Wechsel zwischen Fullscreen- und Windowed
Verfasst: 03.01.2007 23:06
Servus,
zugegeben, das ist jetzt nicht grad der grandioseste Tip, aber falls einer von euch noch am Grübeln war, wie er sein Spiel so programmieren soll, daß ein reibungsloser Wechsel zwischen Fullscreen- und WindowedScreen möglich ist, OHNE daß die Grafiken jedesmal neu geladen werden können, hat hier eine funktionierende Lösung.
DarkDragon hat vorgeschlagen, ein maximiertes OpenGL-Fenster zu benutzen. Wer aber lieber die PB-internen Sprite-Befehle benutzen will, kann folgendes machen:
HINWEIS: (EDIT)
Es lohnt sich definitiv, die nachfolgende Diskussion im Thread zu lesen, da die hier beschriebene Lösung Nachteile hat was den Speicherverbrauch angeht usw, DD und Kaeru haben da auch ein paar Lösungsvorschläge parat. Also bitte kritisch betrachten und nur verwenden, wenn's in eurem Fall gut paßt.
Das (oben) ist der Code, um die Sprites zu laden. Sie werden somit nur ein einziges Mal geladen und gehen beim CloseScreen() nicht verloren.
Um sie benutzen zu können, müssen sie anschließend noch gecatcht werden mit catchGraphics(). Wer will, kann diesen Aufruf natürlich auch direkt in die loadGraphics() einbauen (innerhalb von "if loaded").
Hier nun noch ein einfacher Toggle-Mechanismus. Am besten die Funktion toggleScreenMode() auf F12 legen oder so, und ausprobieren
zugegeben, das ist jetzt nicht grad der grandioseste Tip, aber falls einer von euch noch am Grübeln war, wie er sein Spiel so programmieren soll, daß ein reibungsloser Wechsel zwischen Fullscreen- und WindowedScreen möglich ist, OHNE daß die Grafiken jedesmal neu geladen werden können, hat hier eine funktionierende Lösung.
DarkDragon hat vorgeschlagen, ein maximiertes OpenGL-Fenster zu benutzen. Wer aber lieber die PB-internen Sprite-Befehle benutzen will, kann folgendes machen:
HINWEIS: (EDIT)
Es lohnt sich definitiv, die nachfolgende Diskussion im Thread zu lesen, da die hier beschriebene Lösung Nachteile hat was den Speicherverbrauch angeht usw, DD und Kaeru haben da auch ein paar Lösungsvorschläge parat. Also bitte kritisch betrachten und nur verwenden, wenn's in eurem Fall gut paßt.
Code: Alles auswählen
Structure spr
address.l
number.l
EndStructure
Global NewList spriteList.spr()
; Diese Procedure lädt ein Sprite in den Speicher, das hat
; den Vorteil, daß das Sprite bei einem CloseScreen()
; nicht wieder gelöscht wird!
; Handhabung ist genau gleich wie bei LoadSprite(), mit
; der Ausnahme, daß man keine Flags angeben kann.
; Diese kann man aber in der Procedure catchGraphics()
; angeben (weiter unten).
Procedure.l loadSpriteToMemory(number, filename$)
If ReadFile(0, filename$)
;logger("loading sprite #" + Str(number) + " (" + filename$ + ")")
AddElement(spriteList())
*newSpriteData = AllocateMemory(Lof(0))
ReadData(0, *newSpriteData, Lof(0))
CloseFile(0)
spriteList()\address = *newSpriteData
spriteList()\number = number
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
; Das hier stellt die Procedure dar, die im eigentlichen Spiel
; am Anfang aufgerufen werden muß, um alle Grafiken zu laden.
; Hier kann man vorgehen wie gewohnt, nur daß man halt
; loadSpriteToMemory() aufruft und nicht LoadSprite().
Procedure loadGraphics()
Static loaded = 0
If loaded
ProcedureReturn
EndIf
loadSpriteToMemory(666, "the beast.bmp")
loadSpriteToMemory(667, "neighbor of the beast.bmp")
;...
;...
;...
loaded = 1
EndProcedure
; Hier werden die Grafiken vom normalen RAM in den Videospeicher
; übertragen. Wie bereits erwähnt, wer Flags benötigt, sollte diese
; natürlich hier in den CatchSprite()-Aufruf reinschreiben.
Procedure catchGraphics()
TransparentSpriteColor(-1, RGB(255,0,255))
ForEach spriteList()
CatchSprite(spriteList()\number, spriteList()\address)
Next
EndProcedure
Um sie benutzen zu können, müssen sie anschließend noch gecatcht werden mit catchGraphics(). Wer will, kann diesen Aufruf natürlich auch direkt in die loadGraphics() einbauen (innerhalb von "if loaded").
Hier nun noch ein einfacher Toggle-Mechanismus. Am besten die Funktion toggleScreenMode() auf F12 legen oder so, und ausprobieren

Code: Alles auswählen
Global fullscreen.b
Global openScreenAvailable.b ;um sich zu vergewissern, daß bereits ein Screen geöffnet wurde
#GAME_WINDOW = 0
; öffnet einen neuen Screen im Fullscreen-Modus
Procedure setFullscreenMode()
If IsWindow(#GAME_WINDOW)
CloseWindow(#GAME_WINDOW)
EndIf
If openScreenAvailable
CloseScreen()
EndIf
If OpenScreen(800, 600, 32, "STOP THIS CAR")
ClearScreen(RGB(0,0,0))
FlipBuffers()
loadGraphics()
catchGraphics()
openScreenAvailable = 1
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
; öffnet ein neues Fenster und darin einen Screen
Procedure setWindowedMode()
If openScreenAvailable
CloseScreen()
EndIf
If OpenWindow(0, 0, 0, 800, 600, "STOP THIS CAR", #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(#GAME_WINDOW), 0, 0, 800, 600, 0, 0, 0)
ClearScreen(RGB(0,0,0))
FlipBuffers()
loadGraphics()
catchGraphics()
openScreenAvailable = 1
ProcedureReturn 1
EndIf
EndIf
ProcedureReturn 0
EndProcedure
; diese Funktion muß beim Togglen aufgerufen werden, also
; z.B. bei einem Druck auf F12 oder bei der Auswahl des
; entsprechenden Menüpunktes im Hauptmenü des Spiels
Procedure toggleScreenMode()
If fullScreen = 1
fullScreen = 0
setWindowedMode()
Else
fullScreen = 1
setFullscreenMode()
EndIf
;logger("toggled fullscreen mode.")
EndProcedure