
Que pensez vous de la gestion des sprites ?
Je me demande si c'est une bonne idée de faire comme suis, il y a des avantages, comme ne pas avoir à s’occuper de l'affichage (ou très peu), mais certainement aussi plein d'inconvénient.
Comme tout les jeux ou applications que j'ai programmé jusqu'à maintenant sont CPUvores, j'aimerais passer à une façon rapide d'afficher, et obtenir un bô rendu sans lag.
Je vous avoue que ce sont les derniers screens de Blendman qui m'on réveiller sur ces points là

[edit] je voulais savoir aussi si vous trouvez le jeu fluide, (niveau graphique c'est pas lourd, donc surtout pour les déplacements, car j'ai eu des cas d'accélérations)
Code : Tout sélectionner
;######################################
; programme : Jeu Naze vite fait
#VERSION = "1.00"
; description : - ressemble vaguement au jeu originel Space Invaders
;
; détails : - bah on tire avec espace...
;
; ajouts prévus : - avancer le gameplay, peut-être...
;
; auteur : graph100 alias Kriek106
;######################################
;{ Variables globales
#octet_donne = 8
#w = 800
#h = 600
#terrain_w = 250
#terrain_h = 205
; #l = #h / #terrain_h
#l = 2
Global *sprite.l = 0, EXIT.b = #False, nb_ennemis_tues = 0, nb_a_tuer.l, perdu.b = #False
Global position_globale.POINT
#TEXT_GAGNE = "Vous avez défendu la terre contre les SPACEs INVADERs"
#TEXT_PERDU = "Les SPACEs INVADERs ont envahi la terre, que vous n'avez su défendre..."
;}
;{ init des environnements graphiques
If InitSprite() = 0 Or InitKeyboard() = 0
End
EndIf
;}
;{ structure sprite
Structure sprite
sprite.l
x.l
y.l
w.l ; pas tres tres utile, mais sait-on jamais ???
h.l
is_pos_globale.b
EndStructure
;}
;{ fonction/macro sur le bloc memoire *sprite
Macro AllocateSprite(nb_sprite)
If *sprite
If PeekL(*sprite - #octet_donne) > nb_sprite
*sprite = ReAllocateMemory(*sprite - #octet_donne, nb_sprite * SizeOf(sprite) + #octet_donne) + #octet_donne
For a = PeekL(*sprite - #octet_donne) - 1 To nb_sprite - 1
PokeL(*sprite + a * SizeOf(sprite), -1)
Next
PokeL(*sprite - #octet_donne, nb_sprite)
EndIf
Else
*sprite = AllocateMemory(nb_sprite * SizeOf(sprite) + #octet_donne) + #octet_donne
; on avance l'index mémoire de 4 pour "cacher" le nombre de sprite en mémoire, (faciliter l'accès aux données)
For a = 0 To nb_sprite - 1
PokeL(*sprite + a * SizeOf(sprite), -1)
Next
PokeL(*sprite - #octet_donne, nb_sprite)
EndIf
EndMacro
Macro FreeAllocatedSprite()
If *sprite
For a = 0 To PeekL(*sprite - #octet_donne) - 1
FreeSprite(a)
Next
FreeMemory(*sprite - #octet_donne)
EndIf
EndMacro
Macro NombreSpriteReserver()
PeekL(*sprite - #octet_donne)
EndMacro
Macro NombreSpriteAllouer()
PeekL(*sprite - #octet_donne + 4)
EndMacro
Macro SpriteSprite(hd)
PeekL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\sprite))
EndMacro
Macro SpriteX(hd)
PeekL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\x))
EndMacro
Macro SpriteY(hd)
PeekL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\y))
EndMacro
Macro SpriteW(hd)
PeekL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\w))
EndMacro
Macro SpriteH(hd)
PeekL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\h))
EndMacro
Macro SpriteIsPosGlobale(hd)
PeekB(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\is_pos_globale))
EndMacro
Macro Sprite_SetSprite(hd, sprite1)
PokeL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\sprite), sprite1)
EndMacro
Macro Sprite_SetX(hd, x1)
PokeL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\x), x1)
EndMacro
Macro Sprite_SetY(hd, y1)
PokeL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\y), y1)
EndMacro
Macro Sprite_SetW(hd, w1)
PokeL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\w), w1)
EndMacro
Macro Sprite_SetH(hd, h1)
PokeL(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\h), h1)
EndMacro
Macro Sprite_SetIsPosGlobale(hd, IsPosGlobale1)
PokeB(*sprite + hd * SizeOf(sprite) + OffsetOf(sprite\is_pos_globale), IsPosGlobale1)
EndMacro
Procedure AddSprite(sprite.l, x.l, y.l, IsPosGlobale.b)
If *sprite = 0
AllocateSprite(1)
EndIf
res = NombreSpriteAllouer()
If res = NombreSpriteReserver()
AllocateSprite(res + 1)
Else
For a = 0 To res
If SpriteSprite(a) = -1
res = a
Break
EndIf
Next
EndIf
Sprite_SetSprite(res, sprite)
Sprite_SetX(res, x)
Sprite_SetY(res, y)
Sprite_SetW(res, SpriteWidth(sprite))
Sprite_SetH(res, SpriteHeight(sprite))
Sprite_SetIsPosGlobale(res, IsPosGlobale)
PokeL(*sprite - #octet_donne + 4, NombreSpriteAllouer() + 1)
ProcedureReturn res
EndProcedure
Macro DeleteSprite(hd)
PokeL(*sprite + hd * SizeOf(sprite), -1)
PokeL(*sprite - #octet_donne + 4, NombreSpriteAllouer() - 1)
EndMacro
;}
Procedure DrawSprite(bla); le bla ne sert que pour pouvoir lancer un thread
time2 = ElapsedMilliseconds() - 1
Repeat
;{ calcul temps boucle
time = ElapsedMilliseconds() - time2
time2 = ElapsedMilliseconds()
;}
ClearScreen(0)
If StartDrawing(ScreenOutput())
If time = 0
DrawText(0, 0, "FPS : Infini")
Else
DrawText(0, 0, "FPS : " + Str(1000 / time))
EndIf
StopDrawing()
EndIf
If nb_a_tuer = nb_ennemis_tues
If StartDrawing(ScreenOutput())
DrawText(#terrain_w * #l / 2 - TextWidth(#TEXT_GAGNE) / 2, #terrain_h * #l / 2, #TEXT_GAGNE)
StopDrawing()
EndIf
ElseIf perdu = #True
If StartDrawing(ScreenOutput())
DrawText(#terrain_w * #l / 2 - TextWidth(#TEXT_PERDU) / 2, #terrain_h * #l / 2, #TEXT_PERDU)
StopDrawing()
EndIf
Else
For a = 0 To NombreSpriteReserver() - 1
If SpriteSprite(a) <> -1
If SpriteIsPosGlobale(a) = #True
DisplayTransparentSprite(SpriteSprite(a), SpriteX(a) + position_globale\x, SpriteY(a) + position_globale\y)
If SpriteY(a) + position_globale\y > (#terrain_h - 15) * #l
perdu = #True
EndIf
Else
DisplayTransparentSprite(SpriteSprite(a), SpriteX(a), SpriteY(a))
EndIf
EndIf
Next
EndIf
FlipBuffers()
Until EXIT = #True
EndProcedure
;{ macro gradient --> sprite
Macro DrawMode_Gradient_Start(hd_sprite)
qsd_res = GrabDrawingImage(#PB_Any, 0, 0, SpriteWidth(hd_sprite), SpriteHeight(hd_sprite))
StopDrawing()
EndIf
If StartDrawing(ImageOutput(qsd_res))
DrawingMode(#PB_2DDrawing_Gradient)
EndMacro
Macro DrawMode_Gradient_Stop(hd_sprite)
StopDrawing()
EndIf
If StartDrawing(SpriteOutput(hd_sprite))
DrawImage(ImageID(qsd_res), 0, 0)
FreeImage(qsd_res)
EndMacro
Macro DrawBoxedGradient(x, y, w, h)
BoxedGradient(x, y, w, h)
Box(x, y, w, h)
EndMacro
;}
Macro CatchAlien(Alien_label, sprite_number)
Restore Alien_label
Read.l w
Read.l h
CreateSprite(sprite_number, w * #l, h * #l)
If StartDrawing(SpriteOutput(sprite_number))
DrawMode_Gradient_Start(sprite_number)
; GradientColor(1, 0)
GradientColor(1, #White)
GradientColor(0.8, #White)
GradientColor(0, #White)
For b = 0 To h - 1
For a = 0 To w - 1
Read.b c.b
If c
DrawBoxedGradient(a * #l, b * #l, #l, #l)
EndIf
Next
Next
DrawMode_Gradient_Stop(sprite_number)
StopDrawing()
EndIf
EndMacro
;{ on ouvre un ecran
If OpenScreen(#w, #h, 32, "Mechants Alien v" + #VERSION) = 0
End
EndIf
;}
;{ création graphismes
AllocateSprite(100)
;{ création du vaisseau SPRITE 0
CreateSprite(0, #l * 5, #l * 3)
If StartDrawing(SpriteOutput(0))
DrawMode_Gradient_Start(0)
GradientColor(0, $72E510)
GradientColor(1, $724B10)
DrawBoxedGradient(2 * #l, 0, #l, #l)
For a = 0 To 2
DrawBoxedGradient(#l + a * #l, #l, #l, #l)
Next
For a = 0 To 5
DrawBoxedGradient(a * #l, 2 * #l, #l, #l)
Next
DrawMode_Gradient_Stop(0)
StopDrawing()
EndIf
;}
;{ création des sprites ennemis, 10, 11, 12
CatchAlien(alien1, 10)
CatchAlien(alien2, 11)
CatchAlien(alien3, 12)
;}
;{ fond de l'écran, 1
CreateSprite(1, #terrain_w * #l + 1, #terrain_h * #l + 1)
If StartDrawing(SpriteOutput(1))
Box(0, 0, SpriteWidth(1), SpriteHeight(1), #White)
Box(0, 0, SpriteWidth(1) - 1, SpriteHeight(1) - 1, 0)
StopDrawing()
EndIf
AddSprite(1, 0, 0, #False)
;}
;{ tir du phy'sss, 2
CreateSprite(2, #l, 4 * #l)
If StartDrawing(SpriteOutput(2))
Box(0, 0, SpriteWidth(2), SpriteHeight(2), #White)
StopDrawing()
EndIf
;}
;{ tir des ennemis, 3
CreateSprite(3, #l * 3, 4 * #l)
If StartDrawing(SpriteOutput(3))
Box(#l, 0, #l, 4 * #l, #White)
Box(0, 2 * #l, 3 * #l, #l, #White)
StopDrawing()
EndIf
;}
;}
;{ initialisation
; joueur
joueur.sprite\sprite = AddSprite(0, 100, 176 * #l, #False)
joueur\x = SpriteX(joueur\sprite)
joueur\y = SpriteY(joueur\sprite)
joueur\w = SpriteW(joueur\sprite)
joueur\h = SpriteH(joueur\sprite)
;{ ennemis
position_globale\x = 5 * #l
position_globale\y = 5 * #l
vitesse.POINT\x = #l
vitesse\y = 0
Dim ennemis(10, 4)
For a = 0 To 10
ennemis(a, 0) = AddSprite(10, (a * 15 + 3) * #l, 0, #True)
Next
For a = 0 To 10
ennemis(a, 1) = AddSprite(11, (a * 15 + 2) * #l, 15 * #l, #True)
ennemis(a, 2) = AddSprite(11, (a * 15 + 2) * #l, 30 * #l, #True)
Next
For a = 0 To 10
ennemis(a, 3) = AddSprite(12, (a * 15 + 1) * #l, 45 * #l, #True)
ennemis(a, 4) = AddSprite(12, (a * 15 + 1) * #l, 60 * #l, #True)
Next
;}
NewList tir_physss()
NewList tir_ennemis()
vitesse_tir = #l * 2
nb_a_tuer = (ArraySize(ennemis(), 1) + 1) * (ArraySize(ennemis(), 2) + 1)
;}
;{ tread d'affichage
thread_affichage = CreateThread(@DrawSprite(), 0)
If thread_affichage = 0 : End : EndIf
;}
; time2 = ElapsedMilliseconds() - 1
;{ boucle principale
Repeat
;{ calcul temps boucle
; time = ElapsedMilliseconds() - time2
; time2 = ElapsedMilliseconds()
;}
Delay(10)
ExamineKeyboard()
If KeyboardReleased(#PB_Key_Escape) : event = #PB_Event_CloseWindow : EndIf
;{ ajouts tirs physss
If KeyboardReleased(#PB_Key_Space)
AddElement(tir_physss())
tir_physss() = AddSprite(2, joueur\x + joueur\w / 2, joueur\y - 3 * #l, #False)
EndIf
;}
;{ déplacement joueur
If KeyboardPushed(#PB_Key_Left)
joueur\x - #l
If joueur\x < 0 : joueur\x = 0 : EndIf
Sprite_SetX(joueur\sprite, joueur\x)
EndIf
If KeyboardPushed(#PB_Key_Right)
joueur\x + #l
If joueur\x > #terrain_w * #l - joueur\w : joueur\x = #terrain_w * #l - joueur\w : EndIf
Sprite_SetX(joueur\sprite, joueur\x)
EndIf
;}
;{ déplacements ennemis
If nb_a_tuer > nb_ennemis_tues Or perdu = #False
position_globale\x + vitesse\x * #l
position_globale\y + vitesse\y; * #l
timer - 1
If position_globale\x > 75 * #l
vitesse\y = 1
vitesse\x = 0
position_globale\x = 75 * #l
timer = 15
ElseIf position_globale\x < 15 * #l
vitesse\y = 1
vitesse\x = 0
position_globale\x = 15 * #l
timer = 15
EndIf
If timer = 0 And vitesse\x = 0
If position_globale\x = 15 * #l
vitesse\x = 1
Else
vitesse\x = -1
EndIf
vitesse\y = 0
EndIf
EndIf
;}
;{ déplacements tirs
ForEach tir_physss()
Sprite_SetY(tir_physss(), SpriteY(tir_physss()) - vitesse_tir)
If SpriteY(tir_physss()) < 0
DeleteSprite(tir_physss())
DeleteElement(tir_physss())
Else
; controle si on touche un alien
For a = 0 To ArraySize(ennemis(), 1)
For b = 0 To ArraySize(ennemis(), 2)
If ennemis(a, b) <> -1
If SpritePixelCollision(SpriteSprite(ennemis(a, b)), SpriteX(ennemis(a, b)) + position_globale\x, SpriteY(ennemis(a, b)) + position_globale\y, 2, SpriteX(tir_physss()), SpriteY(tir_physss()))
DeleteSprite(ennemis(a, b))
ennemis(a, b) = -1
DeleteSprite(tir_physss())
DeleteElement(tir_physss())
nb_ennemis_tues + 1
Break 2
EndIf
EndIf
Next
Next
EndIf
Next
;}
Until event = #PB_Event_CloseWindow
;}
;{ on arrete le programme proprement
EXIT = #True
WaitThread(thread_affichage)
;}
End
;{ DATA
DataSection
alien1:
Data.l 8, 8
Data.b 0, 0, 0, 1, 1, 0, 0, 0
Data.b 0, 0, 1, 1, 1, 1, 0, 0
Data.b 0, 1, 1, 1, 1, 1, 1, 0
Data.b 1, 1, 0, 1, 1, 0, 1, 1
Data.b 1, 1, 1, 1, 1, 1, 1, 1
Data.b 0, 0, 1, 0, 0, 1, 0, 0
Data.b 0, 1, 0, 1, 1, 0, 1, 0
Data.b 1, 0, 1, 0, 0, 1, 0, 1
alien2:
Data.l 11, 8
Data.b 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0
Data.b 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1
Data.b 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1
Data.b 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1
Data.b 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Data.b 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
Data.b 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0
Data.b 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0
alien3:
Data.l 12, 8
Data.b 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0
Data.b 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
Data.b 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Data.b 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1
Data.b 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Data.b 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0
Data.b 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0
Data.b 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
fin:
EndDataSection
;}
