[2D] Flip Horizonal

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [2D] Flip Horizonal

Message par falsam »

@Dobro : Je viens de tester avec un code plus important. Si on ajoute un timeout de quelques millisecondes (2) dans la fonction WaitWindowEvent() alors effectivement ça fonctionne parfaitement bien. J'adopte cette façon de faire pour le moment mais je vais m'imposer ne phase de test quand même :) Merci Dobro.

Ci-dessous un contre exemple pour démontrer que sans cette notion de timeout, ton explication n'est pas bonne. Juste pour te faire raler :mrgreen:

Déplace le sprite avec les flèches gauche et droite. Il y a un temps d'attente quand on change le sens de déplacement si on garde ta façon de faire.

Par contre si tu commentes Event = WaitWindowEvent() et décommentes WindowEvent(), il n'y a plus de temps d'attente.

Code : Tout sélectionner

Enumeration
  #MainForm
EndEnumeration

Global Event, GEvent, TEvent
Global Player,PlayerSpeed = 2
Global Ground, x=350, y=450
Global GameEnd = #False

Procedure GamePreload()
  ;Creation du player
  Player = CreateSprite(#PB_Any, 100, 100)
  StartDrawing(SpriteOutput(Player))
  Box(0, 0, 100, 100, RGBA(255, 228, 196, 255))
  Circle(20, 30, 10, RGBA(210, 180, 140, 255))
  Circle(80, 30, 10, RGBA(210, 180, 140, 255))
  Box(40, 50, 20, 20, RGBA(210, 180, 140, 255))
  Box(30, 75, 40, 10, RGBA(210, 180, 140, 255))
  StopDrawing()
  
  ;Creation du sol
  Ground = CreateSprite(#PB_Any, 800, 50)
  StartDrawing(SpriteOutput(Ground))
  Box(0, 0, 800, 50, RGBA(205, 133, 63, 255))
  StopDrawing()
  
EndProcedure

Procedure GameUpdate()

  If KeyboardPushed(#PB_Key_Left) And x > PlayerSpeed
    x-PlayerSpeed
  EndIf
  
  If KeyboardPushed(#PB_Key_Right) And x < 800-SpriteWidth(Player)-PlayerSpeed
    x+PlayerSpeed
  EndIf
  
  DisplaySprite(Player, x, y)
  DisplaySprite(Ground, 0, 550)
EndProcedure


Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  If InitSprite() = 0 Or InitKeyboard() = 0 
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    GameEnd = #True
  EndIf  
  
  If OpenWindow(#mainform, 0, 0, Width, Height, "New Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(#mainform), 0, 0, Width, Height)
      GamePreload()
    EndIf
  EndIf
  
  Repeat  
    ;Repeat
     ;Event = WindowEvent()
      Event = WaitWindowEvent()
      GEvent = EventGadget()
      TEvent = EventType()
     
      Select event    
        Case #PB_Event_CloseWindow
          GameEnd = #True
            
      EndSelect  
    ;Until event=0
    
    FlipBuffers()
    ClearScreen(RGB(255,255,255))
                
    ExamineKeyboard()
    GameUpdate()
  
  Until KeyboardPushed(#PB_Key_Escape) Or GameEnd = #True
EndProcedure

GameStart()
Dernière modification par falsam le lun. 31/mars/2014 15:03, modifié 1 fois.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [2D] Flip Horizonal

Message par blendman »

falsam a écrit :■ Merci Dobro pour ton aide : Le flip fonctionne bien mais on perd le lissage du contour.
majikeyric a écrit :Je pense que le vrai problème venait du canal alpha avec l'emploi du 'plot'.
majikeyric tu as raison et je ne sais pas comment faire pour résoudre ce souci.
En utilisant les drawingmode() et alpha(), ça fonctionne parfaitement, même plus besoin de vérifier la couleur :

Code : Tout sélectionner

Enumeration
  #MainForm
EndEnumeration

Global Event, Sprite
Declare  catch_sprite(sprite)
Declare  SpriteFlipHorizontal(Sprite)
Declare  GameStart()

Procedure catch_sprite(sprite)
  
  Protected Width = SpriteWidth(Sprite)
  Protected Height = SpriteHeight(Sprite)
  Global Dim ColorsArray(Width, height), x, y
  
  If StartDrawing(SpriteOutput(Sprite))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For y = 0 To Height-1
      For x = 0 To Width-1
        ColorsArray(x,y) = RGBA(Red(Point(x,y)), Green(Point(x,y)), Blue(Point(x,y)), Alpha(Point(x,y)))            
      Next x   
    Next y   
    
    StopDrawing()
  EndIf
  TransparentSpriteColor(Sprite,$0)
EndProcedure

Procedure SpriteFlipHorizontal(Sprite)
  Protected Width = SpriteWidth(Sprite)
  Protected Height = SpriteHeight(Sprite)
  
  If StartDrawing(SpriteOutput(Sprite))
    ; on met une couleur noire transparente si besoin
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0,0,Width, height,RGBA(0,0,0,0))
    ; puis on redessine le sprite en miroir
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For y = 0 To Height-1
      For x = Width-1 To 0 Step -1
        Plot((SpriteWidth(Sprite)-1)-x, y , ColorsArray(x,y))   
      Next
    Next
    StopDrawing()
    
  EndIf
  
EndProcedure

Procedure GameStart()
  Protected cr.b = #True
  Protected Width = 1024
  Protected Height = 768
  
  If UsePNGImageDecoder() : EndIf
  
  If  InitNetwork()
    ReceiveHTTPFile("http://s242132022.onlinehome.fr/Download/PureBasic/platform_bench_2.png", GetTemporaryDirectory()+"image.png")
  EndIf
  
  InitSprite() : InitKeyboard() : InitMouse() : InitSound(); il faut mettre des if ;)
  
  If OpenWindow(#mainform, 0, 0, Width, Height, "New Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    
    If  OpenWindowedScreen(WindowID(#mainform), 0, 0, Width, Height)       
      Sprite = LoadSprite(#PB_Any, GetTemporaryDirectory()+"image.png", #PB_Sprite_AlphaBlending)
    EndIf
    
    Repeat
      
      Event = WindowEvent()
      
      Select event   
        Case #PB_Event_CloseWindow
          End
      EndSelect
      
      
      ExamineKeyboard()
      
      If KeyboardReleased(#PB_Key_Space)
        catch_sprite(sprite)
        SpriteFlipHorizontal(Sprite)
      EndIf   
      
      ClearScreen(RGB(245, 222, 179))
      DisplayTransparentSprite(Sprite, 0, 0)
      
      FlipBuffers()
      
      ;ZoomSprite(Sprite, 500, 300)
    Until KeyboardPushed(#PB_Key_Escape)
    
    DeleteFile(GetTemporaryDirectory()+"image.png")
  EndIf
EndProcedure

GameStart()

; Epb
Sinon, la technique de Dobro avec le WaitWindowEvent(Delay) me semble vraiment mieux que le double repeat ;).
La preuve (en reprenant le code de GallyHC), ici ça ne sert à rien :

Code : Tout sélectionner

If InitSprite() = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran & l'environnement nécessaire aux sprites !", 0)
  End
EndIf

If OpenWindow(0, 0, 0, 220, 160, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(0), 0, 0, 160, 160)
  Else
    MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
    End
  EndIf
EndIf

Repeat
    ;
    ; BOUCLE MAIN
    ;
    i = 0
    Repeat
      ;
      ; BOUCLE DE TRAITEMENT DES EVENEMENTS
      ; SI = 0 LA PILE EST VIDE.
      ;
      Event = WaitWindowEvent(1)
     
      i + 1
     
      Select Event
        Case #PB_Event_Gadget
        Case #PB_Event_CloseWindow
          End
      EndSelect
    Until Event = 0
    ;
    ; AFFICHAGE ET AUTRE...
    ;
    Debug i
    ;
    ; SI ON REGARDE i ON VOIS QU'IL A ETE INCREMENTER
    ; 1 FOIS, DONC plus de besoin de double repeat 
ForEver
Pour du jeu, ça me semble mieux qu'un windowEvent().

Bien sûr, il faut mettre un timer avec le waitwindowevent(), sinon, le jeu est en pause ^^.

PS : au fait, merci dobro pour le miroir, je vais utiliser ce code dans un petit programme que je réalise en ce moment, pour créer des spriteSheet ^^.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [2D] Flip Horizonal

Message par falsam »

YeahhHHHhhhh ........ Blendman tu es génial et en plus le lissage est parfait. :)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [2D] Flip Horizonal

Message par blendman »

falsam a écrit :YeahhHHHhhhh ........ Blendman tu es génial et en plus le lissage est parfait. :)
lol, faut pas exagérer ^^
C'est juste que j'ai codé quelques applications de dessins et donc j'avais besoin souvent de gérer l'alpha et la transparence.
Avec drawingmode et les customfilters on peut d'ailleurs réaliser les blendmode de photoshop, c'est aussi assez sympathique.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [2D] Flip Horizonal

Message par falsam »

C'est justement des connaissances que je n'ai pas et qui me manque cruellement. J'ai souvent ces soucis du au canal alpha.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [2D] Flip Horizonal

Message par GallyHC »

la on est au moin deux lol....
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [2D] Flip Horizonal

Message par Backup »

falsam a écrit :@Dobro : Je viens de tester avec un code plus important. Si on ajoute un timeout de quelques millisecondes (2) dans la fonction WaitWindowEvent() alors effectivement ça fonctionne parfaitement bien. J'adopte cette façon de faire pour le moment mais je vais m'imposer ne phase de test quand même :) Merci Dobro.

oui oui :) l'utilisation de WaitWindowEvent(xx) doit etre accompagné de XX :)
on est bien d'accord ..

sur ma bombe (MSI GT780 DXR ) le fait de mettre (1) suffit, mais bien souvent, je met plutot (20)
en fait c'est en voyant Fred utiliser "WaitWindowEvent(20)" , que depuis je met 20 :)
Mesa
Messages : 1098
Inscription : mer. 14/sept./2011 16:59

Re: [2D] Flip Horizonal

Message par Mesa »

Pour ma part, avec mon ordi un peu lent et concernet le code de l'aide:
Avec les 2 repeat : En cliquant sur le bouton, je vois que le bouton s'enfonce et la fenêtre se ferme immédiatement.
Avec 1 repeat : le bouton ne s'enfonce pas ou alors il faut que je reste appuyé 1 seconde environ, et la fenêtre ne se ferme pas immédiatement.

Donc le 2eme repeat sert à quelque chose, désolé dobro :wink: .

Avec un seul repeat, on peut donc s’attendre à des problèmes avec une fenêtre qui contiendrait beaucoup de gadgets surtout avec des gadgets différents.
Il faudrait faire des essais avec linux et osx aussi.

Par contre, sauf erreur j'ai un bug avec le clic-droit sur le bouton:

Code : Tout sélectionner

If InitSprite() = 0
		MessageRequester("Erreur", "Impossible d'ouvrir l'écran & l'environnement nécessaire aux sprites !", 0)
		End
	EndIf
	
	If OpenWindow(0, 0, 0, 220, 160, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		ButtonGadget(0, 170, 135, 45, 20, "Quitter")

		If OpenWindowedScreen(WindowID(0), 0, 0, 160, 160)
			CreateSprite(0, 20, 20)
			If StartDrawing(SpriteOutput(0))
				Box(0, 0, 20, 20, RGB(255, 0, 155))
				Box(5, 5, 10, 10, RGB(155, 0, 255))
				StopDrawing()
			EndIf
		Else
			MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
			End
		EndIf
	EndIf
	
	direction = 2
	Repeat
		; Il est très important de traiter tous les événements restants dans la file d'attente à chaque tour
		;
		Repeat
			Event = WindowEvent()
			
			Select Event 
				Case #PB_Event_Gadget
				  Select EventGadget()
				    Case 0
				     type=EventType() 
				      
				      Debug type
				        Select type
				            
				          Case  #PB_EventType_RightClick;#PB_EventType_LeftClick;
				            Debug "clic-droit sur le bouton"
				        End
				      EndSelect  
				  EndSelect
				  
				Case #PB_Event_RightClick 
				   Debug "clic-droit sur la fenêtre"
				  
				Case #PB_Event_CloseWindow
					End 
			EndSelect
		Until Event = 0
	
		FlipBuffers() 
		ClearScreen(RGB(0, 0, 0))
		DisplaySprite(0, x, x)
		x + direction
		If x > 140 : direction = -2 : EndIf
		If x < 0   : direction =  2 : EndIf
		Delay(1)
	ForEver
Avec le dernier code de falsam, même chose. Si je mets un seul repeat, il faut que j'attende 1 seconde avant que le bonhomme veuille bien bouger après avoir appuyé sur une des touches fléchée.
Pour avoir une réponse immédiate,il faut les 2 repeat et en plus si j'utilise WaitWindowEvent(), il faut absolument que je mette une valeur, par exemple WaitWindowEvent(1) sinon c'est encore pire, le bonhomme ne bouge pas et la fenêtre ne se ferme pas.

Le code le plus rapide, chez moi, c'est :

Code : Tout sélectionner

Enumeration
	#MainForm
EndEnumeration

Global Event, GEvent, TEvent
Global Player,PlayerSpeed = 2
Global Ground, x=350, y=450
Global GameEnd = #False

Procedure GamePreload()
	;Creation du player
	Player = CreateSprite(#PB_Any, 100, 100)
	StartDrawing(SpriteOutput(Player))
	Box(0, 0, 100, 100, RGBA(255, 228, 196, 255))
	Circle(20, 30, 10, RGBA(210, 180, 140, 255))
	Circle(80, 30, 10, RGBA(210, 180, 140, 255))
	Box(40, 50, 20, 20, RGBA(210, 180, 140, 255))
	Box(30, 75, 40, 10, RGBA(210, 180, 140, 255))
	StopDrawing()
	
	;Creation du sol
	Ground = CreateSprite(#PB_Any, 800, 50)
	StartDrawing(SpriteOutput(Ground))
	Box(0, 0, 800, 50, RGBA(205, 133, 63, 255))
	StopDrawing()
	
EndProcedure

Procedure GameUpdate()

	If KeyboardPushed(#PB_Key_Left) And x > PlayerSpeed
		x-PlayerSpeed
	EndIf
	
	If KeyboardPushed(#PB_Key_Right) And x < 800-SpriteWidth(Player)-PlayerSpeed
		x+PlayerSpeed
	EndIf
	
	DisplaySprite(Player, x, y)
	DisplaySprite(Ground, 0, 550)
EndProcedure


Procedure GameStart()
	Protected cr.b = #True
	Protected Width = 800
	Protected Height = 600
	
	If InitSprite() = 0 Or InitKeyboard() = 0 
		MessageRequester("Error", "Sprite system can't be initialized", 0)
		GameEnd = #True
	EndIf  
	
	If OpenWindow(#mainform, 0, 0, Width, Height, "New Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
		If OpenWindowedScreen(WindowID(#mainform), 0, 0, Width, Height)
			GamePreload()
		EndIf
	EndIf
	
	Repeat  
		Repeat
		  Event = WindowEvent()
			;Event = WaitWindowEvent(1)
			GEvent = EventGadget()
			TEvent = EventType()
			
			Select event    
				Case #PB_Event_CloseWindow
					GameEnd = #True
						
			EndSelect  
		Until event=0
		
		FlipBuffers()
		ClearScreen(RGB(255,255,255))
								
		ExamineKeyboard()
		GameUpdate()
	
	Until KeyboardPushed(#PB_Key_Escape) Or GameEnd = #True
EndProcedure

GameStart()
Pour un bon fonctionnement du programme, les 2 repeat sont nécessaires malgré ce que dit dobro.

M.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [2D] Flip Horizonal

Message par graph100 »

Pour faire le point sur ce qui a été dit sur cette fameuse double boucle repeat :

testez les 2 codes suivants :

avec syncronisation (par défaut)

Code : Tout sélectionner

DisableDebugger

InitSprite()

OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 600, 400)

count = 0
time = ElapsedMilliseconds()

Repeat
	
	; boucle de traitement des evènements
	Repeat
		event = WindowEvent()
		
		If event = #PB_Event_CloseWindow
			End
		EndIf
		
	Until event = 0
	
	
	count + 1
	If ElapsedMilliseconds() - time > 100
		draw_fps = 1000 * count / (ElapsedMilliseconds() - time)
		time = ElapsedMilliseconds()
		
		count = 0
	EndIf
	
	ClearScreen(0)
	If StartDrawing(ScreenOutput())
		
			DrawText(0, 0, Str(draw_fps) + " FPS")
		
		StopDrawing()
	EndIf
	FlipBuffers()
	
ForEver

Sans la syncronisation :

Code : Tout sélectionner

DisableDebugger

InitSprite()

OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 600, 400, 0, 0, 0, #PB_Screen_NoSynchronization)

count = 0
time = ElapsedMilliseconds()

Repeat
	
	; boucle de traitement des evènements
	Repeat
		event = WindowEvent()
		
		If event = #PB_Event_CloseWindow
			End
		EndIf
		
	Until event = 0
	
	
	count + 1
	If ElapsedMilliseconds() - time > 100
		draw_fps = 1000 * count / (ElapsedMilliseconds() - time)
		time = ElapsedMilliseconds()
		
		count = 0
	EndIf
	
	ClearScreen(0)
	If StartDrawing(ScreenOutput())
		
			DrawText(0, 0, Str(draw_fps) + " FPS")
		
		StopDrawing()
	EndIf
	FlipBuffers()
	
ForEver
Ces codes font apparaitre l'intérêt d'utiliser la seconde boucle pour traiter la pile des évènements dans le cas de l'utilisation conjointe de WindowEvent() et de FlipBuffers(). Car dans la plupart des cas, la fonction FlipBuffer() intègre déjà le delay nécessaire à limiter la vitesse d'exécution du programme à 60 ips.

Mais par exemple lors du dessin sur un CanvasGadget(), qui n'intègre pas la notion de Flipbuffer(), cette architecture n'est pas judicieuse et doit être remplacée par une autre méthode mieux adaptée.

En gros, la double boucle se justifie dans un cas précis car la pile d'évènement doit être entièrement traitée pour éviter un freeze du programme ou une accumulation dans la pile (en pratique ça n'arrive jamais).
L'utilisation type est un jeu codé dans une fenêtre avec un OpenWindowedScreen(), pour des raisons de fluidité.

Le reste du temps, utilisez WaitWindowEvent() :wink:
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [2D] Flip Horizonal

Message par falsam »

Je découvre ce que donne une fenetre 2D avec et sans synchronisation. Belle démonstration sans appel graph100 :)

J'ai testé mon code sur une vieux PC sous XP (Intel 2.4 Ghz) et effectivement ça rame avec la version de Dobro. Je vais revenir à la version avec les deux repeat.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [2D] Flip Horizonal

Message par Backup »

@graph100

heu... vous lisez ce que j'ai ecris ?

je prends ton code sans synchro , je vire seulement la boucle Repeat interieur

et ça change quoi ?

Code : Tout sélectionner

DisableDebugger
InitSprite()
OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 600, 400, 0, 0, 0, #PB_Screen_NoSynchronization)
count = 0
time = ElapsedMilliseconds()
Repeat
	; boucle de traitement des evènements
	; Repeat ;<<<<<<<<<<<<<<<< retiré par Dobro
	event = WindowEvent()  
	If event = #PB_Event_CloseWindow
		End
	EndIf
	;Until event = 0  ;<<<<<<<<<<<<<<<< retiré par Dobro
	
	count + 1
	If ElapsedMilliseconds() - time > 100
		draw_fps = 1000 * count / (ElapsedMilliseconds() - time)
		time = ElapsedMilliseconds()
		count = 0
	EndIf
	ClearScreen(0)
	If StartDrawing(ScreenOutput())
		DrawText(0, 0, Str(draw_fps) + " FPS")
		StopDrawing()
	EndIf
	FlipBuffers()
ForEver
; Epb



je ne dis pas que windowsEvent n'est pas utile , je dis que c'est votre boucle Repeat-until interieur qui l'est !



de plus lorsque vous utilisez WindowEvent() .... attention je dis bien WindowEvent() pas WaitWindowEvent(x)
il faut utiliser un Delay(x) parce que si vous jeter un oeil au gestionnaire des taches , vous allez voir le processeur
se faire bouffer ses ressources .. alors meme qu'il n'y a rien , pas de sprites, de collisions, de calculs ....

tes 2 exemples bouffent énormément le processeur !!
sur une petite config, c'est la Rame assuré ! :roll:


de plus , je préfère utiliser WaitWindowsEvent(x) coordonné a SetFrameRate(xx)
car comme ça je garde un taux d'affichage Certes , moins élevè , mais relativement constant !!
et surtout, je ne bouffe pas les ressources de l'ordinateur .. (on est sur systeme multitâche , faut en tenir compte )

je reprends ton code non synchro et voila :

Code : Tout sélectionner

DisableDebugger
InitSprite()
OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 600, 400, 0, 0, 0, #PB_Screen_NoSynchronization)
count = 0
time = ElapsedMilliseconds()

SetFrameRate(1000) ; fera son possible pour atteindre 1000 frames par secondes
Repeat
	; boucle de traitement des evènements
	; Repeat ;<<<<<<<<<<<<<<<< retiré par Dobro
	WaitWindowEvent(1)  ; permettra d'utiliser sans soucis les gadgets surtout en mode windowed Screen
; mais surtout permet de ne pas piquer toutes les ressources du system (Ctrl+Del pour voir le temp Processeur )
	
	
	If event = #PB_Event_CloseWindow
		End
	EndIf
	;Until event = 0  ;<<<<<<<<<<<<<<<< retiré par Dobro
	
	count + 1
	If ElapsedMilliseconds() - time > 100
		draw_fps = 1000 * count / (ElapsedMilliseconds() - time)
		time = ElapsedMilliseconds()
		count = 0
	EndIf
	ClearScreen(0)
	If StartDrawing(ScreenOutput())
		DrawText(0, 0, Str(draw_fps) + " FPS")
		StopDrawing()
	EndIf
	FlipBuffers()
ForEver
; Epb



pour finir

WaitWindowEvent(2) = ( WindowEvent() : Delay(2) )

je trouve plus propre d'avoir un peu moins de performances , mais etre respectueux
du systeme sans trop bouffer de ressources, et pouvoir gerer des gadgets eventuel (pensez au WindowedScreen() )
sans pour autant avoir a utiliser une boucle Repeat-until interieur, qui ne sert a rien !

utiliser WindowEvent() sans delay , c'est limiter aux Code De Demos, car on ne cherche pas a respecter
les autres applications, on veux tout le processeur pour nous ... c'est quand meme assez rare comme utilisation !!

mais pour le moment, aucun de vos codes ne m'a apporté la pertinence de l'utilisation d'un boucle interne pour
soi disant "vider" la liste des Events ... :roll:
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [2D] Flip Horizonal

Message par graph100 »

J'ai bien entendu lu ce que tu avais écris et compris ton point de vue.

Simplement, ce que je voulais souligner, c'est l'utilisation conjointe de WindowEvent() et de FlipBuffer() avec la syncro. qui rend complètement superflue l'ajout d'un delay() dans le code, et la nécessité de cette boucle de traitement de tout les events.

La fonction delay() n'est absolument pas précise et non prioritaire, ce qui entraine qu'il peut arriver des lag si le système est occupé ailleurs.

L'intérêt de cette boucle est évidement de vider la pile des évènements window avant de passer à la suite du programme.
On est d'accord que dans la plupart des cas cette pile ne contient qu'un seul évènement, (sauf si tu bouge la souris partout en cliquant vite, ou que tu appuies sur plein de touche, --> comme dans un jeu), mais souvent au lancement de l'appli il y a plein d'évènement windows à traiter à la suite, et non un seul par boucle de calcul, ce qui occasionne des freezes au lancement, ou bien un delay énorme lors actions, qui continuent de s'écouler alors que tu ne touches plus à rien !

@Falsam : sans la syncro j'obtiens un fps qui se stabilise autour de 900 (entre 2500 et 900) :mrgreen: et le processeur qui est dans les 8% constants d'utilisation.
avec la syncro je suis à 60fps constant et 0.8% du proc.


L'intérêt majeur d'utiliser windowevent() et flipbuffer() est de maintenir un fps constant tant que le temps de calcul reste plus petit que 1/60ème de seconde, puis 1/30ème de seconde (lors que la syncro verticale est activée.)

En gros le temps d'exécution de ta boucle est fixé à 1/60ème de seconde.
|---tps de calcul---|................................attente..........................|1/60ème de sec
|--------tps de calcul-------------|...................attente........................|1/60ème de sec
|---------------------tps de calcul--------------------------|........attente.........|1/60ème de sec

Ensuite, si tu prend le fps de 2500 que j'obtiens dans les 10ères secondes du fonctionnement de l'exemple plus haut, ça donne un temps d'exécution de 0.0004 secondes pour une boucle complète. 4 nano secondes

Bref, ne mettez pas de delay() dans une boucle qui contient un flipbuffer() qui est syncronisé. Et par contre mettez une boucle de traitement des event en haut de la boucle principale (je ne le fais pas parce que je suis fainéant dans la plupart de mes programmes, mais c'est parce que ça n'est pas critique :roll: )

Fred, si tu as un avis sur la question et le temps de le poster, je le lirais avec plaisir :wink:
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
majikeyric
Messages : 602
Inscription : dim. 08/déc./2013 23:19
Contact :

Re: [2D] Flip Horizonal

Message par majikeyric »

graph100 a écrit :Fred, si tu as un avis sur la question et le temps de le poster, je le lirais avec plaisir :wink:
Il est en vacances pour 3 semaines :mrgreen:
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [2D] Flip Horizonal

Message par graph100 »

Quand il va revenir il va râler en disant que ce sujet à déjà été traité il y a longtemps :lol:
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Répondre