[games] Events et actions
Publié : jeu. 19/sept./2013 19:28
salut
J'essaie de tester un système d'event et d'action façon Game maker (pour ceux qui connaissent).
Voici le code que j'ai commencé pour étudier ça (je veux un code très simple) :
J'aimerai avoir votre avis sur ce système.
Pensez-vous que ce soit une bonne technique (ça doit permettre d'être "générique", c'est à dire s'adapter au maximum de situation) ?
Vous pouvez aussi m'indiquer votre FPS, chez moi, ça tourne à 32/33.
J'essaie de tester un système d'event et d'action façon Game maker (pour ceux qui connaissent).
Voici le code que j'ai commencé pour étudier ça (je veux un code très simple) :
Code : Tout sélectionner
;{ enumeration
#window_main = 0
; Fixé par le créateur du jeu, dans PGC
#canvas = 0
#WindowWidth = 640
#WindowHeight = 480
#FPSMax = 40 ; le FPS souhaité (approximation à environ -7)
Enumeration EventObject
; les events de chaque objets
#EventCreate
#EventStep
#EventDraw
#EventDestroy
EndEnumeration
Enumeration EventGame
; les events généraux du jeu
#EvtGame_GameStart
#EvtGame_GameEnd
#EvtGame_RoomStart
#EvtGame_RoomEnd
#EvtGame_Step
EndEnumeration
;}
;{ structure
Structure ST_object
Name$
; event
Event.i
EventCreate.a
EventDestroy.a
; pour certains event, pour vérifier si on les a ajouté
EventDraw.a
; autre paramètres
Life.w
SpriteId.i
X.w
Y.w
EndStructure
Global NewList Object.ST_object()
;}
;{ variable
Global ObjectId.i, Exit.a, EventGame.a, Room.a, Color.i
;}
;{ Declare
Declare RoomGotoNext()
Declare GameEnd()
;}
;{ procedures
;{ Event Actions pour objets
Procedure EO_Create(List Obj.ST_object())
If Obj()\EventCreate = 0
Debug "Create " + Obj()\Name$
Obj()\EventCreate = 1
Obj()\Event = #EventStep
EndIf
EndProcedure
Procedure Instance_Create(List Obj.ST_object())
AddElement(Obj())
With Obj()
\Name$ = "Obj_" + ObjectId
ObjectId + 1
\Life = 20 + Random(20)
\X = Random(#WindowWidth)
\Y = Random(#WindowHeight)
\Event = #EventCreate
\EventDraw = 1 ; on a ajouté un code dans l'event draw
; le sprite
\SpriteId = CreateSprite(#PB_Any, 64, 64)
If \SpriteId
If StartDrawing(SpriteOutput(\SpriteId))
Box(0, 0, 64, 64, RGB(Random(255), Random(255), Random(255)))
StopDrawing()
EndIf
EndIf
EndWith
EndProcedure
Procedure EO_Step(List Obj.ST_object())
;{ begin step
;}
;{ step
; un code par exemple
If Obj()\X > - 64
Obj()\X - 1
Else
Obj()\x = #WindowWidth
EndIf
Obj()\Life - 1
If Obj()\life <= 0
Obj()\Event = #EventDestroy; <-- action destroy
EndIf
;}
;{ End step
;}
EndProcedure
Procedure Instance_number(List Obj.ST_object())
ProcedureReturn ListSize(obj())
EndProcedure
Procedure EO_Draw(List Obj.ST_object())
DisplaySprite(Obj()\SpriteId, Obj()\x, Obj()\y)
EndProcedure
Procedure EO_Destroy(List Obj.ST_object())
If Obj()\EventDestroy = 0
Obj()\EventDestroy = 1
Debug "Destroy"
DeleteElement(Obj(),1)
EndIf
; un code par exemple, sur l'event Destroy
; on crée une instance au hasard quand on détruit l'objet
Hasard = Random(1)
If hasard = 1
Instance_Create(Obj())
EndIf
; exemple d'ajout d'un code
If Instance_number(Obj()) <=0
Debug "plus d'instance de l'objet"
RoomGotoNext()
EndIf
EndProcedure
;}
;{ Event Generaux
Procedure RoomGotoNext()
EventGame = #EvtGame_RoomEnd
Debug "RoomGotoNext"
EndProcedure
Procedure GameStart()
Debug "GameStart"
; On lance les actions issues du GameStart
EventGame = #EvtGame_RoomStart
EndProcedure
Procedure GameEnd()
EventGame = #EvtGame_GameEnd
EndProcedure
Procedure GameEvents()
Select EventGame
Case #EvtGame_Step
;{ event Step
; le step de chaque objet
ForEach Object()
Select Object()\event
Case #EventCreate
EO_Create(Object())
Case #EventStep
EO_Step(Object())
;EO_Draw(object())
Case #EventDestroy
EO_Destroy(Object())
EndSelect
Next
;}
Case #EvtGame_RoomStart
;{ event Roomstart
; on fait les actions de l'event Roomstart
Debug "Room Start: " + Room
;{ Par exemple on crée 3 objets pour commencer (avec soit un code room soit un objet ayant lui-même ce code)
For i = 0 To 2
Instance_Create(Object())
Next i
;}
; puis on passe à l'évent Step
EventGame = #EvtGame_Step
;}
Case #EvtGame_RoomEnd
;{ event RoomEnd
Debug "Room End : " + Room
If Room > 3 ; le nombre de room qu'on aura créée
Debug "Room : " + Room
GameEnd()
Else
Room + 1
Color = RGB(50 + Random(50),50 + Random(50),50 + Random(50))
EventGame = #EvtGame_RoomStart
EndIf
;}
Case #EvtGame_GameEnd
;{ event GameEnd
; actions pour la fin du jeu
Debug "GameEnd"
; sortie de boucles
Exit = 1
;}
EndSelect
EndProcedure
Procedure GameDraw()
; event draw general
ClearScreen(0)
If StartDrawing(ScreenOutput())
; un fond
Box(0, 0, #WindowWidth, #WindowHeight, Color)
DrawText(200,0, "Room "+Str(Room) + " - Nb Objets : " + Str(ListSize(Object())))
StopDrawing()
EndIf
ForEach Object()
If Object()\EventDraw = 0
DisplaySprite(Object()\SpriteId, Object()\x, Object()\y)
Else
EO_Draw(object())
EndIf
Next
FlipBuffers()
EndProcedure
Procedure FPS()
Shared s, fps
ss = Second(Date())
fps + 1
If s <> ss
SetWindowTitle(0,"FPS: "+Str(FPS))
s = ss
fps = 0
EndIf
EndProcedure
;}
;}
;{ window & Loop
If InitSprite() : EndIf
If OpenWindow(#window_main, 0, 0, #WindowWidth, #WindowHeight, "Game Events", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
If OpenWindowedScreen(WindowID(#window_main), 0, 0, #WindowWidth, #WindowHeight, 1, 0, 0)
; Init the game
Room = 1
Color = RGB(Random(50), Random(50), Random(50))
; on lance la première room
GameStart()
Repeat
Event = WindowEvent()
If ElapsedMilliseconds() > CheckTime + 1000/#FPSMax
CheckTime = ElapsedMilliseconds()
GameEvents()
GameDraw()
FPS()
Else
Delay(1)
EndIf
; autre : menu, par exemple ?
Until event = #PB_Event_CloseWindow Or Exit = 1
EndIf
EndIf
;}
Pensez-vous que ce soit une bonne technique (ça doit permettre d'être "générique", c'est à dire s'adapter au maximum de situation) ?
Vous pouvez aussi m'indiquer votre FPS, chez moi, ça tourne à 32/33.