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à (bravo d’ailleurs)
[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
;}