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.