problème d'affichage

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

problème d'affichage

Message par fly »

je suis en train de programmer un jeu de stratégie du style "Age of empire" et je suis confronté à un problème de ralentissement de l'affichage malgré un ordinateur puissant. Lorsque j'arrive à environ 1000 personnages à l'écran, mon FPS passe de 60 à 30 voire moins. Etant donné que je fais de la programmation que depuis 1 an je ne maitrise pas encore purebasic.
Pour la création de mes personnages j'utilise les listes chainées, le problème ne viendrait pas de là par hasard ?
Voici la partie du code qui permet d'afficher mes personnages :

FOREACH perso()

displaytransparentsprite(perso()\id_perso,perso()\pos_x,perso()\pos_y)

NEXT

Est ce que le fait d'afficher tous mes personnages d'un coup serait le problème de mon ralentissement.

Merci d'avance pour vos réponses
Anonyme

Message par Anonyme »

Oui, le fait d'afficher tout les perso hors écran pose problème, la solution est de trier les unitées visibles (élément du décors, perso,ect...)

Code : Tout sélectionner

FOREACH perso()


if perso()\pos_x > 0 and perso()\pos_x< ecran_x and perso()\pos_y > 0 and perso()\pos_yx< ecran_y
  displaytransparentsprite(perso()\id_perso,perso()\pos_x,perso()\pos_y)
endif 


NEXT 
bernard13
Messages : 1221
Inscription : mer. 05/janv./2005 21:30

Message par bernard13 »

dis moi Fly

as tu des captures d'ecran de ton travail?

merci d'avance
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

Merci Cpl.bator d'avoir repondu mais j'utilise deja la solution que tu m'as donné. Par souci de simplicité je ne l'ai pas mis dans mon message précedent parce que mon probleme de ralentissement se manifeste lorsque j'ai mes 1000 personnages à l'écran, quand ils sont en dehors,mon FPS revient à la normal.
Je ne comprend pas pourquoi il y a un ralentissement alors ce ne sont que des sprites et que j'ai un ordinateur relativement puissant.

Je n'ai pas encore de capture d'ecran mais je vais essayer d'en faire.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ça n'a rien a voir , avec le pure tu peux afficher nettement plus que 1000
sprites ,il ne ralentira pas :lol:

j'ai un casse brique que j'ai fait accessible sur mon site (purenoide 1 et 2)
ou rien que les étoiles d'arriere plans c'est deja 1000 sprites !!

l'erreur la plus flagrante de ralentissement ,fait par les debutant en purebasic

c'est d'inclure les "StartDrawing()" et "StopDrawing()" a l'interieur des boucles for-next

bref ça c'est pas bon :

Code : Tout sélectionner

for x=0 to 1000
StartDrawing()
; bla bla
StopDrawing()
next x
il faut faire

Code : Tout sélectionner


StartDrawing()
for x=0 to 1000
; bla bla
next x
StopDrawing()


et la c'est le turbo qui est en route :D
(pareil pour les Flipbuffer()) ect ..
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

pour afficher un sprite tu n'as pas besoin de startDrawing() d'ailleurs le code de fly est correct, du moins le morceau de code qu'il nous montre, faudrait voir le reste.

Est-ce que tu as le débogueur désactivé ?

Code : Tout sélectionner

FOREACH perso()
   displaytransparentsprite(perso()\id_perso,perso()\pos_x,perso()\pos_y)
NEXT 
Mais Dobro a raison 1000 sprites ça devrait s'afficher correctement. Enfin ça dépend ils font quelle taille ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

moi je n'utilise pas "StartDrawing()","StopDrawing()" et pas non plus de boucle for-next . Comme j'utilise les listes chainées j'utilise foreach-next.

Je ne vois pas du tout ou est le problème
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

Je ne sais pas si mon debogueur est désactiver. Ca change quoi?
Pour mes personnage j'utilise des image qui pèse 1 mo environ mais comme je l'ai découpe pour créer des animations avec clipsprite cela donne des sprites qui pèse que quelque ko.
Anonyme

Message par Anonyme »

je ne sais pas ce que vaut le clipsprite en terme de rapidité, mais essaye d'avoir des sprites séparé avec grabsprite(), tu auras certainement un gain de rapidité.


Découpe un sprite en 64*64

Code : Tout sélectionner

GrabNumber = 1
For y = 0 To SpriteHeight(0) - 1 Step 64
  For x = 0 To SpriteWidth(0) - 1 Step 64
    GrabSprite(GrabNumber, x, y, 64, 64)
    GrabNumber=GrabNumber + 1
  Next x
Next y 
Anonyme

Message par Anonyme »

Autre chose, si tu es un maniaque de l'optimisation, tu peut toujours laisser tombé les listes chainées au profit d'allocatememory()


Voici un p'tit exemple qui te donne un ordre d'idée en terme de rapidité :

Code : Tout sélectionner

#Item = 5000000

Timer_A0 = ElapsedMilliseconds()
Dim Tableau_A(#Item)
For i = 0 To #Item
  Tableau_A(i) = Random(2147483647)
Next
Timer_A1 = ElapsedMilliseconds()

Timer_B0 = ElapsedMilliseconds()
NewList Tableau_B()
For i = 0 To #Item
  AddElement(Tableau_B())
  Tableau_B() = Random(2147483647)
Next
Timer_B1 = ElapsedMilliseconds()


Timer_C0 = ElapsedMilliseconds()
*Tableau_C = AllocateMemory(#Item*4)
For i = 0 To #Item
  PokeL(*Tableau_C+(i*4),Random(2147483647))
Next
Timer_C1 = ElapsedMilliseconds()



Timer_A0_ = ElapsedMilliseconds()
For i = 0 To #Item
  R = Tableau_A(i) 
Next
Timer_A1_ = ElapsedMilliseconds()

Timer_B0_ = ElapsedMilliseconds()
ForEach Tableau_B()
  R = Tableau_B() 
Next 
Timer_B1_ = ElapsedMilliseconds()


Timer_C0_ = ElapsedMilliseconds()
For i = 0 To #Item
   R = PeekL(*Tableau_C+(i*4))
Next
Timer_C1_ = ElapsedMilliseconds()





OpenConsole()
PrintN("RESULTAT DECLARATION & ALLOCATION SUR "+Str(#Item)+" ELEMENT(S)"+Chr(10))
PrintN("Tableau        = " +Str(Timer_A1-Timer_A0)+" ms")
PrintN("Liste C        = " +Str(Timer_B1-Timer_B0)+" ms")
PrintN("Pointeur&Alloc = " +Str(Timer_C1-Timer_C0)+" ms"+Chr(10))
PrintN("RESULTAT LECTURE SUR "+Str(#Item)+" ELEMENT(S)"+Chr(10))
PrintN("Tableau        = " +Str(Timer_A1_-Timer_A0_)+" ms")
PrintN("Liste C        = " +Str(Timer_B1_-Timer_B0_)+" ms")
PrintN("Pointeur&Alloc = " +Str(Timer_C1_-Timer_C0_)+" ms")


Repeat
ForEver
 

Bien entendu , rare sont les listes chainées avec 5000000 d'éléments , mais tu te rendra compte , surtout dans un jeu notament pour les tests de collisions une boucle du style :

Code : Tout sélectionner

Foreach machin()
  Foreach Chose()

  next
next
En admetant que chaque liste contient 1000 element cela revient à faire une boucle a 1000*1000 soit 1000000 , a savoir aussi, qu'il reste le pathfinding, l'ia, l'affichage, etc...
Donc l'optimisation n'est pas à prendre à la légère

:)
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

Merci Cpl.bator je vais essayer ta technique

Mais pour comprendre ou je me plante j'ai fait un petit code qui utilise le même principe de création et d'affichage des personnages mais qui est super simple et il se passe le même problème de ralentissement.Peut etre que vous mon erreur.

voici le code:

Code : Tout sélectionner

InitSprite()
InitKeyboard()
InitMouse()
InitSound()
InitSprite3D()

OpenScreen(1440,900,32,"essai")

UsePNGImageDecoder()
UseJPEGImageDecoder() 


LoadSprite(0,"data\porte etendart.png")

Structure terrain_1  
x.f
y.f
EndStructure

Global NewList terrain.terrain_1()

Declare principal()

Repeat
  FlipBuffers()
  ClearScreen(0)
  ExamineKeyboard()  
  
  If Second < ElapsedMilliseconds()
     Second = ElapsedMilliseconds()+1000
     fps = Frame_Counter
     Frame_Counter = 0
  EndIf
  If Second > ElapsedMilliseconds()
    Frame_Counter + 1
  EndIf    
    
  StartDrawing(ScreenOutput())
    DrawText(0,0,"FPS : "+Str(fps))  
  StopDrawing()
    
  ; création des procedures
  
  principal()  

Until  KeyboardPushed(#PB_Key_Escape)


Procedure principal()

If CountList(terrain())<1000
      AddElement(terrain())      
      terrain()\x=Random(1440)
      terrain()\y=Random(900)
EndIf

ForEach terrain()
  DisplayTransparentSprite(0,terrain()\x,terrain()\y)
Next

EndProcedure
Anonyme

Message par Anonyme »

Code : Tout sélectionner

InitSprite()

InitKeyboard()

InitMouse()
InitSound()
InitSprite3D()

OpenScreen(1024,768,32,"essai")



UsePNGImageDecoder()


LoadSprite(0,"C:\Documents and Settings\Ortali\Bureau\01.png",#PB_Sprite_Texture)
CreateSprite3D(0,0)



Structure terrain_1
  
  x.f
  y.f
  
  
EndStructure

Global *Memoire  = AllocateMemory(1000*SizeOf(terrain_1))
Global Count.l

Macro principal()
  
  While Count<1000
    PokeL(*Memoire+(Count*4),Random(1024))
    PokeL(*Memoire+(Count*4)+4,Random(768))
    Count + 1  
  Wend
  
  
  
  Start3D()
  For i = 0 To 1000
    x = PeekL(*Memoire+(i*4))
    y = PeekL(*Memoire+(i*4)+4)
    DisplaySprite3D(0,x,y)
  Next
  Stop3D()
EndMacro

Repeat
  
  
  FlipBuffers(0)
  ClearScreen(0)
  ExamineKeyboard()
  
  
  
  If Second < ElapsedMilliseconds()
    Second = ElapsedMilliseconds()+1000
    fps = Frame_Counter
    Frame_Counter = 0
  EndIf
  If Second > ElapsedMilliseconds()
    Frame_Counter + 1
  EndIf
  
  

  
  ; création des procedures
  
  principal()
  
  StartDrawing(ScreenOutput())
  DrawText(0,0,"FPS  : "+Str(fps))
  DrawText(0,20,"NBR : "+Str(Count))
  StopDrawing()
 
Until KeyboardPushed(#PB_Key_Escape)

Voila, pas tout a fait pareil, mais c'est optmiser ^^
utilise la balise

Code : Tout sélectionner

 [/ code]  pour posté du code sur le forum 
 :)
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

Pourrais tu me dire ce qui faisais que mon code ralentissait
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

fly a écrit :Je ne sais pas si mon debogueur est désactiver. Ca change quoi?
ça ralentit le programme.

Pour savoir si le débogueur est activé regarde l'icone utiliser le débogueur.
ou dans le menu débogueur.


@Cpl.Bator, je ne suis pas convaincu que le ClipSprite soit plus lent ? tu as fait des tests ? Moi je n'en ai pas fait , c'est pour ça que je te demande :)
Dernière modification par comtois le sam. 10/févr./2007 22:44, modifié 2 fois.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
fly
Messages : 16
Inscription : sam. 10/févr./2007 14:13

Message par fly »

merci Cpl.bator pour ton aide

Comtois , je pense pas non plus que clipsprite ralentissement mon progamme. Dans le code que j'ai mis sur le forum je n'utile pas clisprite et pourtant j'ai le même problème de ralentissement

Peut t'étre que mon ralentissement est normal et que purebasic n'est pas capable d'afficher 1000 sprite(environ 100*100 pixel) à un fps de 60.Mais cela m'étonne tout de même.
Répondre