Ayant un peu de temps ces jours-ci j'ai repris une idée de jeu en Iso3D.
Et j'aurais voulu avoir votre avis sur ma façon de faire pour la map.
Théorie:
Pour moi la map est constitué d'élément. Chaque élément ayant plusieurs état, état pouvant être un sprite ou une animation. L'animation d'un élément peut être global ou Unique:
Exemple:
1)Animation Global : de l'eau qui coule, tout les éléments sur la carte on la même animation au même moment.
2)Animation Unique :Une porte que vous ouvrez, il n'y a que cette porte qui s'ouvre et pas les autres. l'animation est unique
Dans le cas de l'animation Global, l'animation se gère au niveau de l'élément.
Au niveau de l'animation Unique, l'animation se gère au niveau de la Map.
Et je pensais aussi a la possibilité de coller un script a un Element si une action est entrepris sur cet element (marché dessus, pousser, tirer, regarder, etc...)
j'espère que suis claire

Pratique:

Au vu de tout ça je pense procéder comme ça :
Ce code n'est pas encore opérationel. j'aurais voulu avoir votre avis sur ma reflexion et ma façon de faire avant d'aller plus loin. merci d'avance a tout ceux qui auront prit le temps de me lire

Code : Tout sélectionner
;- #### Animation ####
; *Animation DataSheet
; Offset | Size | Type | Description
; 0 | 2 | .w | Frames
; 2 | 1 | .b | 0 No Loop Animation / 1 Loop Animation
; 3 | 4 | * | IdSprite Frame[ 1]
; 7 | 2 | .w | Temps d'affichage en milliseconde
; 9 | 4 | * | IdSprite Frame[ 2]
; 13 | 2 | .w | Temps d'affichage en milliseconde
; 3+x*6 | 4 | * | IdSprite Frame[ x]
; 7+x*6 | 2 | .w | Temps d'affichage en milliseconde
;etc....
;Ajout d'un sprite a une animation
Procedure SetSpriteToAnimation(*Anim, IdSprite.l, Time.w)
If *Anim>0
Size.l = MemorySize(*Anim)
Else
Size.l = 3
*Anim = AllocateMemory(Size)
EndIf
*Anim = ReAllocateMemory(*Anim, Size + 6)
PokeW(*Anim, PeekW(*Anim) + 1)
PokeL(*Anim + Size, IdSprite)
PokeW(*Anim + Size + 4, Time)
ProcedureReturn *Anim
EndProcedure
;Retourne le sprite correspondant a l'image d'une Animation
Procedure.l GetSpriteFromAnimation(*Anim, Frame.w)
Debug "Frame:"+Str(Frame)+" Anim:"+Str(*Anim)
Location.l = 3 + Frame*6
If Location<MemorySize(*Anim)
ProcedureReturn PeekL(*Anim + Location) :
Else
ProcedureReturn #False
EndIf
EndProcedure
;Retourne le temps d'affichage d'une imge dans une animation
Procedure.l GetTimeSpriteFromAnimation(*Anim, Frame.w)
Location.l = 7 + Frame*6
If Location<MemorySize(*Anim)
Debug "time:"+Str(PeekW(*Anim + Location))
ProcedureReturn PeekW(*Anim + Location) :
Else
ProcedureReturn #False
EndIf
EndProcedure
;Active ou desactive le bouclage de l'annimation
Procedure.b SetAnimationLoop(*Anim, Loop.b)
If *Anim>0
PokeB(*Anim + 2, Loop)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;Retourne le nombre d'image dans une animation
Procedure GetFramesAnimation(*Anim)
ProcedureReturn PeekW(*Anim)
EndProcedure
;Retourne 1 si l'animation est Bouclé et 0 dans le cas contraire
Procedure.b GetAnimationLoop(*Anim)
If *Anim>0
ProcedureReturn PeekB(*Anim + 2)
EndIf
EndProcedure
;-#### Element ####
; *Element DataSheet
; Offset | Size | Type | Description
; 0 | 2 | .w | States
; 2 | 1 | .b | 0 l'animation est Global / 1 l'animation est unique
; 3 | 2 | .w | CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
; 5 | 4 | .l | Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
; 9 | 1 | .b | 0 IdSprite / 1 *Animation State[1]
; 10 | 4 | * | IdSprite or *Animation State[1]
; 14 | 1 | .b | 0 IdSprite / 1 *Animation State[2]
; 15 | 4 | * | IdSprite or *Animation State[2]
; 9+x*5 | 1 | .b | 0 IdSprite / 1 *Animation State[x]
; 10+x*5 | 4 | * | IdSprite or *Animation State[x]
Procedure DebugElement(*Element)
Debug"__________"
Debug "Element:"+Str(*Element )
Debug "States :"+Str(PeekW(*Element)); 0 | 2 | .w | States
Debug "Animation Type :"+Str(PeekB(*Element+2)); 2 | 1 | .b | 0 l'animation est Global / 1 l'animation est unique
Debug "CurrentFrame:"+Str(PeekW(*Element+3)); 3 | 2 | .w | CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
Debug "NextTime:"+Str(PeekL(*Element+3));; 5 | 4 | .l | Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
For z=0 To PeekW(*Element)-1
Debug "Type"+Str(z+1)+" :"+Str(PeekB(*Element+9*z*5)); 9 | 1 | .b | 0 IdSprite / 1 *Animation State[1]
Debug "Sprite/Anim"+Str(z+1)+" :"+Str(PeekL(*Element+10*z*5)); 10 | 4 | * | IdSprite or *Animation State[1]
Next
EndProcedure
;Rajoute une animation ou une image a un Element
Procedure SetStatetoElement(*Element, *Anim, IdSprite = 0)
If *Element>0 ;si l'element existe on regarde sa taille
Size.l = MemorySize(*Element)
Else ;si l'element n'existe pas on le créer
Size.l = 9
*Element = AllocateMemory(Size)
PokeB(*Element+2,0)
EndIf
*Element = ReAllocateMemory(*Element , Size + 5)
PokeW(*Element, PeekW(*Element) + 1) ;Ajout d'un etat
State=PeekW(*Element)-1
Debug "State"
If *Anim>0 ; Si c'est une Animation
PokeB(*Element+9+State*5, 1)
PokeL(*Element+10+State*5, *Anim)
Debug PeekW(*Element)
Debug "ajout d'une Anim"
Debug PeekL(*Element+10+State*5)
Else ; Si c'est un Sprite
PokeB(*Element+9+State*5, 0)
PokeL(*Element+10+State*5, IdSprite)
Debug "ajour d'un sprite"
EndIf
ProcedureReturn *Element
EndProcedure
;position l'animation d'un element
Procedure SetFrameToElement(*Element, Frame.w)
PokeW(*Element + 3, Frame)
EndProcedure
;-#### Map ####
;*Map(Coord X, Coord Y, Level)
#MapMaxWidth = 512
#MapMaxHeight = 512
#MapMaxLevel = 4
Structure Map
*Element ;Pointeur vers l'element
ElementState.w ;Etat de l'element
Time.l ;Si l'animation est uniquel alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
IdScript.l ;Script lors d'un action sur cet Element
EndStructure
Global Dim Map.Map(#MapMaxWidth, #MapMaxHeight, #MapMaxLevel)
Procedure GetSpriteFromMap(X.l, Y.l, L.l)
*Element = Map(X, Y, L)\Element;
State=(Map(X, Y, L)\ElementState+1)-1
If PeekB(*Element + 9 + State*5) = 0 ;Si c'est un Sprite
ProcedureReturn PeekL(*Element + 10 + State*5);On retourne l'idsprite
Else ;Si c'est une animation
*Anim = PeekL(*Element + 10 + State*5)
If PeekB(*Element + 2) = 0 ;Si l'animation est Global
Frame.w = PeekW(*Element + 3)
If PeekL(*Element + 5) = 0 :
PokeL(*Element + 5, ElapsedMilliseconds()+GetTimeSpriteFromAnimation(*Anim, Frame))
EndIf
If ElapsedMilliseconds()>PeekL(*Element + 5);Si le temps s'est écoulé pour cette image
Frame.w + 1;on passe a l'image suivante
If Frame>GetFramesAnimation(*Anim)-1 ; si on depasse le nombre d'image du film
SetAnimationLoop(*Anim,#True)
If GetAnimationLoop(*Anim) = #True ;Si on boucle
Frame = 0
Else
Frame-1
EndIf
EndIf
SetFrameToElement(*Element,Frame);On rafraichit l'image courante
PokeL(*Element + 5, ElapsedMilliseconds() + GetTimeSpriteFromAnimation(*Anim, Frame));(On note quand est ce qu'on passera a l'image suivante
EndIf
EndIf
ProcedureReturn GetSpriteFromAnimation(*Anim, Frame.w)
EndIf
EndProcedure
;###############################################################################
;On test
;###############################################################################
InitSprite()
OpenWindow(0, 0, 0, 640, 480, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0)
;Creation d'une animation
*Anim = 0
For z = 0 To 10
CreateSprite(z, 64, 64)
StartDrawing(SpriteOutput(z))
Box(0, 0, 64, 64, #Blue)
Circle(z*6, 32, 4, #Red)
StopDrawing()
*Anim = SetSpriteToAnimation(*Anim, z, 500)
Next
;Creation d'un Element et attribution d'une animation
*Element=0
*Element = SetStatetoElement(*Element, *Anim)
DebugElement(*Element)
Debug"______"
Map(0, 0, 0)\Element = *Element
Repeat
; Il est très important de traiter tous les événements restants dans la file d'attente à chaque tour
;
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
FlipBuffers()
ClearScreen(RGB(0, 0, 0))
Sprite=GetSpriteFromMap(0,0,0)
DisplaySprite(Sprite,128,128)
Delay(1)
ForEver