Code : Tout sélectionner
;*************************
;*** ***
;*** GoSprite Engine ***
;*** ***
;*************************
;- Constantes
#GOSE_VERSION = "0.4"
#QUOTE = Chr(34)
#MAXSPR = 100 ; NB MAX SPRITE
#VALWALK = 5 ; Vitesse
#VALRUN = 20
#VALLANCE = 30
#Fnt_Width = 16 ; Largeur de la fonte
#Fnt_Height = 16 ; Hauteur de la fonte
;- Structures
Structure SPR
Spr.l[#MAXSPR] ; #MAXSPR sprites possibles par image
EndStructure
Structure MYSPRITE
spr_num.l
spr_color.l
spr_max.l
spr_width.l
spr_height.l
sprite.SPR
EndStructure
;=========================================================================
;- Declarations
;=========================================================================
Declare GS_Error(num_error.l, val_error.l = 0)
;=========================================================================
;- Procedures
;=========================================================================
Procedure OpenWin()
If OpenWindow(0, 0, 0, 380, 240, "GOSE v"+#GOSE_VERSION, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
ButtonGadget(0, 330, 210, 45, 25, "Quit")
EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, 320, 240, 0, 0, 0)
Else
MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
End
EndIf
EndIf
EndProcedure
;> Procedure GS_Init()
Procedure GS_Init()
If UsePNGImageDecoder() And InitSprite() And InitKeyboard()
Global NewList Sprite.SPR()
Global NewList Spr.MYSPRITE()
Global Quit.l = 0
Global knight.l, ring.l, fnt.l, fnt2.l
Global player1.l, player2.l, top_score.l, score.l, game_over.l
Global SpriteFileName.s = ""
Else
GS_Error(100)
EndIf
EndProcedure
;> Procedure GS_Error(num_error.l, val_error.l = 0)
Procedure GS_Error(num_error.l, val_error.l = 0)
Protected Text_Error.s
Select num_error
Case 100
Text_Error = "CAN'T INITIALIZE GRAPHICS !"
Case 101
Text_Error = "Unknow frame number"
Case 102
Text_Error = "Cannot create Image"
Case 103
Text_Error = "Cannot load sprite "+#QUOTE+SpriteFileName+#QUOTE
Default
Text_Error = "Unknow !!!"
EndSelect
If val_error > 0 : Text_Error + " #"+Str(val_error) : EndIf
MessageRequester("[ ERROR ]",Text_Error)
End
EndProcedure
;> Procedure.l GS_LoadAnimSprite(FileName.s,spr_Width.l,spr_Height.l,NB_Frame.l = 1,maskcolor.l = -1)
Procedure.l GS_LoadAnimSprite(FileName.s,spr_Width.l,spr_Height.l,NB_Frame.l = 1,maskcolor.l = -1)
Protected spr_num.l, image_width.l, image_height.l, nb_sprite_width.l
Protected spr_new.l, spr_color.l, colonne.l, x.l, y.l
SpriteFileName = FileName
If ReadFile(0,filename)
spr_num = LoadSprite(#PB_Any,filename) ;attribution automatique d'un n° de sprite
image_width = SpriteWidth(spr_num) ;Largeur de l'image
nb_sprite_width = image_width / spr_width ;nbre de sprites max par la largeur
If maskcolor = -1
StartDrawing(SpriteOutput(spr_num))
spr_color = Point(0,0) ;retourne automatiquement la couleur du fond pour la transparence
StopDrawing()
Else
spr_color = maskcolor ;sinon on met la couleur demandée
EndIf
AddElement(Spr())
Spr()\spr_num = spr_num
Spr()\spr_color = spr_color
Spr()\spr_max = NB_Frame
Spr()\spr_width = spr_width
Spr()\spr_height = spr_height
;Partie du code permetant la récupération des sprites
;exemple :
;
;fichier image contient 5 sprites (NB_Frame)
;max de large = 3 car image_width / spr_width = 3 (nb_sprite_width)
;
; <----------- image_width ----------->
;
; colonne=1
; +-----------+-----------+-----------+
; !<--------->! ^ ! !
; ! spr_width ! | ! !
; ! ! spr_height! !
; ! ! | ! !
; ! ! | ! !
; ! 1! v 2! 3!
; +-----------+-----------+-----------+
; ! ! !
; ! ! !
; ! ! !
; ! ! !
; ! ! !
; ! 4! 5!
; +-----------+-----------+
colonne = 1 ;à partir de la 1ere colonne
x = y = 0 ;on commence à la position 0,0
UseBuffer(spr_num) ;utilise le sprite chargé en mem
For i = 1 To NB_Frame
spr_new = GrabSprite(#PB_Any,x,y,spr_width,spr_height) ;selectionne une partie pour créer un nouveau frame
Spr()\Sprite\Spr[i] = spr_new ;ajout du nouveau frame dans liste chainée
TransparentSpriteColor(spr_new, spr_color) ;définit son maskcolor (pour la transparence)
If colonne % nb_sprite_width = 0 ;si le reste de la div = 0
colonne = 1 : x = 0 : y + spr_height ;on va a la ligne suivante
Else
colonne + 1 : x + spr_width ;sinon on continue sur la même ligne
EndIf
Next i
UseBuffer(-1) ;retour buffer précédent
ProcedureReturn spr_num
Else
GS_Error(103)
EndIf
EndProcedure
;> Procedure GS_DrawSprite(Sprite.l,X.l,Y.l,Frame.l = 1)
Procedure GS_DrawSprite(Sprite.l,X.l,Y.l,Frame.l = 1)
Protected spr.l
FirstElement(Spr())
While Spr()\spr_num <> Sprite
NextElement(Spr())
Wend
If frame > Spr()\spr_max : GS_Error(101,Frame) : EndIf
spr = Spr()\Sprite\Spr[frame]
DisplayTransparentSprite(spr, X, Y)
EndProcedure
;> Procedure GS_DrawText(Font.l, X.l,Y.l,Text$)
Procedure GS_DrawText(Font.l, X.l,Y.l,Text$)
Protected OldX.l = X
Protected position.l
For i = 1 To Len(Text$)
position = (Asc(Mid(Text$, i, 1)))-31 ;31 car on commence à partir du sprite 1 (sinon 32 si commence à 0)
GS_DrawSprite(Font, OldX, Y, position)
OldX = OldX + #Fnt_Width
Next
EndProcedure
;> Procedure.l GS_MakeSpriteText(Font.l, Text$, Color.l)
Procedure.l GS_MakeSpriteText(Font.l, Text$, Color.l)
Protected SprID.l, spr_width.l, spr_height.l, ccolor.l
FirstElement(Spr())
While Spr()\spr_num <> Font
NextElement(Spr())
Wend
spr_width = Spr()\spr_width * Len(Text$)
spr_height = Spr()\spr_height
SprID = CreateSprite(#PB_Any, spr_width, spr_height)
If SprID
StartDrawing(SpriteOutput(SprID))
Box(0, 0, spr_width, spr_height, Color)
StopDrawing()
UseBuffer(SprID)
GS_DrawText(Font, 0, 0, Text$)
UseBuffer(-1)
; StartDrawing(SpriteOutput(SprID))
; ccolor = Point(0,0)
; StopDrawing()
;
; TransparentSpriteColor(SprID, ccolor) ;couleur de la fonte est égale à RGB(0,0,0)
TransparentSpriteColor(SprID, 0) ;couleur de la fonte est égale à RGB(0,0,0)
AddElement(Spr())
Spr()\spr_num = SprID
Spr()\spr_color = color
Spr()\spr_max = 1
Spr()\spr_width = SpriteWidth(SprID)
Spr()\spr_height = SpriteHeight(SprID)
Spr()\Sprite\Spr[1] = SprID
ProcedureReturn SprID
Else
GS_Error(102)
EndIf
EndProcedure
;=========================================================================
;- Programme Principal
;=========================================================================
GS_Init()
OpenWin()
knight = GS_LoadAnimSprite("Knight_walk.png",48,72,12)
ring = GS_LoadAnimSprite("ring.png",64,64,4)
fnt = GS_LoadAnimSprite("GNG_Fnt.png",#Fnt_Width,#Fnt_Height,94)
fnt2 = GS_LoadAnimSprite("GNG_Fnt.png",#Fnt_Width,#Fnt_Height,94,$FFFFFF) ;$BBGGRR = RGB(255,255,255))
ecran = GS_LoadAnimSprite("ecran3.png",100,64,1,RGB(255,0,255))
player1 = GS_MakeSpriteText(fnt2, "PLAYER #", RGB(238,204,0))
player2 = GS_MakeSpriteText(fnt2, "PLAYER $", RGB(238,204,0))
top_score = GS_MakeSpriteText(fnt2, "TOP_SCORE", RGB(255,0,102))
game_over = GS_MakeSpriteText(fnt2, "GAME OVER", RGB(255,136,136))
score = GS_MakeSpriteText(fnt2, "10000", RGB(255,255,255))
ResetList(Spr())
direction = #VALWALK
direction2 = #VALRUN
direction3 = #VALLANCE
x = 25 : x2 = 200 : x3 = 0
spr_knight_walk = 1 ; numéro du sprite du chevalier qui marche
spr_knight_run = 3 ; numéro du sprite du chevalier qui court
spr_knight_lance = 9 ; numéro du sprite du chevalier qui lance
spr_ring = 1 ; numéro du sprite de l'anneau
ecr_x = 320-100
ecr_y = 240-64
Pas_x = 20
Pas_y = 10
Repeat
ExamineKeyboard()
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 0
quit = 1
EndIf
Case #PB_Event_CloseWindow
quit = 1
EndSelect
Until Event = 0
If KeyboardPushed(#PB_Key_Escape) : quit = 1 : EndIf
; ====== AFFICHAGE ======
FlipBuffers()
ClearScreen(RGB(150, 100, 50))
; *** Fond d'écran
For i = 1 To 50
ax = Random(320 - 64)
ay = Random(240 - 64)
aspr = 1 + Random(3)
GS_DrawSprite(ring,ax,ay,aspr)
Next i
; *** Animation des sprites
GS_DrawSprite(ring,0,0,spr_ring)
GS_DrawSprite(knight,x,0,spr_knight_walk)
GS_DrawSprite(knight,x2,80,spr_knight_run)
GS_DrawSprite(knight,x3,160,spr_knight_lance)
; *** Affichages fixes
GS_DrawText(fnt,0,240-16,"GOSE "+#GOSE_VERSION+" %Flaith 07")
GS_DrawText(fnt,0,16,Str(ecr_x)+"/"+Str(ecr_y))
GS_DrawSprite(player1,0,0)
GS_DrawSprite(top_score,180,0)
GS_DrawSprite(score,240,20)
GS_DrawSprite(game_over,100,112)
; GS_DrawSprite(ecran,0,0)
; GS_DrawSprite(ecran,100,0)
; GS_DrawSprite(ecran,200,0)
; GS_DrawSprite(ecran,300,0)
GS_DrawSprite(ecran,ecr_x,ecr_y)
; *** Sprites suivants
spr_knight_walk + 1
spr_knight_run + 1
spr_knight_lance + 1
spr_ring + 1
; *** Vérification des sprites à afficher
If direction > 0
If spr_knight_walk > 2 : spr_knight_walk = 1 :EndIf
Else
If spr_knight_walk > 6 : spr_knight_walk = 5 :EndIf
EndIf
If direction2 > 0
If spr_knight_run > 4 : spr_knight_run = 3 :EndIf
Else
If spr_knight_run > 8 : spr_knight_run = 7 :EndIf
EndIf
If direction3 > 0
If spr_knight_lance > 10 : spr_knight_lance = 9 :EndIf
Else
If spr_knight_lance > 12 : spr_knight_lance = 11 :EndIf
EndIf
If spr_ring > 4 : spr_ring = 1 : EndIf
; *** Vérification des coordonnées de l'écran à afficher
If KeyboardPushed(#PB_Key_Up) : ecr_y - Pas_y : EndIf
If KeyboardPushed(#PB_Key_Down) : ecr_y + Pas_y : EndIf
If KeyboardPushed(#PB_Key_Left) : ecr_x - Pas_x : EndIf
If KeyboardPushed(#PB_Key_Right) : ecr_x + Pas_x : EndIf
If ecr_x > 320-100 : ecr_x = 320-100 : EndIf
If ecr_x < 0 : ecr_x = 0 : EndIf
If ecr_y > 240-64 : ecr_y = 240-64 : EndIf
If ecr_y < 0 : ecr_y = 0 : EndIf
; *** Modification de la direction chevalier marchant
x + direction
If x > 320-48 : direction = -#VALWALK : spr_knight_walk = 5 : EndIf
If x < 0 : direction = #VALWALK : spr_knight_walk = 1 : EndIf
; *** Modification de la direction chevalier courant
x2 + direction2
If x2 > 320-48 : direction2 = -#VALRUN : spr_knight_run = 7 : EndIf
If x2 < 0 : direction2 = #VALRUN : spr_knight_runk = 3 : EndIf
; *** Modification de la direction chevalier glissant ???
x3 + direction3
If x3 > 320-48 : direction3 = -#VALLANCE : spr_knight_lance = 11 : EndIf
If x3 < 0 : direction3 = #VALLANCE : spr_knight_lance = 9 : EndIf
; *** Delai pour le process
Delay(60)
Until quit = 1
End




---
Note : fonctionne aussi bien sous GNU/Linux que sous Windows