Really simple sprite system demo actually, but if you look closely, it's showing off something neat:
http://www.seamlesstexturegenerator.com/systems/sprite_system_demo.zip
This is the code that makes it run:
Notice anything special?
Parenting! And it works as better than the parent/child system in Blitz 3D!
Now, when you hide a parent, the children are hidden as well. But their state is maintained, so when you make the parent visible again the children that were visible reappear, and those that weren't, don't.
Alpha is tied to the parent as well. Fade out a parent, and the children fade with it. It will even handle cases where a child is at 50% alpha, and you can even set up a case where the parent is 50% transparent and the child is not, because you can set the alpha for the child to 200%.
Just as in Blitz 3D when you parent a child, and move that child, you move it in parent space. When you scale the parent up, the child scales up, and the position of the child moves to maintain it's position in the now scaled parent space. Rotation works as well.
Each function for getting a sprite's position, scale, alpha, etc, has a global parameter. Set it to false, and you get the sprite's local state, relative to any parent it has. Set it to True, and you get it's global state, or where it actually is, and how it actually looks on the screen. This is all handled through recursion.
Here's a list of all the methods so far:
Why do you want parenting in a sprite system? Well, there's a lot of reasons, but one of the best examples would be where you have a menu. The menu background could be the parent of all the buttons and things inside it. When you want to move the whole thing on or off the screen, you need only animate the parent and all the children will follow along with it.
Anyway, getting all that parenting stuff working was a huge pain. There's a lot of rotation math involved and it's hard to wrap your head around how to invert the transformations so you can parent/unparent a sprite without changing the sprite's position on the screen. Especially at 4am. :-) So that's what I'm most happy with here, and what I'm testing now to make sure it all works right.
http://www.seamlesstexturegenerator.com/systems/sprite_system_demo.zip
This is the code that makes it run:
Include "Swift Sprite System-014.bmx" Graphics 800, 600, 32, 80 AutoMidHandle True Marble:TImage = LoadImage("marble-001.png") S1:Sprite = Sprite.Create(Marble) S2:Sprite = Sprite.Create(Marble) S3:Sprite = Sprite.Create(Marble) S2.SetParent(S1) S3.SetParent(S2) S1.SetPosition(400, 300) S1.SetScale(2, 2) S2.SetPosition(64, 0) S2.SetScale(0.5, 0.5) S3.SetPosition(64, 0) S3.SetScale(0.5, 0.5) Current_Time = MilliSecs() Game_Start_Time = Current_Time Repeat SetClsColor 0, 0, 0 Cls Repeat Time_Old = Current_Time ' Store start time of last frame. Current_Time = MilliSecs() ' Get the current time. Use this instead of Millisecs() from here on if you need the time. Time_Delta = Current_Time - Time_Old ' Calculate how long last frame took to render, in milliseconds. Time_Delta_Sec# = Float(Time_Delta)/1000.0 ' Convert frame time to seconds. Until (Time_Delta > 0) And (Time_Delta < 250) ' Handle unnaturally long pauses between frames gracefully. FPS = 1000.0 / Float(Time_Delta) ' Sprites are animated seperately, so you can move them, then check for collisions, then change their properties/positions, then draw them. ' Sprite.AnimateAll() S1.Rotate(0.25) S2.Rotate(4) Sprite.DrawAll() DrawText FPS, 16, 16 Flip Until KeyHit(KEY_ESCAPE)
Notice anything special?
Parenting! And it works as better than the parent/child system in Blitz 3D!
Now, when you hide a parent, the children are hidden as well. But their state is maintained, so when you make the parent visible again the children that were visible reappear, and those that weren't, don't.
Alpha is tied to the parent as well. Fade out a parent, and the children fade with it. It will even handle cases where a child is at 50% alpha, and you can even set up a case where the parent is 50% transparent and the child is not, because you can set the alpha for the child to 200%.
Just as in Blitz 3D when you parent a child, and move that child, you move it in parent space. When you scale the parent up, the child scales up, and the position of the child moves to maintain it's position in the now scaled parent space. Rotation works as well.
Each function for getting a sprite's position, scale, alpha, etc, has a global parameter. Set it to false, and you get the sprite's local state, relative to any parent it has. Set it to True, and you get it's global state, or where it actually is, and how it actually looks on the screen. This is all handled through recursion.
Here's a list of all the methods so far:
Type Sprite Function Create:Sprite(Image:TImage, Order=0, Parent:Sprite=Null) Method Remove() Method SetParent(NewParent:Sprite, StayStill=False) Method SetOrder(NewOrder) Method SetImage(NewImage:TImage) Method SetFrame(NewFrame#) Method SetBlend(NewBlend) Method SetColor(NewR#, NewG#, NewB#) Method SetAlpha(NewAlpha#) Method SetPosition(NewX#, NewY#, GlobalSpace=False) Method SetRotation(NewRotation#) Method SetScale(NewScaleX#, NewScaleY#) Method SetViewport(NewX#, NewY#, NewWidth#, NewHeight#) Method GetParent:Sprite() Method GetOrder() Method GetImage:TImage() Method GetFrame#() Method GetBlend() Method GetR#(GlobalSpace=False) Method GetG#(GlobalSpace=False) Method GetB#(GlobalSpace=False) Method GetAlpha#(GlobalSpace=False) Method GetX#(GlobalSpace=False) Method GetY#(GlobalSpace=False) Method GetRotation#(GlobalSpace=False) Method GetScaleX#(GlobalSpace=False) Method GetScaleY#(GlobalSpace=False) Method GetViewportX#(GlobalSpace=False) Method GetViewportY#(GlobalSpace=False) Method GetViewportWidth#(GlobalSpace=False) Method GetViewportHeight#(GlobalSpace=False) Method GetWidth#(GlobalSpace=False) Method GetHeight#(GlobalSpace=False) Method GetHidden(GlobalSpace=False) Method Translate(OffsetX#, OffsetY#) Method Rotate(Adjustment#) Method Show() Method Hide() Method Draw() Method Overlaps(Other:Sprite) Function DrawAll() Method Compare(OtherObject:Object) End Type
Why do you want parenting in a sprite system? Well, there's a lot of reasons, but one of the best examples would be where you have a menu. The menu background could be the parent of all the buttons and things inside it. When you want to move the whole thing on or off the screen, you need only animate the parent and all the children will follow along with it.
Anyway, getting all that parenting stuff working was a huge pain. There's a lot of rotation math involved and it's hard to wrap your head around how to invert the transformations so you can parent/unparent a sprite without changing the sprite's position on the screen. Especially at 4am. :-) So that's what I'm most happy with here, and what I'm testing now to make sure it all works right.