Jump to content
dennis

[LUA] animated sprite sheet ?

Recommended Posts

Hi there,

 

I was wondering how I can do animated sprite sheets for explosions, fx effecs and waterfalls?

Have searched around the forums and haven't found anything.

 

Thanks in common.

 

Dennis

Share this post


Link to post

No, it would take millions of very small particles to make fire like this. It could be made with particles simulation in blender, but in the game it has to be animated sprite.

Share this post


Link to post

No, it would take millions of very small particles to make fire like this. It could be made with particles simulation in blender, but in the game it has to be animated sprite.

 

Will try it when I arrive home. Still working :/

Share this post


Link to post

I might be able to help you with this one, i also checked out the shadmar's firepit but considering i'm horrible with shaders just yet, it wasn't the best example to play with haha (it's still good! Don't get me wrong in that wink.png ) i did however found another post which is from macklebee which showed how to draw small parts from a texture. With this you can create your own "animation" function and sequence it in the way you like! I'm currently still at school and almost finished, when i get home i'll show you exactly what i mean wink.png

 

For now, here is a link; http://www.leadwerks.com/werkspace/topic/12537-drawing-a-section-of-a-2d-texture-setting-uv-coords/#entry90453

 

This is currently my (messy?;P) code to animate it


Script.original_W = 280/1.5
Script.original_H = 280/1.5
Script.texture_W = 280
Script.texture_H = 280
Script.screen_W = 600
Script.screen_H = 600
Script.animate = false
Script.currentAnim_X = 0
Script.currentAnim_Y = 0

in start:
self.soul_Essence_Anim = {}


self.soul_Essence_Tex = Texture:Load("Materials/Hud/Soul Essence Anim2.tex")
self.texture_W = self.soul_Essence_Tex:GetWidth()/1.5
self.texture_H = self.soul_Essence_Tex:GetHeight()/1.5

in updateWorld()
if self.animate and not upgradeScreen and not paused then
self.currentAnim_X = Math:Inc((self.texture_W/self.original_W)-1,self.currentAnim_X,1)
if self.currentAnim_X == (self.texture_W/self.original_W)-1 then
self.animate = false
self.currentAnim_X = (self.currentAnim_Y == 2 and (self.texture_W/self.original_W)-1 or 0)
if self.currentAnim_Y < 2 then self.currentAnim_Y = self.currentAnim_Y + 1 end
end
end

in the postrender stuff
self.shader_Spritesheet:SetVec2("uvcoords", Vec2(self.currentAnim_X,self.currentAnim_Y))--set uvcoords in shader
self.shader_Spritesheet:SetVec2("zoom", Vec2(self.texture_W/self.original_W,self.texture_H/self.original_H))--set zoom in shader

 

Short explanation: self.texture_W and _H get the current full texture size with all the animated sequences in.

self.original_W and _H are the size of the actual picture you want to animate.

currentAnim_X goes through the horizontal animation and currentAnim_Y goes through the vertical one.

 

What i did here is pretty much first go through the first set of animation then set it to the second row and do the same and so on.

 

My animated spritesheet:

 

8314553bbe.png

 

I actually went on way longer then intended haha, i hope this helps somewhat with your current question smile.png Let me know if you need more information and i'll come back at you as soon i get home!

 

Goodluck happy.png

 

 

EDIT: In this example i mostly focused on the 2D screen draw, but this is also usable on sprites! When i'm home i'll give you an example that i made with the sprite ^^

Share this post


Link to post

Awesome!

 

Still at work too, got ten more minutes to survive.

But will check that out and Like to see that sprite.

But what if you just attach the script to a regular sprite object in the editor ?

That way it just will work right ?

Share this post


Link to post

Still at school aswell haha, waiting for the last conversation with my teacher tongue.png

I'll make screenshots of the sprite as soon as i get home wink.png Currently i got no mouse and my CTRL button is broken on my laptop which makes it pretty hard to do this haha.

As far i know it should also still work, if i remember right i did this that exact way. I got the information which texture is on the sprite and then used the animating script on it. Another way which is possible, is just create the sprite object the way you want it and then attach the script to it and do all the texture from within the script and attach it to the sprite with self.entity:SetTexture(*texture*)

 

So yes, that should work happy.png

 

Edit: Fixed confusing typo :P

Share this post


Link to post

I felt so bad that i almost forgot to post here again while i got home (My day has really been crazy and busy haha when i got home i just started playing a game and relax :P)

 

Eitherway! I promised a screenshot ^^ Now, this might not be the best screenshot but i suppose it does the trick

f04b6e4a6a.jpg

 

You mostly need to look at the part where the origin of the beam is. I have checked this project again (been weeks that i have visited this due my exam project with the animated sprite sheet example that i posted earlier) and i noticed that i created the sprite inside the script.

 

Spritesheet:

1e0a3450dc.png

 

When i first started making things in leadwerks i tended to do this to understand the lua scripting method a bit more. (if i explain it right hehe)

 

Eitherway! To the point!

 

I just realized by looking at my code.. That i used a different method for the sprite.. That is a bit embarrassing.

But! I got my own solution ^_^ (The shader i'm currently using is a small variation on the earlier mentioned of the shadmar's firepit which is mostly edited speed & images considering mine always needed to loop)

 

Right, to get my piece of code;

 

Option 1:
-- Full spritesheet size
Script.texture_W = 300
Script.texture_H = 100
-- Size of 1 frame
Script.original_w = 50
Script.original_H = 50
-- Current Frame Position
Script.currentAnim_X = 0
Script.currentAnim_Y = 0
Script.animate = false
function Start()
self.sprite = Sprite:Create()
self.sprite_Material = Material:Load("*material name*.mat")
self.sprite:SetMaterial(self.sprite_Material)
local texture = self.sprite_Material:GetTexture()
self.texture_W = texture:GetWidth()
self.texture_H = texture:GetHeight()
self.sprite.Shader = self.sprite_Material:GetShader()
end
function UpdateWorld()
if window:KeyHit(Key.Space) then self.animate = true end
if self.animate then
 self.currentAnim_X = Math:Inc((self.texture_W/self.original_W)-1,self.currentAnim_X,1)
 if self.currentAnim_X == (self.texture_W/self.original_W)-1 then
  self.animate = false
  -- I used this method to check if the animation reached the last spot of the spritesheet or not. If not, reset it to 0 on the next layer. If
  --yes, keep it at the end.
  self.currentAnim_X = (self.currentAnim_Y == 2 and (self.texture_W/self.original_W)-1 or 0) 

  -- Check if this is on the last row of the animation, this can probably be done better but i have very limited time in my project hence
  -- the dirty way ( I would recommended checking the Height of your sheet and dividing it by the height of the frame )
  if self.currentAnim_Y < 2 then self.currentAnim_Y = self.currentAnim_Y + 1 end
 end
end

self.shader_Spritesheet:SetVec2("uvcoords", Vec2(self.currentAnim_X,self.currentAnim_Y))--set uvcoords in shader
self.shader_Spritesheet:SetVec2("zoom", Vec2(self.texture_W/self.original_W,self.texture_H/self.original_H))--set zoom in shader
end

 

With this method, you can use the whole spritesheet on a material so that you can attach it to a sprite (My mistake earlier! I thought it was a texture that was attached!) and then you can attach the shader of macklebee to the material.

The code will get the shader from the material and use it's information to what it needs to do.

 

#2: Another option is: (i would've loved to add it above in the code part aswell but i'm awful tired at 2:35 haha)

This is similar to the above code, but instead you create the whole material inside the code and attach the texture + shader to it.

This will only change the way and over complicate (in my opinion) it in the "Start()" function. Ofcourse, if this is what you desire, go nuts :)

 

Yet another option that i thought up right now;

You create the sprite in the editor itself, add the material that has the texture & shader attached (or well, you could not do that and go partly option 2 with over complicating inside the start script :P) then you attach a Script that has the above method handling in the UpdateWorld() (Or, you could place it elsewhere, whatever you desire the most ofcourse)

While having in the Start() the information of the texture a bit the same way we did above, but instead of loading a material, we'll just do "sprite_Material = self.entity:GetMaterial()" and the rest of the process would be pretty much the same.

 

I hope i explained it enough this way ^_^ i hope i didn't went overboard with my wall of text haha, i just like to be detailed and well, hopefully understandable ofcourse :)

 

If there are any questions left, let me know and i'll try to reply ASAP! (This time for sure :) )

 

Another thing; Excuses if i might go a bit overboard with my "emoticons". I tend to use them alot, especially when i'm excited ^_^ (see? There i go again haha) i try to reduce this to a minimum and not flooding the post with it :)

Share this post


Link to post

Well this is perfect haha.

Thanks for your help ! :D Will login later today on my PC, problem is I ain't got very much time, Have to built a gaming pc for some budy of mine. But before that I will certainly check the code you wrote :o. Wouldn't be cool If I didn't right? ;)

I wish you all the luck with your exams :D

Share this post


Link to post

Haha, take your time ^_^ That's one of the most important things :D

And thanks ^_^ can't wait to be done with my exams and just go on rampage with all the things i wanted to test haha :D

Share this post


Link to post

Glad to hear mate!

When I'm back on my laptop (within a few mins) I'll post the full solution here for anyone that also wants to achieve the same thing ;)

Since we changed some stuff ;)

Share this post


Link to post

Complete spritesheet lua & shader + an example spritesheet on how it works smile.png

 

Steps to follow:

1. Create a sprite in the scene.

2. Attach the Custom spritesheet.lua

3. Attach the "testing" material to it.

4. Run the game!

 

Now, this is a very basic one. If you want to use an other spritesheet, all you have to do it change the Frame width & height in the Script tab smile.png (of 1 frame!!)

And if you desire to change the speed, change the frame speed, this sets the actual speed at how fast the animation will go (the lower the number, the faster it goes smile.png )

 

And that's all to it! Enjoy happy.png

 

Credits to shadmar's original spritesheet shader from his fire pit :) (I modified it slightly for this purpose)

 

http://puu.sh/pLljg/40232be99f.zip

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...