1
DotNet / [SFML 2.0 RC] Aide optimisation
« le: Février 28, 2013, 02:36:00 pm »
Bonjour à tous et à toutes,
Après une assez longue absence du monde de la programmation, me revoilà.
Je m'étais donc relancé dans mon projet de jeu vidéo, l'éditeur suffisamment avancé, je me suis dit : "Allez, il est temps d'optimiser tout ça et de comprendre pourquoi cela bouffe autant de proc".
Après plusieurs essais, j'en suis arrivé à la conclusion (peut-être fausse, corrigez moi si je me trompe) que cela venait de la méthode .Draw() de ma RenderWindow.
C'est pour cela que je me tourne vers vous aujourd'hui. Actuellement j'utilise une méthode un peu barbare (qui ne consommait rien sur la 1.6, étrange, je vous l'accorde). Cette méthode consiste à dessiner case par case, couche par couche (sur lesquelles il y a quelque chose à afficher, les cases vides sont pas dessinées, faut pas déconner) des cases de 32*32pix.. Ce qui correspond donc à 19*14*7=1862 petites cases à dessiner (si toutes les couches sont remplies par des tiles non nuls, bien entendu).
Voici mon code, j'aimerais que vous m'aidiez à l'optimiser pour parvenir à réduire la consommation processeur anormalement élevée pour de la 2D. Je souhaiterais également comprendre et pas me faire balancer une solution comme ça. Merci.
Voici ma boucle de refresh (Gameloop) :
Ainsi que ma méthode de dessin (Ce n'est pas tant les calculs qui sont lourds, j'ai fais des tests, mais si vous avez une meilleure optimisation, je suis preneur car je n'ai pas encore optimisé la partie calculs) :
Voilà, je remercie ceux qui ont pris le temps de me lire, de réfléchir et de m'aider.
Bonne journée !
Après une assez longue absence du monde de la programmation, me revoilà.
Je m'étais donc relancé dans mon projet de jeu vidéo, l'éditeur suffisamment avancé, je me suis dit : "Allez, il est temps d'optimiser tout ça et de comprendre pourquoi cela bouffe autant de proc".
Après plusieurs essais, j'en suis arrivé à la conclusion (peut-être fausse, corrigez moi si je me trompe) que cela venait de la méthode .Draw() de ma RenderWindow.
C'est pour cela que je me tourne vers vous aujourd'hui. Actuellement j'utilise une méthode un peu barbare (qui ne consommait rien sur la 1.6, étrange, je vous l'accorde). Cette méthode consiste à dessiner case par case, couche par couche (sur lesquelles il y a quelque chose à afficher, les cases vides sont pas dessinées, faut pas déconner) des cases de 32*32pix.. Ce qui correspond donc à 19*14*7=1862 petites cases à dessiner (si toutes les couches sont remplies par des tiles non nuls, bien entendu).
Voici mon code, j'aimerais que vous m'aidiez à l'optimiser pour parvenir à réduire la consommation processeur anormalement élevée pour de la 2D. Je souhaiterais également comprendre et pas me faire balancer une solution comme ça. Merci.
Voici ma boucle de refresh (Gameloop) :
' - Boucle de rafraichissement du jeu
Public Sub Gameloop()
While _Socket.Connected
' Affichage graphique
If EnJeu Then
FenetreRendu.Clear(New Color(160, 160, 160))
' Affichage des couches inférieures
For x = 0 To MAX_MAPX
For y = 0 To MAX_MAPY
If Not x < 0 And Not x > 30 And Not y < 0 And Not y > 30 Then
With Map(MapActuelle).Cases(x, y)
If .Sol <> 0 Then
Call AfficherCase(MapActuelle, x, y, 0)
End If
If .Inf1 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 1)
End If
If .Inf2 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 2)
End If
If .Inf3 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 3)
End If
End With
End If
Next
Next
'Petit commentaire pour vous, j'afficherais les joueurs ici, c'est pourquoi j'ai fais deux boucles.
' Affichage des couches supérieures
For x = 0 To MAX_MAPX
For y = 0 To MAX_MAPY
If Not x < 0 And Not x > 30 And Not y < 0 And Not y > 30 Then
With Map(MapActuelle).Cases(x, y)
If .Sup1 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 4)
End If
If .Sup2 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 5)
End If
If .Sup3 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 6)
End If
End With
End If
Next
Next
' Affichage de la grille
If Grille Then
Call AfficherGrille()
End If
' Affichage du tiles selectionné
Call AfficherPreviTiles()
FenetreRendu.Display()
FPS += 1
End If
Application.DoEvents()
End While
MsgBox("Connexion avec le serveur perdue ! Merci de le signaler à l'équipe du jeu.", MsgBoxStyle.Critical, "Erreur fatale")
End
End Sub
Public Sub Gameloop()
While _Socket.Connected
' Affichage graphique
If EnJeu Then
FenetreRendu.Clear(New Color(160, 160, 160))
' Affichage des couches inférieures
For x = 0 To MAX_MAPX
For y = 0 To MAX_MAPY
If Not x < 0 And Not x > 30 And Not y < 0 And Not y > 30 Then
With Map(MapActuelle).Cases(x, y)
If .Sol <> 0 Then
Call AfficherCase(MapActuelle, x, y, 0)
End If
If .Inf1 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 1)
End If
If .Inf2 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 2)
End If
If .Inf3 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 3)
End If
End With
End If
Next
Next
'Petit commentaire pour vous, j'afficherais les joueurs ici, c'est pourquoi j'ai fais deux boucles.
' Affichage des couches supérieures
For x = 0 To MAX_MAPX
For y = 0 To MAX_MAPY
If Not x < 0 And Not x > 30 And Not y < 0 And Not y > 30 Then
With Map(MapActuelle).Cases(x, y)
If .Sup1 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 4)
End If
If .Sup2 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 5)
End If
If .Sup3 <> 0 Then
Call AfficherCase(MapActuelle, x, y, 6)
End If
End With
End If
Next
Next
' Affichage de la grille
If Grille Then
Call AfficherGrille()
End If
' Affichage du tiles selectionné
Call AfficherPreviTiles()
FenetreRendu.Display()
FPS += 1
End If
Application.DoEvents()
End While
MsgBox("Connexion avec le serveur perdue ! Merci de le signaler à l'équipe du jeu.", MsgBoxStyle.Critical, "Erreur fatale")
End
End Sub
Ainsi que ma méthode de dessin (Ce n'est pas tant les calculs qui sont lourds, j'ai fais des tests, mais si vous avez une meilleure optimisation, je suis preneur car je n'ai pas encore optimisé la partie calculs) :
' - Affichage d'une case sur la map
Public Sub AfficherCase(ByVal mapnum As Integer, ByVal X As Byte, ByVal Y As Byte, ByVal Couche As Byte)
Dim tX As Byte
Dim tY As Byte
Select Case Couche
Case 0 ' Sol
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).SolSet))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sol)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sol)
Case 1 ' Inf1
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf1Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf1)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf1)
Case 2 ' Inf2
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf2Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf2)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf2)
Case 3 ' Inf3
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf3Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf3)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf3)
Case 4 ' Sup1
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup1Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup1)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup1)
Case 5 ' Sup2
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup2Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup2)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup2)
Case 6 ' Sup3
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup3Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup3)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup3)
End Select
sprtTiles.TextureRect = New IntRect(tX * 32, tY * 32, 32, 32)
sprtTiles.Position = New Vector2f(X * 32, Y * 32)
FenetreRendu.Draw(sprtTiles)
sprtTiles.Dispose()
End Sub
Public Sub AfficherCase(ByVal mapnum As Integer, ByVal X As Byte, ByVal Y As Byte, ByVal Couche As Byte)
Dim tX As Byte
Dim tY As Byte
Select Case Couche
Case 0 ' Sol
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).SolSet))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sol)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sol)
Case 1 ' Inf1
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf1Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf1)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf1)
Case 2 ' Inf2
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf2Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf2)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf2)
Case 3 ' Inf3
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Inf3Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Inf3)
tY = DecodeY(Map(mapnum).Cases(X, Y).Inf3)
Case 4 ' Sup1
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup1Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup1)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup1)
Case 5 ' Sup2
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup2Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup2)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup2)
Case 6 ' Sup3
sprtTiles = New Sprite(imgTiles(Map(mapnum).Cases(X, Y).Sup3Set))
tX = DecodeX(Map(mapnum).Cases(X, Y).Sup3)
tY = DecodeY(Map(mapnum).Cases(X, Y).Sup3)
End Select
sprtTiles.TextureRect = New IntRect(tX * 32, tY * 32, 32, 32)
sprtTiles.Position = New Vector2f(X * 32, Y * 32)
FenetreRendu.Draw(sprtTiles)
sprtTiles.Dispose()
End Sub
Voilà, je remercie ceux qui ont pris le temps de me lire, de réfléchir et de m'aider.
Bonne journée !