15. Table sprite

A table sprite inherit from renderizable and implement all methods as usual.. Each animation on sprite has an initial frame and final frame which represent its cycle. Also each animation has a shader table by default which can be accessed by getShader method.

15.1. sprite methods

15.1.1. sprite new

new(string * world, number * x, number * y, number * z)

Create a new instance of a sprite passing the world desired (detail) and position.

Parameters
  • stringworld can be 2ds, 2dw or 3d.

  • numberx position (optional).

  • numbery position (optional).

  • numberz position (optional).

Returns

sprite table.

Example:

tSpt = sprite:new('2dw') --note that sprite inherits from renderizable

15.1.2. sprite load

load(string file_name)

Load a sprite from file (expected .spt extension).

Parameters

stringfile name from file.

Example:

tSprite = sprite:new('3d')
if tSprite:load('mario.spt') then
   print('Successfully loaded sprite:','mario.spt')
else
   print('Failed to loaded sprite:','mario.spt')
end

Note

The load method will search in all known path.
You can add a path to search by the method addPath.

15.2. Creating a sprite programmatically

Here an example how to create an sprite programmatically using the engine to do that.

It is possible to save any mesh with help of meshDebug. For that it is necessary to prepare the meshDebug based on our renderizable.

  • First, we have to create coordinates of vertex buffer.

  • We also need to create index buffer (1 index based) for the vertex.

  • Then we create a meshDebug which will store all the information.

  • The UV and normal coordinates are not mandatory. For this example we will not fill it.

  • Next we create a frame informing the stride (for sprite will be 2) and add a new subset.

  • One frame can have one or more subsets. Each subset has its own texture.

  • Next we add the vertex buffer and index buffer.

  • The vertex buffer can have normal buffer (optional) and texture coordinates (optional).

  • Next we set the sprite type (others types are mesh, particle, font, …).

  • Finally we just need to specify the file name to save through the function save.

15.2.1. Sprite to a binary file

For the first example we will use the following texture:

_images/HB_smile.png

Figure 15.1 smile.png

download.

Follow the first example how to save a sprite to a binary file:

 1 mbm.setColor(1,1,1) --set background color to white
 2 
 3 function createFace()
 4 
 5    local tFace = {  {x=-50, y= -50},
 6                     {x=-50, y=  50},
 7                     {x= 50, y= -50},
 8                     {x= 50, y=  50}}
 9    local tIndex = {1,2,3, 3,2,4}
10    local sTextureFileName = 'HB_smile.png'
11 
12    return tFace, tIndex, sTextureFileName
13 end
14 
15 function saveMeshToBinaryFile(fileName,tVertex,tIndex,sTexture)
16 
17     --meshDebug is used to create dynamically mesh in the engine.
18     --For sprite it has to have at least one frame to be able to generate the sprite
19     local stride      = 2 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
20     local tMesh       = meshDebug:new() --new mesh debug to store the information about our sprite
21     local nFrame      = tMesh:addFrame(stride) -- Add one frame with stride 2 (x,y)
22     local indexFrame  = nFrame   --(meshDebug uses 1 based index)
23     local indexSubset = 1 --first subset (1 based index)
24    
25    
26     --To add vertex, first we need to add a subset
27     local nSubset     = tMesh:addSubSet(indexFrame) --add one subset for the first frame
28 
29     --we are adding vertex to frame (next)
30     --this vertex list has to have at least 3 vertex (one triangle) to be valid
31     -- The table expected is : {{x,y},{x,y},{x,y}, ...}
32     if not tMesh:addVertex(indexFrame,indexSubset,tVertex) then 
33         print("Error on add vertex buffer")
34         return false
35     end
36     
37     if not tMesh:addIndex(indexFrame,indexSubset,tIndex) then 
38         print("Error on add index buffer")
39         return false
40     end
41 
42     --apply the texture to frame / subset
43     if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
44         print("Error on set texture!")
45         return false
46     end
47 
48     tMesh:setType('sprite')  -- set it to sprite type
49 
50     local calcNormal,calcUv = false,true --Instruct to do not calculate normal but calcule UV
51     if tMesh:save(fileName,calcNormal,calcUv) then
52         print("Sprite created successfully ")
53         return true
54     else
55         print("Failed to create sprite!")
56         return false
57     end
58     
59 end
60 
61 
62 function onInitScene()
63 
64     tSprite = sprite:new('2DW')-- our object which will load from binary file
65 
66     local sFileNameSprite = 'smile.spt'
67 
68     local tFaceVertex, tFaceIndex, sTextureFileName = createFace()--create our face 
69 
70     if saveMeshToBinaryFile(sFileNameSprite,tFaceVertex, tFaceIndex, sTextureFileName) then
71         tSprite:load(sFileNameSprite) --all coordinate already in place
72     else
73         print('Failed to create ' .. sFileNameSprite)
74         mbm.quit()
75     end
76 
77 end

download.

_images/sprite_creating_example_1.png

Figure 15.2 Example 1 creating sprite

Follow other example how to save a sprite to a binary file setting uv coordinates:

 1 mbm.setColor(1,1,1) --set background color to white
 2 
 3 function createFaceUv()
 4 
 5    local tFace = {  {x=-50, y= -50, u=0, v=1},
 6                     {x=-50, y=  50, u=0, v=0},
 7                     {x= 50, y= -50, u=1, v=1},
 8                     {x= 50, y=  50, u=1, v=0}}
 9    local tIndex = {1,2,3, 3,2,4}
10    local sTextureFileName = 'HB_smile.png'
11 
12    return tFace, tIndex, sTextureFileName
13 end
14 
15 function saveMeshToBinaryFile(fileName,tVertex,tIndex,sTexture)
16 
17     --meshDebug is used to create dynamically mesh in the engine.
18     --For sprite it has to have at least one frame to be able to generate the sprite
19     local stride      = 2 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
20     local tMesh       = meshDebug:new() --new mesh debug to store the information about our sprite
21     local nFrame      = tMesh:addFrame(stride) -- Add one frame with stride 2 (x,y)
22     local indexFrame  = nFrame   --(meshDebug uses 1 based index)
23     local indexSubset = 1 --first subset (1 based index)
24    
25    
26     --To add vertex, first we need to add a subset
27     local nSubset     = tMesh:addSubSet(indexFrame) --add one subset for the first frame
28 
29     --we are adding vertex to frame (next)
30     --this vertex list has to have at least 3 vertex (one triangle) to be valid
31     -- The table expected is : {{x,y},{x,y},{x,y}, ...}
32     if not tMesh:addVertex(indexFrame,indexSubset,tVertex) then 
33         print("Error on add vertex buffer")
34         return false
35     end
36     
37     if not tMesh:addIndex(indexFrame,indexSubset,tIndex) then 
38         print("Error on add index buffer")
39         return false
40     end
41 
42     --apply the texture to frame / subset
43     if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
44         print("Error on set texture!")
45         return false
46     end
47 
48     tMesh:setType('sprite')  -- set it to sprite type
49 
50     local calcNormal,calcUv = false,false --Instruct to do not calculate normal and UV
51     if tMesh:save(fileName,calcNormal,calcUv) then
52         print("Sprite created successfully ")
53         return true
54     else
55         print("Failed to create sprite!")
56         return false
57     end
58     
59 end
60 
61 
62 function onInitScene()
63 
64     tSprite = sprite:new('2DW')-- our object which will load from binary file
65 
66     local sFileNameSprite = 'smile.spt'
67 
68     local tFaceVertex, tFaceIndex, sTextureFileName = createFaceUv()--create our face and uv coordinates
69 
70     if saveMeshToBinaryFile(sFileNameSprite,tFaceVertex, tFaceIndex, sTextureFileName) then
71         tSprite:load(sFileNameSprite) --all coordinate already in place
72     else
73         print('Failed to create ' .. sFileNameSprite)
74         mbm.quit()
75     end
76 
77 end

download.

_images/sprite_creating_example_2.png

Figure 15.3 Example 2 setting uv to create a sprite

Follow other example how to save a sprite to a binary file setting uv coordinates upside down:

 1 mbm.setColor(1,1,1) --set background color to white
 2 
 3 function createFaceUvUpSideDown()
 4 
 5    local tFace = {  {x=-50, y= -50, u=0, v=0},
 6                     {x=-50, y=  50, u=0, v=1},
 7                     {x= 50, y= -50, u=1, v=0},
 8                     {x= 50, y=  50, u=1, v=1}}
 9    local tIndex = {1,2,3, 3,2,4}
10    local sTextureFileName = 'HB_smile.png'
11 
12    return tFace, tIndex, sTextureFileName
13 end
14 
15 function saveMeshToBinaryFile(fileName,tVertex,tIndex,sTexture)
16 
17     --meshDebug is used to create dynamically mesh in the engine.
18     --For sprite it has to have at least one frame to be able to generate the sprite
19     local stride      = 2 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
20     local tMesh       = meshDebug:new() --new mesh debug to store the information about our sprite
21     local nFrame      = tMesh:addFrame(stride) -- Add one frame with stride 2 (x,y)
22     local indexFrame  = nFrame   --(meshDebug uses 1 based index)
23     local indexSubset = 1 --first subset (1 based index)
24    
25    
26     --To add vertex, first we need to add a subset
27     local nSubset     = tMesh:addSubSet(indexFrame) --add one subset for the first frame
28 
29     --we are adding vertex to frame (next)
30     --this vertex list has to have at least 3 vertex (one triangle) to be valid
31     -- The table expected is : {{x,y},{x,y},{x,y}, ...}
32     if not tMesh:addVertex(indexFrame,indexSubset,tVertex) then 
33         print("Error on add vertex buffer")
34         return false
35     end
36     
37     if not tMesh:addIndex(indexFrame,indexSubset,tIndex) then 
38         print("Error on add index buffer")
39         return false
40     end
41 
42     --apply the texture to frame / subset
43     if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
44         print("Error on set texture!")
45         return false
46     end
47 
48     tMesh:setType('sprite')  -- set it to sprite type
49 
50     local calcNormal,calcUv = false,false --Instruct to do not calculate normal and UV
51     if tMesh:save(fileName,calcNormal,calcUv) then
52         print("Sprite created successfully ")
53         return true
54     else
55         print("Failed to create sprite!")
56         return false
57     end
58     
59 end
60 
61 
62 function onInitScene()
63 
64     tSprite = sprite:new('2DW')-- our object which will load from binary file
65 
66     local sFileNameSprite = 'smile.spt'
67 
68     local tFaceVertex, tFaceIndex, sTextureFileName = createFaceUvUpSideDown()--create our face upside down
69 
70     if saveMeshToBinaryFile(sFileNameSprite,tFaceVertex, tFaceIndex, sTextureFileName) then
71         tSprite:load(sFileNameSprite) --all coordinate already in place
72     else
73         print('Failed to create ' .. sFileNameSprite)
74         mbm.quit()
75     end
76 
77 end

download.

_images/sprite_creating_example_3.png

Figure 15.4 Example 3 setting uv upside down to create a sprite

15.2.2. Sprite animated to a binary file

Next one example how to create animated sprite.

We will use four different image for this example:

_images/HB_smile.png

Figure 15.5 smile

download HB_smile.png

_images/HB_sad.png

Figure 15.6 sad

download HB_sad.png

_images/HB_neutral.png

Figure 15.7 neutral

download HB_neutral.png

_images/HB_dead.png

Figure 15.8 dead

download HB_dead.png

 1 mbm.setColor(1,1,1) --set background color to white
 2 
 3 function createOneFrame(sTexture)
 4 
 5    local tVertex = {  {x=-50, y= -50, u=0, v=1},
 6                     {x=-50, y=  50, u=0, v=0},
 7                     {x= 50, y= -50, u=1, v=1},
 8                     {x= 50, y=  50, u=1, v=0}}
 9    local tIndex = {1,2,3, 3,2,4}
10 
11    return {tVertex = tVertex, tIndex = tIndex, sTexture = sTexture }
12 end
13 
14 function saveMeshToBinaryFile(fileName,tFrames)
15 
16     --meshDebug is used to create dynamically mesh in the engine.
17     --For sprite it has to have at least one frame to be able to generate the sprite
18     local stride      = 2 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
19     local tMesh       = meshDebug:new() --new mesh debug to store the information about our sprite
20     
21     --First we must add the frames
22     for i = 1, #tFrames do
23         local tFrame = tFrames[i]
24         local indexFrame  = tMesh:addFrame(stride) -- Add one frame with stride 2 (x,y)
25         --To add vertex, first we need to add a subset
26         local indexSubset = tMesh:addSubSet(indexFrame) --add one subset for the first frame
27         --we are adding vertex to frame (next)
28         --this vertex list has to have at least 3 vertex (one triangle) to be valid
29         -- The table expected is : {{x,y},{x,y},{x,y}, ...}
30         if not tMesh:addVertex(indexFrame,indexSubset,tFrame.tVertex) then 
31             print("Error on add vertex buffer")
32             return false
33         end
34     end
35     
36     --Then we add the index buffer
37     for indexFrame = 1, #tFrames do
38         local tFrame = tFrames[indexFrame]
39         local indexSubset = 1
40         if not tMesh:addIndex(indexFrame,indexSubset,tFrame.tIndex) then 
41             print("Error on add index buffer")
42             return false
43         end
44         --apply the texture to frame / subset
45         if not tMesh:setTexture(indexFrame,indexSubset,tFrame.sTexture) then
46             print("Error on set texture!")
47             return false
48         end
49     end
50 
51     tMesh:setType('sprite')  -- set it to sprite type
52 
53     --animation
54     local animation_name   = 'first_animation'
55     local initialFrame     = 1
56     local finalFrame       = 4
57     local timeBetweenFrame = 0.3
58     local typeAnimation    = mbm.GROWING_LOOP
59 
60     local index = tMesh:addAnim(animation_name,initialFrame,finalFrame,timeBetweenFrame,typeAnimation)
61     print('Animation :', index)
62 
63 
64     local calcNormal,calcUv = false,false --Instruct to do not calculate normal and UV
65     if tMesh:save(fileName,calcNormal,calcUv) then
66         print("Sprite created successfully ")
67         return true
68     else
69         print("Failed to create sprite!")
70         return false
71     end
72     
73 end
74 
75 
76 function onInitScene()
77 
78     tSprite = sprite:new('2DW')-- our object which will load from binary file
79 
80     local sFileNameSprite = 'smile.spt'
81 
82     local tFrames = {
83         [1] = createOneFrame('HB_smile.png'),
84         [2] = createOneFrame('HB_sad.png'),
85         [3] = createOneFrame('HB_neutral.png'),
86         [4] = createOneFrame('HB_dead.png') 
87     }
88 
89     if saveMeshToBinaryFile(sFileNameSprite,tFrames) then
90         tSprite:load(sFileNameSprite) --all coordinate already in place
91     else
92         print('Failed to create ' .. sFileNameSprite)
93         mbm.quit()
94     end
95 
96 end

download

_images/sprite_creating_example_4.gif

Figure 15.9 Example how to create animated sprite using different images.

Next example we will use a unique image with 9 animations inside:

_images/Bird.png

Figure 15.10 Bird

download Bird.png

  1 mbm.setColor(1,1,1) --set background color to white
  2 
  3 function addBirdFrame(x,y)
  4 
  5     local sTexture = 'Bird.png'
  6     local w_size_texture, h_size_texture = 512, 512 -- we know the size of texture
  7     local pw = 1.0 / w_size_texture * (w_size_texture/3) --we calculate the 3 birds in the x
  8     local ph = 1.0 / h_size_texture * (h_size_texture/3) --we calculate the 3 birds in the y
  9 
 10     local tVertex = {  {x=-50, y= -50, u= (x-1) * pw, v= (y  ) * ph},
 11                        {x=-50, y=  50, u= (x-1) * pw, v= (y-1) * ph},
 12                        {x= 50, y= -50, u= (x  ) * pw, v= (y  ) * ph},
 13                        {x= 50, y=  50, u= (x  ) * pw, v= (y-1) * ph}}
 14    local tIndex = {1,2,3, 3,2,4}
 15 
 16    return {tVertex = tVertex, tIndex = tIndex, sTexture = sTexture }
 17 end
 18 
 19 function saveMeshToBinaryFile(fileName,tFrames)
 20 
 21     --meshDebug is used to create dynamically mesh in the engine.
 22     --For sprite it has to have at least one frame to be able to generate the sprite
 23     local stride      = 2 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
 24     local tMesh       = meshDebug:new() --new mesh debug to store the information about our sprite
 25     
 26     --First we must add the frames
 27     for i = 1, #tFrames do
 28         local tFrame = tFrames[i]
 29         local indexFrame  = tMesh:addFrame(stride) -- Add one frame with stride 2 (x,y)
 30         --To add vertex, first we need to add a subset
 31         local indexSubset = tMesh:addSubSet(indexFrame) --add one subset for the first frame
 32         --we are adding vertex to frame (next)
 33         --this vertex list has to have at least 3 vertex (one triangle) to be valid
 34         -- The table expected is : {{x,y},{x,y},{x,y}, ...}
 35         if not tMesh:addVertex(indexFrame,indexSubset,tFrame.tVertex) then 
 36             print("Error on add vertex buffer")
 37             return false
 38         end
 39     end
 40     
 41     --Then we add the index buffer
 42     for indexFrame = 1, #tFrames do
 43         local tFrame = tFrames[indexFrame]
 44         local indexSubset = 1
 45         if not tMesh:addIndex(indexFrame,indexSubset,tFrame.tIndex) then 
 46             print("Error on add index buffer")
 47             return false
 48         end
 49         --apply the texture to frame / subset
 50         if not tMesh:setTexture(indexFrame,indexSubset,tFrame.sTexture) then
 51             print("Error on set texture!")
 52             return false
 53         end
 54     end
 55 
 56     tMesh:setType('sprite')  -- set it to sprite type
 57 
 58     --animation
 59     local animation_name   = 'bird flying'
 60     local initialFrame     = 1
 61     local finalFrame       = #tFrames
 62     local timeBetweenFrame = 0.2
 63     local typeAnimation    = mbm.GROWING_LOOP
 64 
 65     local index = tMesh:addAnim(animation_name,initialFrame,finalFrame,timeBetweenFrame,typeAnimation)
 66     print('Animation :', index)
 67 
 68 
 69     local calcNormal,calcUv = false,false --Instruct to do not calculate normal and UV
 70     if tMesh:save(fileName,calcNormal,calcUv) then
 71         print("Sprite created successfully ")
 72         return true
 73     else
 74         print("Failed to create sprite!")
 75         return false
 76     end
 77     
 78 end
 79 
 80 
 81 function onInitScene()
 82 
 83     tSprite = sprite:new('2DW')-- our object which will load from binary file
 84 
 85     local sFileNameSprite = 'Bird.spt'
 86 
 87     local tFrames = {
 88         [1] = addBirdFrame(1,1),
 89         [2] = addBirdFrame(1,2),
 90         [3] = addBirdFrame(1,3),
 91 
 92         [4] = addBirdFrame(2,1),
 93         [5] = addBirdFrame(2,2),
 94         [6] = addBirdFrame(2,3),
 95 
 96         [7] = addBirdFrame(3,1),
 97         [8] = addBirdFrame(3,2),
 98         [9] = addBirdFrame(3,3),        
 99     }
100 
101     if saveMeshToBinaryFile(sFileNameSprite,tFrames) then
102         tSprite:load(sFileNameSprite) --all coordinate already in place
103     else
104         print('Failed to create ' .. sFileNameSprite)
105         mbm.quit()
106     end
107 
108 end

download

_images/sprite_creating_example_5.gif

Figure 15.11 Example how to create animated sprite using unique image and different coordinates by frame.