
Code: Select all
;*************************
;*** ***
;*** GoSprite Engine ***
;*** ***
;*************************
;- Constantes
#GOSE_VERSION = "0.4.4"
#QUOTE = Chr(34)
#FULLSCREEN = #False
#Screen_width = 800
#Screen_height = 600
#depth = 32
#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 Not #FULLSCREEN
If OpenWindow(0, 0, 0, #Screen_width+80, #Screen_height, "GOSE v"+#GOSE_VERSION, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
ButtonGadget(0, #Screen_width+20, #Screen_height-30, 45, 25, "Quit")
EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, #Screen_width, #Screen_height, 0, 0, 0)
Else
MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
End
EndIf
EndIf
Else
OpenScreen(#Screen_width, #Screen_height, #depth, "GOSE v"+#GOSE_VERSION)
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, player1.l, player2.l, top_score_txt.l, top_score.l, score_p1.l, score_p2.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
;>Procedure.l GS_GetFPS()
; Procedure.l GS_GetFPS()
; Static timerFrames.l, timerFPS.l, oldtime.l
;
; timerFrames + 1
; If ElapsedMilliseconds()-OldTime >= 1000
; OldTime = ElapsedMilliseconds()
; timerFPS = timerFrames
; timerFrames = 0
; EndIf
;
; ProcedureReturn timerFPS
; EndProcedure
Procedure.l GS_GetFPS()
Static time_init.l, time_fps.l, count_fps.l, number_FPS.l
time_init = ElapsedMilliseconds()
If time_init - time_fps <= 1000
count_fps + 1
Else
number_FPS = count_fps
count_fps = 0
time_fps = time_init
EndIf
ProcedureReturn number_FPS
EndProcedure
;>Procedure GS_Flip(RefreshRate.l)
Procedure GS_Flip(RefreshRate.l)
Static timer.f
timer = ElapsedMilliseconds() - timer
If timer <= 1000/RefreshRate
Delay( Int( (1000/RefreshRate) - timer ) )
EndIf
FlipBuffers()
timer = ElapsedMilliseconds()
EndProcedure
; ::::: Procedures Locales :::::
Structure ANIM
x.l
y.l
frame.l
speed.l
count.l
EndStructure
Procedure Init_BackGround(nbcount.l)
Global NewList spranim.ANIM()
For i = 1 To nbcount
AddElement(spranim())
spranim()\x = Random(#Screen_width - 64)
spranim()\y = Random(#Screen_height - 64)
spranim()\frame = 1 + Random(3)
spranim()\speed = Random(10)
spranim()\count = 0
Next i
EndProcedure
Procedure Draw_BackGround(sprite,max_frame)
ForEach spranim()
GS_DrawSprite(sprite,spranim()\x,spranim()\y,spranim()\frame)
If spranim()\count < spranim()\speed
spranim()\count + 1
Else
spranim()\frame + 1
If spranim()\frame > max_frame : spranim()\frame = 1 : EndIf
spranim()\count = 0
EndIf
Next
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))
player2_x = #Screen_width - SpriteWidth(player2)
score_p1 = GS_MakeSpriteText(fnt2, "10000", RGB(255,255,255))
score_p2 = GS_MakeSpriteText(fnt2, "0", RGB(255,255,255))
score_p2_x.l = #Screen_width - SpriteWidth(score_p2)
top_score_txt = GS_MakeSpriteText(fnt2, "TOP SCORE", RGB(255,0,102))
top_score_txt_x.l = (#Screen_width - SpriteWidth(top_score_txt))/2
game_over = GS_MakeSpriteText(fnt2, "GAME OVER", RGB(255,136,136))
game_over_x.l = (#Screen_width - SpriteWidth(game_over))/2
game_over_y.l = (#Screen_height - SpriteHeight(game_over))/2
top_score = GS_MakeSpriteText(fnt2, "100,000,000", RGB(255,255,255))
top_score_x = top_score_txt_x + SpriteWidth(top_score_txt) - SpriteWidth(top_score)
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
ecr_x = #Screen_width-100
ecr_y = #Screen_height-64
Pas_x = 20
Pas_y = 10
Init_BackGround(400) ; creation du fond d'écran avec 200 anneaux
Repeat
ExamineKeyboard()
If Not #FULLSCREEN
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
EndIf
If KeyboardPushed(#PB_Key_Escape) : quit = 1 : EndIf
; ====== AFFICHAGE ======
; FlipBuffers()
GS_Flip(35)
ClearScreen(RGB(150, 100, 50))
; *** Fond d'écran
; For i = 1 To 50
; ax = Random(#Screen_width - 64)
; ay = Random(#Screen_height - 64)
; aspr = 1 + Random(3)
; GS_DrawSprite(ring,ax,ay,aspr)
; Next i
Draw_BackGround(ring,4)
; *** Animation des sprites
GS_DrawSprite(knight,x,0,spr_knight_walk)
GS_DrawSprite(knight,x2,80,spr_knight_run)
GS_DrawSprite(knight,x3,160,spr_knight_lance)
; *** FPS
GS_DrawText(fnt,0,64,"FPS:"+Str(GS_GetFPS()))
; *** Affichages fixes
GS_DrawText(fnt,0,#Screen_height-16,"GOSE "+#GOSE_VERSION+" % Flaith 2007")
GS_DrawText(fnt,0,48,Str(ecr_x)+"/"+Str(ecr_y))
GS_DrawSprite(player1,0,0)
GS_DrawSprite(player2,player2_x,0)
GS_DrawSprite(score_p1,0,20)
GS_DrawSprite(score_p2,score_p2_X,20)
GS_DrawSprite(top_score_txt,top_score_txt_x,0)
GS_DrawSprite(top_score,top_score_x,20)
GS_DrawSprite(game_over,game_over_x,game_over_y)
GS_DrawSprite(ecran,ecr_x,ecr_y)
; *** Sprites suivants
spr_knight_walk + 1
spr_knight_run + 1
spr_knight_lance + 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 > #Screen_width-100 : ecr_x = #Screen_width-100 : EndIf
If ecr_x < 0 : ecr_x = 0 : EndIf
If ecr_y > #Screen_height-64 : ecr_y = #Screen_height-64 : EndIf
If ecr_y < 0 : ecr_y = 0 : EndIf
; *** Modification de la direction chevalier marchant
x + direction
If x > #Screen_width-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 > #Screen_width-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 > #Screen_width-48 : direction3 = -#VALLANCE : spr_knight_lance = 11 : EndIf
If x3 < 0 : direction3 = #VALLANCE : spr_knight_lance = 9 : EndIf
Until quit = 1
End




---
Nota : run under GNU/Linux & Windows