[2D] Kill Birds
Publié : mar. 11/mars/2014 15:57
Kill Birds (Raz le bol des Flappy Bird Like) : Un tir mode bourrain qui met en oeuvre les animations 2D d'un sprite grâce à l'utilisation conjointe de ClipSprite() et d'une liste chainée.

Code, images et son dans ce fichier compressé.
Télécharger killbirds.zip (Sources 455 Ko)
Utilisez la souris pour déplacer le viseur et le bouton gauche de la souris pour tirer.
L'animation d'un sprite n'est pas simple comparé à d'autres langages. Je vais même finir par aimer certains framework JavaScript dédié au 2D 

Code, images et son dans ce fichier compressé.

Utilisez la souris pour déplacer le viseur et le bouton gauche de la souris pour tirer.
Code : Tout sélectionner
;Kill Birds
EnableExplicit
Enumeration
#font ; Font pour l'affichage du score
#mainform
#background
#ground
#scorepanel
#scoretext
#bird ;Oiseau
#sight ;Viseur
#explosion
#gunshoot ;Son tir
EndEnumeration
Global Event ; Evénement fenetre principale
;Structure type d'un sprite qui servira pour chaque oiseau et chaque explosion.
Structure Sprite
Actif.b ; Actif
x.i ; Position en X du sprite
y.i ; Position en Y du sprite
Animation.i ; Animation en cours
CurrentFrame.i ; Indique quelle image de l'animation est actuellement en cours
FrameWidth.i ; Largeur de chaque image de l'animation
FrameHeight.i ; hauteur de chaque image de l'animation
FrameMax.i ; Nombre d'image maximum pour une animation
FrameRate.i ; Transition entre deux images (Ms)
FrameTimeLife.i ; Indique la durée d'affichage de l'image en cours
VelocityX.i ; Vitesse déplacement en X
VelocityY.i ; Vitesse déplacement en Y
SpriteWidth.i ; Largeur du sprite
SpriteHeight.i ; Hauteur du sprite
Life.i ; Nombre de vie d'un sprite (Aucune utilité dans ce code)
Died.b ; Exemple: Quand l'oiseau est touché il tombe
Opacity.i ; Exemple: Quand un oiseau est mort, l'opacité du sprite est réduite de moitié
EndStructure
Global NewList birds.Sprite(), CountBirds=30, AnimLeft=0, AnimRight=1, AnimDown = 2
Global explosion.sprite, AnimExplosion=0
Global Shoot.b ; Il y a eu un tir (#True)
Global ShootTimeLife ; Durée de vie d'un tir (En Ms)
Global LastShoot ; Quand à eu lieu le dernier tir (en Ms)
Global ShootLife.b ; Un tir est actif
Global Ground ;En quel position se trouve le sol
Global WMouseX.i, WMouseY.i, MouseRelease.b
Procedure Init()
Protected cr.b = #True
LoadFont(#font, "Arial", 25)
UseJPEGImageDecoder()
UsePNGImageDecoder()
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
MessageRequester("Error", "Sprite system can't be initialized", 0)
cr=#False
EndIf
ProcedureReturn cr
EndProcedure
;Creation des oiseaux
Procedure BirdsCreate(Value)
Protected n, Scale
For n =1 To Value
Scale = Random(100, 30)
AddElement(birds())
birds()\Actif = #True
birds()\died = #False
birds()\Animation = AnimLeft
birds()\CurrentFrame = Random(3, 0)
birds()\FrameMax = 4
birds()\FrameWidth = 64
birds()\FrameHeight = 64
birds()\FrameTimeLife = ElapsedMilliseconds()
birds()\FrameRate = 130
birds()\x = Random(700, 100)
birds()\y = Random(400, 50)
birds()\VelocityX = Random(5, 1)*-1
birds()\VelocityY = Random(2, 1)
birds()\SpriteWidth = birds()\FrameWidth * Scale/100
birds()\SpriteHeight = birds()\FrameHeight * Scale/100
birds()\Opacity = 255
Next
EndProcedure
;Les plumes voles (Sprite de 10 images de 200x200 - Frame rate 130ms)
Procedure ExplosionCreate()
explosion\Animation = AnimExplosion
explosion\CurrentFrame=0
explosion\FrameMax = 10
explosion\FrameWidth = 200
explosion\FrameHeight = 200
explosion\FrameTimeLife = ElapsedMilliseconds()
explosion\FrameRate = 130
EndProcedure
;Mise à jour du jeu
Procedure GameUpdate()
DisplaySprite(#background, 0, 0)
DisplaySprite(#ground, 0, 500)
ForEach birds()
;- Animation de chaque oiseau (Quel cirque!!!)
If ElapsedMilliseconds()-birds()\FrameTimeLife > birds()\FrameRate
birds()\FrameTimeLife = ElapsedMilliseconds()
If birds()\CurrentFrame < birds()\FrameMax-1
birds()\CurrentFrame+1
Else
birds()\CurrentFrame=0
EndIf
EndIf
ClipSprite(#bird, birds()\CurrentFrame * birds()\FrameWidth, birds()\Animation * birds()\FrameHeight, birds()\FrameWidth , birds()\FrameHeight)
ZoomSprite(#bird, birds()\SpriteWidth, birds()\SpriteHeight)
DisplayTransparentSprite(#bird, birds()\x, birds()\y, birds()\Opacity)
;- Joueur tire
If MouseButton(#PB_MouseButton_Left) And Shoot = #False
Shoot = #True
ShootLife = #True
PlaySound(#gunshoot)
EndIf
If MouseButton(#PB_MouseButton_Left) = 0
Shoot = #False
EndIf
;- Collision entre le viseur et un oiseau au moment du tir (ShootLife = #True)
; L'oiseau doit etre actif (birds()\Actif = #True)
; L'oiseau n'est pas encore touché (birds()\died = #False)
If SpriteCollision(#sight, MouseX(), MouseY(), #bird, birds()\x, birds()\y) And birds()\died = #False And birds()\Actif = #True
If ShootLife = #True ;On vient de tirer
birds()\died = #True ;L'oiseau est touché
CountBirds-1 ;Un oiseau de moins (Je deteste les Flappy Birds like :p)
explosion\Actif = #True ;Initialisation des plumes qui volent.
;Coordonnées de l'explosion par rapport au point x,y central de l'oiseau.
explosion\x = birds()\x - birds()\FrameWidth
explosion\y = birds()\y - birds()\FrameHeight
EndIf
EndIf
;- Animation explosion (Les plumes voles)
If explosion\Actif = #True
ClipSprite(#explosion, explosion\CurrentFrame * explosion\FrameWidth, explosion\Animation * explosion\FrameHeight, explosion\FrameWidth , explosion\FrameHeight)
DisplayTransparentSprite(#explosion, explosion\x, explosion\y, 255)
If ElapsedMilliseconds()-explosion\FrameTimeLife > explosion\FrameRate
Explosion\FrameTimeLife = ElapsedMilliseconds()
If explosion\CurrentFrame < explosion\FrameMax-1
explosion\CurrentFrame+1
Else
explosion\CurrentFrame=0
explosion\Actif = #False
EndIf
EndIf
EndIf
;-Controle vélocité et rebond des oiseaux dans les limites de la surface de jeu
If birds()\Actif = #True
birds()\x + birds()\VelocityX
If birds()\x < 0 Or birds()\x > 800
birds()\VelocityX *-1
If birds()\VelocityX > 0
birds()\Animation = AnimRight
Else
birds()\Animation = AnimLeft
EndIf
EndIf
Else
birds()\y - birds()\VelocityY
EndIf
;-Un oiseau est touché
If birds()\Died = #True And birds()\Actif = #True
birds()\Animation = AnimDown
birds()\y + (birds()\VelocityY)*3 ;Il tombe 3 fois plus vite
;Il touche le sol
If birds()\y > Ground
birds()\y = ground
birds()\Actif = #False ;Il devient inactif
birds()\Opacity = 128
EndIf
EndIf
Next
;- Controle durée de vie d'un tir
If ShootLife=#True
If ElapsedMilliseconds()-LastShoot > ShootTimeLife
LastShoot = ElapsedMilliseconds()
ShootLife = #False
EndIf
EndIf
;Affiche le viseur
DisplayTransparentSprite(#sight, MouseX(), MouseY(), 255)
;Affichage du score
DisplayTransparentSprite(#scorepanel, 650, 480)
CreateSprite(#scoretext, 120, 60)
StartDrawing(SpriteOutput(#scoretext))
Box(0, 0, 120, 60, RGB(54, 54, 54))
DrawingFont(FontID(#font))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10, 10, Str(CountBirds), RGB(255, 69, 0))
StopDrawing()
RotateSprite(#scoretext, -5, #PB_Absolute)
TransparentSpriteColor(#scoretext, RGB(54, 54, 54))
DisplayTransparentSprite(#scoretext, 685, 475, 255)
EndProcedure
Procedure GameStart()
ShootTimeLife = 500 ;Durée de vie d'un tir en ms
Ground = 450 ;Position vertical du sol
If OpenWindow(#mainform, 0, 0, 800, 600, "Kill Birds", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(#mainform), 0, 0, 800, 600)
;Son tir
LoadSound(#gunshoot, "data/sounds/gunshot.wav")
;Creation de l'animation explosion
ExplosionCreate()
;Image de fond et sol
LoadSprite(#background, "data/images/background.jpg")
LoadSprite(#ground, "data/images/ground.jpg")
;Panneau de score
LoadSprite(#scorepanel, "data/images/panel1.png", #PB_Sprite_AlphaBlending)
ZoomSprite(#scorepanel, 120, 60)
;L'oiseau
LoadSprite(#bird, "data/images/bird.png", #PB_Sprite_AlphaBlending)
;Viseur
LoadSprite(#sight, "data/images/sight.png", #PB_Sprite_AlphaBlending)
ZoomSprite(#sight, 50, 50)
;Explosion
LoadSprite(#explosion, "data/images/iceblaster.png", #PB_Sprite_AlphaBlending)
;Oiseaux
BirdsCreate(CountBirds)
;-Boucle evenementielle
Repeat
Repeat
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
End
EndSelect
Until event=0
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()
ExamineMouse()
GameUpdate()
;- U.T.: Pointeur de la souris en dehors des limites du jeu
WMouseX = WindowMouseX(#Mainform)
WMouseY = WindowMouseY(#Mainform)
If MouseRelease = #True
MouseRelease = #False
EndIf
MouseLocate(WMouseX, WMouseY)
If WMouseX > 0 And WMouseX < WindowWidth(#Mainform, #PB_Window_InnerCoordinate)-1 And
WMouseY > 0 And WmouseY < WindowHeight(#Mainform, #PB_Window_InnerCoordinate)-1
ReleaseMouse(#False)
Else
MouseRelease = #True
ReleaseMouse(#True)
EndIf
;Fin U.T.
Until KeyboardPushed(#PB_Key_Escape)
Else
MessageRequester("Oops", "Erreur lors de la création de la fenêtre 2D", 0)
EndIf
EndIf
EndProcedure
If Init()
GameStart()
Else
MessageRequester("Oops !", "Impossible d'intialiser l'environnement 2D")
EndIf
End
