Seite 1 von 1

Zucken beim WindowedScreen

Verfasst: 08.10.2007 23:20
von HeX0R
Moin.

Kann mir mal einer sagen wieso es bei dem folgenden Code bei den Bewegungen des Rasters (WASD-Tasten) immer (scheinbar alle 2 Teile) zu kurzen Zuckern kommt ?
Selbst wenn ich das Delay(5) auf 0 setze oder gar ganz rausnehme ändert das nüscht.
Auch nur ein simples WindowEvent(), also ohne vollständige Entleerung der Queue, bringt goa nix.

Im Fullscreen arbeitet das ganze wunderbar.

Hier der Code:

Code: Alles auswählen

#Do_Full_Screen = 0

#MyColor        = $00AABB
#MOVE_SPEED     = 4

If InitSprite() = 0 Or InitKeyboard() = 0
	End
EndIf

CompilerIf #Do_Full_Screen
If OpenScreen(1024, 768, 32, "Lag Test...") = 0
	End
EndIf
CompilerElse
If OpenWindow(0, 0, 0, 1024, 768, "Lag Test...", #PB_Window_SystemMenu) = 0 Or OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, 0, 0, 0) = 0
	End
EndIf
CompilerEndIf
	

CreateSprite(0, 128, 128)
If StartDrawing(SpriteOutput(0))
	LineXY(0, 63, 63, 0, #MyColor)
	LineXY(64, 0, 128, 63, #MyColor)
	LineXY(128, 64, 64, 128, #MyColor)
	LineXY(0, 64, 63, 128, #MyColor)
	FillArea(64, 64, -1, #MyColor)
	StopDrawing()
EndIf

Define.l PosX, PosY, x, y

Repeat
	CompilerIf #Do_Full_Screen = 0
	Repeat
		Select WindowEvent()
			Case 0
				Delay(5)
				Break
			Case #PB_Event_CloseWindow
				Break 2
		EndSelect
	ForEver
	CompilerEndIf

	If ExamineKeyboard()
		If KeyboardPushed(#PB_Key_D)
			PosX + #MOVE_SPEED
		EndIf
		If KeyboardPushed(#PB_Key_A)
			PosX - #MOVE_SPEED
		EndIf
		If KeyboardPushed(#PB_Key_S)
			PosY + #MOVE_SPEED
		EndIf
		If KeyboardPushed(#PB_Key_W)
			PosY - #MOVE_SPEED
		EndIf
		If KeyboardPushed(#PB_Key_Escape)
			Break
		EndIf
	EndIf
	
	ClearScreen(0)
	For y = 0 To 20
		For x = 0 To 20
			DisplayTransparentSprite(0, PosX + x * 128, PosY + y * 128)
		Next x
	Next y
	
	FlipBuffers()
ForEver

Verfasst: 09.10.2007 14:58
von #NULL
bearbeite nur ein event pro mainloop.
lass das If vor ExamineKeyboard() weg!

Code: Alles auswählen

Repeat
   CompilerIf #Do_Full_Screen = 0
      event = WindowEvent()
      Select event
      Case #PB_Event_CloseWindow
         Break
      EndSelect
   CompilerEndIf

   ExamineKeyboard()
   If KeyboardPushed(#PB_Key_D)
      PosX + #MOVE_SPEED
   EndIf
   If KeyboardPushed(#PB_Key_A)
      PosX - #MOVE_SPEED
   EndIf
   If KeyboardPushed(#PB_Key_S)
      PosY + #MOVE_SPEED
   EndIf
   If KeyboardPushed(#PB_Key_W)
      PosY - #MOVE_SPEED
   EndIf
   If KeyboardPushed(#PB_Key_Escape)
      Break
   EndIf
   
   ClearScreen(0)
   For y = 0 To 20
      For x = 0 To 20
         DisplayTransparentSprite(0, PosX + x * 128, PosY + y * 128)
      Next x
   Next y
   
   FlipBuffers()
ForEver 

Verfasst: 09.10.2007 16:15
von Kaeru Gaman
> bearbeite nur ein event pro mainloop.
eigentlich wird ausdrücklich dazu geraten, alle events in einem durchgang abzuarbeiten.
das ist besonders wichtig, wenn der screen nicht das ganze fenster einnimmt,
und drumrum buttons angeordnet sind, die ne funktion haben sollen, und wenn man menus hat.
wenn man nur das close-event abfragen will, kommt es da nicht drauf an.
ein Forever-Loop ist allerdings unsauber, und das Delay hat dort erstrecht nichts verloren.


generell:
ich kenn das problem, oftmals ist das ein async zwischen der screen-framerate und der desktop-framerate.

wie man des problems wirklich herr wird, weiß ich allerdings auch nicht.
versuch mal, ob es was bringt, wenn du vorher die refresh-rate ermittelst und dann eine feste framerate einstellst.
versuch auch mal, eine framerate einzustellen, die 1-3 frames höher bzw. niedriger ist,
damit die minimale zeitdifferenz, die zum zuckeln führt, ausgeglichen wird.

Verfasst: 09.10.2007 17:53
von HeX0R
Kaeru Gaman hat geschrieben: [...]
ein Forever-Loop ist allerdings unsauber
[...]
Gott sei Dank liegt das im Auge des Betrachters, ich für meinen Teil finde eine unnötige Event-Variable wesentlich "unsauberer".
Kaeru Gaman hat geschrieben: [...]
und das Delay hat dort erstrecht nichts verloren.
[...]
Kannst du das begründen ?
Es geht hier um eine Fensteranwendung, also eine Anwendung, die mir um Himmels Willen nicht 100% CPU-Power ausnudeln soll.
Ob ich das Delay direkt vor dem Beenden der Schleife anbringe, oder irgendwo später dürfte doch Jacke wie Hose sein oder würdest du gar keins einfügen ?

Immerhin erscheint mir der Rest plausibel, das werde ich mal genauer untersuchen.

Übrigens:
Nehme ich den selben Code und aktiviere Stefans DX9-Subsystem ruckelt gar nix mehr.

Verfasst: 09.10.2007 18:07
von nco2k
@HeX0R
das ist leider eines der mysterien von purebasic. ich habs besonders bei Weaponez II gemerkt. ein paar sekunden nachdem man das spiel gestartet hat, fängt es an kurz zu zucken, danach läufts wieder (relativ) gleichmässig. abhilfe schafft SetFrameRate(1000) + SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS) + time-based movement + vsync off, aber selbst dann kann es gelegentlich zucken.

was mir auch aufgefallen ist, dass es unter win xp, bei einem windowed screen besonders stark zuckt, wenn man den task-manager offen hat und dieser sich dann aktuallisiert. aber nicht nur dann, sondern auch durch kleinste festplattenzugriffe.

irgendwie scheinen pb screens sehr empfindlich zu sein. woran das nun aber genau liegt, wird dir vermutlich keiner beantworten können. ich hoffe nur, dass das problem durch dx9 + tripple buffering noch weiter gedrückt werden kann.

ps: komischerweise konnte ich bisher das problem mit dem taskmanager unter vista nicht reproduzieren.

c ya,
nco2k