AnimateSprite (ALL OS) - AnimateSprite3D (Windows only)

Share your advanced PureBasic knowledge/code with the community.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

AnimateSprite (ALL OS) - AnimateSprite3D (Windows only)

Post by J. Baker »

I'm sure this code could still be optimized but it works. Thanks to Kaeru Gaman for helping me. In order to use AnimateSprite3D, you will need the ClipSprite3D code from here. I've include the ZoomSprite3D in the procedure that ClipSprite3D requires in order to set the correct size of the sprite. This works with multiple animated sprites (set up For 0 To 99 animated sprites).

Sprite3D - #Sprite3D.
ClipWidth- Width of the clipped sprite.
ClipHeight- Height of the clipped sprite.
FramesPerRow - The number of frames per row.
StartFrame - Start at any given frame number (from left to right).
EndFrame - Stop at any given frame number, that's greater then StartFrame.
FpsDelay - 0 equals no delay. 1 and higher adjust the fps for fast delays in your main Repeat / Until loop. This helps if your animated sprite has a lower framerate then your delay.

AnimateSprite3D() (AnimateSprite() is in post below)
Updated June 2, 2009

Code: Select all

Structure SpriteCalculations
XStart.l
YStart.l
XEnd.l
YEnd.l
Loop.l
NextFrame.l
EndStructure

Procedure AnimateSprite3D(Sprite3D, ClipWidth, ClipHeight, FramesPerRow, StartFrame, EndFrame, FpsDelay)

Static Dim Sprites.SpriteCalculations(99)

  Sprites(Sprite3D)\Loop + 1

If Sprites(Sprite3D)\Loop = 1

     Sprites(Sprite3D)\XStart = ((StartFrame % FramesPerRow) * ClipWidth) - ClipWidth
      If XStart = 0 - ClipWidth
          XStart = (ClipWidth * FramesPerRow) - ClipWidth
      EndIf
     Sprites(Sprite3D)\YStart = Round((StartFrame / FramesPerRow), #PB_Round_Down) * ClipHeight

     Sprites(Sprite3D)\XEnd = ((EndFrame % FramesPerRow) * ClipWidth)
      If XEnd = 0 - ClipWidth
          XEnd = (ClipWidth * FramesPerRow) - ClipWidth
      EndIf
     Sprites(Sprite3D)\YEnd = Round((EndFrame / FramesPerRow), #PB_Round_Down) * ClipHeight
     
EndIf

  ZoomSprite3D(Sprite3D, ClipWidth, ClipHeight)

  ClipSprite3D(Sprite3D, Sprites(Sprite3D)\XStart, Sprites(Sprite3D)\YStart, ClipWidth, ClipHeight)
  
If Sprites(Sprite3D)\NextFrame = FpsDelay

  If EndFrame > StartFrame
     Sprites(Sprite3D)\XStart + ClipWidth
  EndIf
    
   If Sprites(Sprite3D)\XStart = ClipWidth * FramesPerRow
       Sprites(Sprite3D)\XStart = 0
       Sprites(Sprite3D)\YStart + ClipHeight
   EndIf
   
   If Sprites(Sprite3D)\XStart >= Sprites(Sprite3D)\XEnd And Sprites(Sprite3D)\YStart >= Sprites(Sprite3D)\YEnd
       Sprites(Sprite3D)\Loop = 0
   EndIf

     Sprites(Sprite3D)\NextFrame = 0

 Else 
     
     Sprites(Sprite3D)\NextFrame + 1

EndIf

EndProcedure
Last edited by J. Baker on Sun Jul 31, 2011 7:58 am, edited 15 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Here's a procedure for AnimateSprite(). This is almost the same as above except it's for normal sprites (not Sprite3D). This works with multiple animated sprites (it's set up For 0 To 99 animated sprites).

AnimateSprite()
Updated July 31, 2011

Code: Select all

Structure SpriteCalculations
XStart.l
YStart.l
XEnd.l
YEnd.l
Loop.l
NextFrame.l
FrameNumber.l
StartNow.l
EndStructure

Procedure AnimateSprite(Sprite, ClipWidth, ClipHeight, FramesPerRow, StartFrame, EndFrame, FpsDelay)

  Static Dim Sprites.SpriteCalculations(99)
  
  If Sprites(Sprite)\StartNow = 0
    Sprites(Sprite)\NextFrame = FpsDelay
    Sprites(Sprite)\StartNow +1
  EndIf

  Sprites(Sprite)\Loop + 1

If Sprites(Sprite)\Loop = 1

     Sprites(Sprite)\XStart = ((StartFrame % FramesPerRow) * ClipWidth) - ClipWidth
      If XStart = 0 - ClipWidth
          XStart = (ClipWidth * FramesPerRow) - ClipWidth
      EndIf
     Sprites(Sprite)\YStart = Round((StartFrame / FramesPerRow), #PB_Round_Down) * ClipHeight

     Sprites(Sprite)\XEnd = ((EndFrame % FramesPerRow) * ClipWidth)
      If XEnd = 0 - ClipWidth
          XEnd = (ClipWidth * FramesPerRow) - ClipWidth
      EndIf
     Sprites(Sprite)\YEnd = Round((EndFrame / FramesPerRow), #PB_Round_Down) * ClipHeight
     
EndIf

  ClipSprite(Sprite, Sprites(Sprite)\XStart, Sprites(Sprite)\YStart, ClipWidth, ClipHeight)
  
If Sprites(Sprite)\NextFrame = FpsDelay 

  If EndFrame > StartFrame
     Sprites(Sprite)\XStart + ClipWidth
  EndIf
    
   If Sprites(Sprite)\XStart = ClipWidth * FramesPerRow
       Sprites(Sprite)\XStart = 0
       Sprites(Sprite)\YStart + ClipHeight
   EndIf
   
   If Sprites(Sprite)\XStart >= Sprites(Sprite)\XEnd And Sprites(Sprite)\YStart >= Sprites(Sprite)\YEnd
       Sprites(Sprite)\Loop = 0
   EndIf

    Sprites(Sprite)\NextFrame = 1
    
   If Sprites(Sprite)\FrameNumber = (EndFrame - StartFrame) +1
       Sprites(Sprite)\FrameNumber = 0
   EndIf
    
    Sprites(Sprite)\FrameNumber +1

 Else 
     
    Sprites(Sprite)\NextFrame + 1

EndIf
  
  ProcedureReturn Sprites(Sprite)\FrameNumber
  
EndProcedure

Code: Select all

ReturnFrame = AnimateSprite(Sprite, ClipWidth, ClipHeight, FramesPerRow, StartFrame, EndFrame, FpsDelay)
Last edited by J. Baker on Sat Jun 02, 2012 11:18 pm, edited 9 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Edited source for both AnimateSprite3D() & AnimateSprite() so both procedures share the same settings.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Here is some source and images to show how AnimateSprite works. Set the Library Subsystem to DirectX9.

The flower sprite wasn't animated at the same frame rate as the smurf sprite when I made them. And this is where setting the FpsDelay helps correct playback speed.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Post by jamirokwai »

Hi J. Baker,

just to inform you... Works on Mac OS X without DirectX... :)
Nice finding! Could be usefull for my own projects. Thanks!
Regards,
JamiroKwai
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

jamirokwai wrote:Hi J. Baker,

just to inform you... Works on Mac OS X without DirectX... :)
Nice finding! Could be usefull for my own projects. Thanks!
Thanks for testing it on a Mac. Does the clipped sprites work correctly using OpenGL on the Mac? On windows when using OpenGL the sprites don't clip properly. When the smurf is done walking, both smurfs should be in a standing stance with arms facing down (in my source test in post 4).

EDIT: When clipped correctly it should look like the second smurf by the flower.
Image
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Post by jamirokwai »

J. Baker wrote:EDIT: When clipped correctly it should look like the second smurf by the flower.
This is how it looks on the Mac:

Image

I saw your png has 4x4 images. What if one image is empty, eg. you only
put 15 images instead of 16 in there. Is there some kind of error-check??
I didn't check the source, but if there is no check, the Smurf would have a
gap in his animation... :wink:
Regards,
JamiroKwai
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

There's a bug with ClipSprite( ) when using OpenGL. I was just hoping it was a bug in windows only. But I've already posted it in the Bugs-Windows on this forum. I'll update it and say it's a bug for OpenGL period.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Updated the AnimateSprite procedure in the second post. The OpenGL bug for a clipped sprite was fixed by Fred and will be updated in the next PB release.

EDIT: Now works properly with the OpenGL subsystem in PB 4.31 Beta 1 and up.
Last edited by J. Baker on Tue Jun 02, 2009 5:49 pm, edited 3 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

jamirokwai wrote:I saw your png has 4x4 images. What if one image is empty, eg. you only put 15 images instead of 16 in there. Is there some kind of error-check?? I didn't check the source, but if there is no check, the Smurf would have a gap in his animation... :wink:
Yeah it checks. That's why it ask for StartFrame & EndFrame. Sorry for the delay in responding. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Updated the AnimateSprite() procedure in the second post. There were a couple of issues. But now everything works fine. But there is still one known issue. You can't use StartFrame at the end of a row. For example...

Let's say you have a sprite sheet that's 512x512. And each sprite is 128x128. You can't start at 0x384, 128x384, ect. But of course you can end at the end of a row. I will try to fix that though.

Also, NumberOfFrames was removed as it's no longer needed due to rewrite. But it still works the same as before.

EDIT: Updated AnimateSprite3D() in the first post.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: AnimateSprite3D & AnimateSprite

Post by J. Baker »

I've updated AnimateSprite() procedure but I didn't update AnimateSprite3D() procedure as I made a AnimateSprite3D() procedure that is cross platform and can be found here, http://www.purebasic.fr/english/viewtop ... 12&t=46988 . But I left the old AnimateSprite3D() procedure (windows only) here just in case you prefer it and are coding for windows only.

The updated AnimateSprite() procedure now returns its current frame. This is helpful if your animated sprite has collision with another sprite but you may want to do different things depending on the frame its currently on.

Also, I notice when I added this, there was a very slight delay on starting the animation in the old procedure that is now fixed in this updated procedure.

Enjoy! ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
PHP
User
User
Posts: 65
Joined: Sat Sep 10, 2005 5:38 pm

Re: AnimateSprite (ALL OS) - AnimateSprite3D (Windows only)

Post by PHP »

Any new update for PB5?
deesko
User
User
Posts: 39
Joined: Fri Sep 21, 2012 11:40 pm
Location: Portugal

Re: AnimateSprite (ALL OS) - AnimateSprite3D (Windows only)

Post by deesko »

PHP wrote:Any new update for PB5?
I tested the code provided in the zipfile on PB 5.30 x64 Win 8.1, I just needed to change a few lines:

Code: Select all

CatchSprite(0, ?Pic0, #PB_Sprite_AlphaBlending)
CatchSprite(1, ?Pic0, #PB_Sprite_AlphaBlending)
CatchSprite(2, ?Pic1, #PB_Sprite_AlphaBlending)
Since CatchSprite no longer supports #PB_Sprite_Texture constant (Also note an optimization there, no need to supply a double of the animation);

and

Code: Select all

DataSection
  Pic0:
    IncludeBinary "images\smurf.png"
  Pic1:
    IncludeBinary "images\flower.png"
EndDataSection
Instead of the one provided (again the optimized code, only supplies one copy of smurf.png instead of two).
User avatar
N_Gnom
User
User
Posts: 76
Joined: Fri Sep 13, 2013 3:20 pm
Location: Germany

Re: AnimateSprite (ALL OS) - AnimateSprite3D (Windows only)

Post by N_Gnom »

Does this work completly?
Or can anyone post a full sourcecode?
Post Reply