spine-love, Love runtime.
4
.gitignore
vendored
@ -44,3 +44,7 @@ Assembly-*.pidb
|
||||
|
||||
spine-corona/spine-lua/
|
||||
!spine-corona/spine-lua/Place spine-lua here.txt
|
||||
|
||||
spine-love/spine-lua/
|
||||
spine-love/love/
|
||||
!spine-love/spine-lua/Place spine-lua here.txt
|
||||
|
||||
BIN
spine-love/data/eyes-closed.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
spine-love/data/eyes.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
499
spine-love/data/goblins.json
Normal file
@ -0,0 +1,499 @@
|
||||
{
|
||||
"bones": [
|
||||
{ "name": "root" },
|
||||
{ "name": "hip", "parent": "root", "x": 0.64, "y": 114.41 },
|
||||
{ "name": "left upper leg", "parent": "hip", "length": 50.39, "x": 14.45, "y": 2.81, "rotation": -89.09 },
|
||||
{ "name": "left lower leg", "parent": "left upper leg", "length": 49.89, "x": 56.34, "y": 0.98, "rotation": -16.65 },
|
||||
{ "name": "left foot", "parent": "left lower leg", "length": 46.5, "x": 58.94, "y": -7.61, "rotation": 102.43 },
|
||||
{ "name": "right upper leg", "parent": "hip", "length": 42.45, "x": -20.07, "y": -6.83, "rotation": -97.49 },
|
||||
{ "name": "right lower leg", "parent": "right upper leg", "length": 58.52, "x": 42.99, "y": -0.61, "rotation": -14.34 },
|
||||
{ "name": "right foot", "parent": "right lower leg", "length": 45.45, "x": 64.88, "y": 0.04, "rotation": 110.3 },
|
||||
{ "name": "torso", "parent": "hip", "length": 85.82, "x": -6.42, "y": 1.97, "rotation": 93.92 },
|
||||
{ "name": "neck", "parent": "torso", "length": 18.38, "x": 81.67, "y": -6.34, "rotation": -1.51 },
|
||||
{ "name": "head", "parent": "neck", "length": 68.28, "x": 20.93, "y": 11.59, "rotation": -13.92 },
|
||||
{ "name": "right shoulder", "parent": "torso", "length": 37.24, "x": 76.02, "y": 18.14, "rotation": 133.88 },
|
||||
{ "name": "right arm", "parent": "right shoulder", "length": 36.74, "x": 37.6, "y": 0.31, "rotation": 36.32 },
|
||||
{ "name": "right hand", "parent": "right arm", "length": 15.32, "x": 36.9, "y": 0.34, "rotation": 2.35 },
|
||||
{ "name": "left shoulder", "parent": "torso", "length": 35.43, "x": 74.04, "y": -20.38, "rotation": -156.96 },
|
||||
{ "name": "left arm", "parent": "left shoulder", "length": 35.62, "x": 37.85, "y": -2.34, "rotation": 28.16 },
|
||||
{ "name": "left hand", "parent": "left arm", "length": 11.52, "x": 35.62, "y": 0.07, "rotation": 2.7 },
|
||||
{ "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.57 }
|
||||
],
|
||||
"slots": [
|
||||
{ "name": "left shoulder", "bone": "left shoulder", "attachment": "left shoulder" },
|
||||
{ "name": "left arm", "bone": "left arm", "attachment": "left arm" },
|
||||
{ "name": "left hand item", "bone": "left hand", "attachment": "spear" },
|
||||
{ "name": "left hand", "bone": "left hand", "attachment": "left hand" },
|
||||
{ "name": "left foot", "bone": "left foot", "attachment": "left foot" },
|
||||
{ "name": "left lower leg", "bone": "left lower leg", "attachment": "left lower leg" },
|
||||
{ "name": "left upper leg", "bone": "left upper leg", "attachment": "left upper leg" },
|
||||
{ "name": "neck", "bone": "neck", "attachment": "neck" },
|
||||
{ "name": "torso", "bone": "torso", "attachment": "torso" },
|
||||
{ "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" },
|
||||
{ "name": "right foot", "bone": "right foot", "attachment": "right foot" },
|
||||
{ "name": "right lower leg", "bone": "right lower leg", "attachment": "right lower leg" },
|
||||
{ "name": "undie straps", "bone": "pelvis", "attachment": "undie straps" },
|
||||
{ "name": "undies", "bone": "pelvis", "attachment": "undies" },
|
||||
{ "name": "right upper leg", "bone": "right upper leg", "attachment": "right upper leg" },
|
||||
{ "name": "head", "bone": "head", "attachment": "head" },
|
||||
{ "name": "eyes", "bone": "head" },
|
||||
{ "name": "right shoulder", "bone": "right shoulder", "attachment": "right shoulder" },
|
||||
{ "name": "right arm", "bone": "right arm", "attachment": "right arm" },
|
||||
{ "name": "right hand item", "bone": "right hand", "attachment": "dagger" },
|
||||
{ "name": "right hand", "bone": "right hand", "attachment": "right hand" }
|
||||
],
|
||||
"skins": {
|
||||
"default": {
|
||||
"left hand item": {
|
||||
"dagger": { "x": 7.88, "y": -23.45, "rotation": 10.47, "width": 26, "height": 108 },
|
||||
"spear": { "x": -4.55, "y": 39.2, "rotation": 13.04, "width": 22, "height": 368 }
|
||||
},
|
||||
"right hand item": {
|
||||
"dagger": { "x": 6.51, "y": -24.15, "rotation": -8.06, "width": 26, "height": 108 }
|
||||
}
|
||||
},
|
||||
"goblin": {
|
||||
"neck": {
|
||||
"neck": { "name": "goblin/neck", "x": 10.1, "y": 0.42, "rotation": -93.69, "width": 36, "height": 41 }
|
||||
},
|
||||
"undies": {
|
||||
"undies": { "name": "goblin/undies", "x": 6.3, "y": 0.12, "rotation": 0.91, "width": 36, "height": 29 }
|
||||
},
|
||||
"right hand": {
|
||||
"right hand": { "name": "goblin/right-hand", "x": 7.88, "y": 2.78, "rotation": 91.96, "width": 36, "height": 37 }
|
||||
},
|
||||
"right arm": {
|
||||
"right arm": { "name": "goblin/right-arm", "x": 16.44, "y": -1.04, "rotation": 94.32, "width": 23, "height": 50 }
|
||||
},
|
||||
"head": {
|
||||
"head": { "name": "goblin/head", "x": 25.73, "y": 2.33, "rotation": -92.29, "width": 103, "height": 66 }
|
||||
},
|
||||
"left shoulder": {
|
||||
"left shoulder": { "name": "goblin/left-shoulder", "x": 15.56, "y": -2.26, "rotation": 62.01, "width": 29, "height": 44 }
|
||||
},
|
||||
"left arm": {
|
||||
"left arm": {
|
||||
"name": "goblin/left-arm",
|
||||
"x": 16.7,
|
||||
"y": -1.69,
|
||||
"scaleX": 1.057,
|
||||
"scaleY": 1.057,
|
||||
"rotation": 33.84,
|
||||
"width": 37,
|
||||
"height": 35
|
||||
}
|
||||
},
|
||||
"left hand": {
|
||||
"left hand": {
|
||||
"name": "goblin/left-hand",
|
||||
"x": 3.47,
|
||||
"y": 3.41,
|
||||
"scaleX": 0.892,
|
||||
"scaleY": 0.892,
|
||||
"rotation": 31.14,
|
||||
"width": 36,
|
||||
"height": 41
|
||||
}
|
||||
},
|
||||
"right lower leg": {
|
||||
"right lower leg": { "name": "goblin/right-lower-leg", "x": 25.68, "y": -3.15, "rotation": 111.83, "width": 36, "height": 76 }
|
||||
},
|
||||
"right upper leg": {
|
||||
"right upper leg": { "name": "goblin/right-upper-leg", "x": 20.35, "y": 1.47, "rotation": 97.49, "width": 34, "height": 63 }
|
||||
},
|
||||
"pelvis": {
|
||||
"pelvis": { "name": "goblin/pelvis", "x": -5.61, "y": 0.76, "width": 62, "height": 43 }
|
||||
},
|
||||
"left lower leg": {
|
||||
"left lower leg": { "name": "goblin/left-lower-leg", "x": 23.58, "y": -2.06, "rotation": 105.75, "width": 33, "height": 70 }
|
||||
},
|
||||
"left upper leg": {
|
||||
"left upper leg": { "name": "goblin/left-upper-leg", "x": 29.68, "y": -3.87, "rotation": 89.09, "width": 33, "height": 73 }
|
||||
},
|
||||
"torso": {
|
||||
"torso": { "name": "goblin/torso", "x": 38.09, "y": -3.87, "rotation": -94.95, "width": 68, "height": 96 }
|
||||
},
|
||||
"right shoulder": {
|
||||
"right shoulder": { "name": "goblin/right-shoulder", "x": 15.68, "y": -1.03, "rotation": 130.65, "width": 39, "height": 45 }
|
||||
},
|
||||
"right foot": {
|
||||
"right foot": { "name": "goblin/right-foot", "x": 23.56, "y": 9.8, "rotation": 1.52, "width": 63, "height": 33 }
|
||||
},
|
||||
"left foot": {
|
||||
"left foot": { "name": "goblin/left-foot", "x": 24.85, "y": 8.74, "rotation": 3.32, "width": 65, "height": 31 }
|
||||
},
|
||||
"undie straps": {
|
||||
"undie straps": { "name": "goblin/undie-straps", "x": -3.87, "y": 13.1, "scaleX": 1.089, "width": 55, "height": 19 }
|
||||
},
|
||||
"eyes": {
|
||||
"eyes closed": { "name": "goblin/eyes-closed", "x": 32.21, "y": -21.27, "rotation": -88.92, "width": 34, "height": 12 }
|
||||
}
|
||||
},
|
||||
"goblingirl": {
|
||||
"left upper leg": {
|
||||
"left upper leg": { "name": "goblingirl/left-upper-leg", "x": 30.21, "y": -2.95, "rotation": 89.09, "width": 33, "height": 70 }
|
||||
},
|
||||
"left lower leg": {
|
||||
"left lower leg": { "name": "goblingirl/left-lower-leg", "x": 25.02, "y": -0.6, "rotation": 105.75, "width": 33, "height": 70 }
|
||||
},
|
||||
"left foot": {
|
||||
"left foot": { "name": "goblingirl/left-foot", "x": 25.17, "y": 7.92, "rotation": 3.32, "width": 65, "height": 31 }
|
||||
},
|
||||
"right upper leg": {
|
||||
"right upper leg": { "name": "goblingirl/right-upper-leg", "x": 19.69, "y": 2.13, "rotation": 97.49, "width": 34, "height": 63 }
|
||||
},
|
||||
"right lower leg": {
|
||||
"right lower leg": { "name": "goblingirl/right-lower-leg", "x": 26.15, "y": -3.27, "rotation": 111.83, "width": 36, "height": 76 }
|
||||
},
|
||||
"right foot": {
|
||||
"right foot": { "name": "goblingirl/right-foot", "x": 23.46, "y": 9.66, "rotation": 1.52, "width": 63, "height": 33 }
|
||||
},
|
||||
"torso": {
|
||||
"torso": { "name": "goblingirl/torso", "x": 36.28, "y": -5.14, "rotation": -95.74, "width": 68, "height": 96 }
|
||||
},
|
||||
"left shoulder": {
|
||||
"left shoulder": { "name": "goblingirl/left-shoulder", "x": 19.8, "y": -0.42, "rotation": 61.21, "width": 28, "height": 46 }
|
||||
},
|
||||
"left arm": {
|
||||
"left arm": { "name": "goblingirl/left-arm", "x": 19.64, "y": -2.42, "rotation": 33.05, "width": 37, "height": 35 }
|
||||
},
|
||||
"left hand": {
|
||||
"left hand": {
|
||||
"name": "goblingirl/left-hand",
|
||||
"x": 4.34,
|
||||
"y": 2.39,
|
||||
"scaleX": 0.896,
|
||||
"scaleY": 0.896,
|
||||
"rotation": 30.34,
|
||||
"width": 35,
|
||||
"height": 40
|
||||
}
|
||||
},
|
||||
"neck": {
|
||||
"neck": { "name": "goblingirl/neck", "x": 6.16, "y": -3.14, "rotation": -98.86, "width": 35, "height": 41 }
|
||||
},
|
||||
"head": {
|
||||
"head": { "name": "goblingirl/head", "x": 27.71, "y": -4.32, "rotation": -85.58, "width": 103, "height": 81 }
|
||||
},
|
||||
"right shoulder": {
|
||||
"right shoulder": { "name": "goblingirl/right-shoulder", "x": 14.46, "y": 0.45, "rotation": 129.85, "width": 39, "height": 45 }
|
||||
},
|
||||
"right arm": {
|
||||
"right arm": { "name": "goblingirl/right-arm", "x": 16.85, "y": -0.66, "rotation": 93.52, "width": 28, "height": 50 }
|
||||
},
|
||||
"right hand": {
|
||||
"right hand": { "name": "goblingirl/right-hand", "x": 7.21, "y": 3.43, "rotation": 91.16, "width": 36, "height": 37 }
|
||||
},
|
||||
"pelvis": {
|
||||
"pelvis": { "name": "goblingirl/pelvis", "x": -3.87, "y": 3.18, "width": 62, "height": 43 }
|
||||
},
|
||||
"undie straps": {
|
||||
"undie straps": { "name": "goblingirl/undie-straps", "x": -1.51, "y": 14.18, "width": 55, "height": 19 }
|
||||
},
|
||||
"undies": {
|
||||
"undies": { "name": "goblingirl/undies", "x": 5.4, "y": 1.7, "width": 36, "height": 29 }
|
||||
},
|
||||
"eyes": {
|
||||
"eyes closed": { "name": "goblingirl/eyes-closed", "x": 28, "y": -25.54, "rotation": -87.04, "width": 37, "height": 21 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"animations": {
|
||||
"walk": {
|
||||
"bones": {
|
||||
"left upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -26.55 },
|
||||
{ "time": 0.1333, "angle": -8.78 },
|
||||
{ "time": 0.2333, "angle": 9.51 },
|
||||
{ "time": 0.3666, "angle": 30.74 },
|
||||
{ "time": 0.5, "angle": 25.33 },
|
||||
{ "time": 0.6333, "angle": 26.11 },
|
||||
{ "time": 0.7333, "angle": -7.7 },
|
||||
{ "time": 0.8666, "angle": -21.19 },
|
||||
{ "time": 1, "angle": -26.55 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -1.32, "y": 1.7 },
|
||||
{ "time": 0.3666, "x": -0.06, "y": 2.42 },
|
||||
{ "time": 1, "x": -1.32, "y": 1.7 }
|
||||
]
|
||||
},
|
||||
"right upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 42.45 },
|
||||
{ "time": 0.1333, "angle": 52.1 },
|
||||
{ "time": 0.2333, "angle": 8.53 },
|
||||
{ "time": 0.5, "angle": -16.93 },
|
||||
{ "time": 0.6333, "angle": 1.89 },
|
||||
{
|
||||
"time": 0.7333,
|
||||
"angle": 28.06,
|
||||
"curve": [ 0.462, 0.11, 1, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8666,
|
||||
"angle": 58.68,
|
||||
"curve": [ 0.5, 0.02, 1, 1 ]
|
||||
},
|
||||
{ "time": 1, "angle": 42.45 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 6.23, "y": 0 },
|
||||
{ "time": 0.2333, "x": 2.14, "y": 2.4 },
|
||||
{ "time": 0.5, "x": 2.44, "y": 4.8 },
|
||||
{ "time": 1, "x": 6.23, "y": 0 }
|
||||
]
|
||||
},
|
||||
"left lower leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -22.98 },
|
||||
{ "time": 0.1333, "angle": -63.5 },
|
||||
{ "time": 0.2333, "angle": -73.76 },
|
||||
{ "time": 0.5, "angle": 5.11 },
|
||||
{ "time": 0.6333, "angle": -28.29 },
|
||||
{ "time": 0.7333, "angle": 4.08 },
|
||||
{ "time": 0.8666, "angle": 3.53 },
|
||||
{ "time": 1, "angle": -22.98 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0 },
|
||||
{ "time": 0.2333, "x": 2.55, "y": -0.47 },
|
||||
{ "time": 0.5, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"left foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -3.69 },
|
||||
{ "time": 0.1333, "angle": -10.42 },
|
||||
{ "time": 0.2333, "angle": -5.01 },
|
||||
{ "time": 0.3666, "angle": 3.87 },
|
||||
{ "time": 0.5, "angle": -3.87 },
|
||||
{ "time": 0.6333, "angle": 2.78 },
|
||||
{ "time": 0.7333, "angle": 1.68 },
|
||||
{ "time": 0.8666, "angle": -8.54 },
|
||||
{ "time": 1, "angle": -3.69 }
|
||||
]
|
||||
},
|
||||
"right shoulder": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 5.29,
|
||||
"curve": [ 0.264, 0, 0.75, 1 ]
|
||||
},
|
||||
{ "time": 0.6333, "angle": 6.65 },
|
||||
{ "time": 1, "angle": 5.29 }
|
||||
]
|
||||
},
|
||||
"right arm": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": -4.02,
|
||||
"curve": [ 0.267, 0, 0.804, 0.99 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6333,
|
||||
"angle": 19.78,
|
||||
"curve": [ 0.307, 0, 0.787, 0.99 ]
|
||||
},
|
||||
{ "time": 1, "angle": -4.02 }
|
||||
]
|
||||
},
|
||||
"right hand": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 8.98 },
|
||||
{ "time": 0.6333, "angle": 0.51 },
|
||||
{ "time": 1, "angle": 8.98 }
|
||||
]
|
||||
},
|
||||
"left shoulder": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 6.25,
|
||||
"curve": [ 0.339, 0, 0.683, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5,
|
||||
"angle": -11.78,
|
||||
"curve": [ 0.281, 0, 0.686, 0.99 ]
|
||||
},
|
||||
{ "time": 1, "angle": 6.25 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 1.15, "y": 0.23 }
|
||||
]
|
||||
},
|
||||
"left hand": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": -21.23,
|
||||
"curve": [ 0.295, 0, 0.755, 0.98 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5,
|
||||
"angle": -27.28,
|
||||
"curve": [ 0.241, 0, 0.75, 0.97 ]
|
||||
},
|
||||
{ "time": 1, "angle": -21.23 }
|
||||
]
|
||||
},
|
||||
"left arm": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 28.37,
|
||||
"curve": [ 0.339, 0, 0.683, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5,
|
||||
"angle": 60.09,
|
||||
"curve": [ 0.281, 0, 0.686, 0.99 ]
|
||||
},
|
||||
{ "time": 1, "angle": 28.37 }
|
||||
]
|
||||
},
|
||||
"torso": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -10.28 },
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": -15.38,
|
||||
"curve": [ 0.545, 0, 0.818, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.3666,
|
||||
"angle": -9.78,
|
||||
"curve": [ 0.58, 0.17, 0.669, 0.99 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6333,
|
||||
"angle": -15.75,
|
||||
"curve": [ 0.235, 0.01, 0.795, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.8666,
|
||||
"angle": -7.06,
|
||||
"curve": [ 0.209, 0, 0.816, 0.98 ]
|
||||
},
|
||||
{ "time": 1, "angle": -10.28 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -1.29, "y": 1.68 }
|
||||
]
|
||||
},
|
||||
"right foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -5.25 },
|
||||
{ "time": 0.2333, "angle": -1.91 },
|
||||
{ "time": 0.3666, "angle": -6.45 },
|
||||
{ "time": 0.5, "angle": -5.39 },
|
||||
{ "time": 0.7333, "angle": -11.68 },
|
||||
{ "time": 0.8666, "angle": 0.46 },
|
||||
{ "time": 1, "angle": -5.25 }
|
||||
]
|
||||
},
|
||||
"right lower leg": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": -3.39,
|
||||
"curve": [ 0.316, 0.01, 0.741, 0.98 ]
|
||||
},
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": -45.53,
|
||||
"curve": [ 0.229, 0, 0.738, 0.97 ]
|
||||
},
|
||||
{ "time": 0.2333, "angle": -4.83 },
|
||||
{ "time": 0.5, "angle": -19.53 },
|
||||
{ "time": 0.6333, "angle": -64.8 },
|
||||
{
|
||||
"time": 0.7333,
|
||||
"angle": -82.56,
|
||||
"curve": [ 0.557, 0.18, 1, 1 ]
|
||||
},
|
||||
{ "time": 1, "angle": -3.39 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.5, "x": 0, "y": 0 },
|
||||
{ "time": 0.6333, "x": 2.18, "y": 0.21 },
|
||||
{ "time": 1, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"hip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": -4.16 },
|
||||
{
|
||||
"time": 0.1333,
|
||||
"x": 0,
|
||||
"y": -7.05,
|
||||
"curve": [ 0.359, 0.47, 0.646, 0.74 ]
|
||||
},
|
||||
{ "time": 0.3666, "x": 0, "y": 6.78 },
|
||||
{ "time": 0.5, "x": 0, "y": -6.13 },
|
||||
{
|
||||
"time": 0.6333,
|
||||
"x": 0,
|
||||
"y": -7.05,
|
||||
"curve": [ 0.359, 0.47, 0.646, 0.74 ]
|
||||
},
|
||||
{ "time": 0.8666, "x": 0, "y": 6.78 },
|
||||
{ "time": 1, "x": 0, "y": -4.16 }
|
||||
]
|
||||
},
|
||||
"neck": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 3.6 },
|
||||
{ "time": 0.1333, "angle": 17.49 },
|
||||
{ "time": 0.2333, "angle": 6.1 },
|
||||
{ "time": 0.3666, "angle": 3.45 },
|
||||
{ "time": 0.5, "angle": 5.17 },
|
||||
{ "time": 0.6333, "angle": 18.36 },
|
||||
{ "time": 0.7333, "angle": 6.09 },
|
||||
{ "time": 0.8666, "angle": 2.28 },
|
||||
{ "time": 1, "angle": 3.6 }
|
||||
]
|
||||
},
|
||||
"head": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 3.6,
|
||||
"curve": [ 0, 0, 0.704, 1.17 ]
|
||||
},
|
||||
{ "time": 0.1333, "angle": -0.2 },
|
||||
{ "time": 0.2333, "angle": 6.1 },
|
||||
{ "time": 0.3666, "angle": 3.45 },
|
||||
{
|
||||
"time": 0.5,
|
||||
"angle": 5.17,
|
||||
"curve": [ 0, 0, 0.704, 1.61 ]
|
||||
},
|
||||
{ "time": 0.6666, "angle": 1.1 },
|
||||
{ "time": 0.7333, "angle": 6.09 },
|
||||
{ "time": 0.8666, "angle": 2.28 },
|
||||
{ "time": 1, "angle": 3.6 }
|
||||
]
|
||||
}
|
||||
},
|
||||
"slots": {
|
||||
"eyes": {
|
||||
"attachment": [
|
||||
{ "time": 0.7, "name": "eyes closed" },
|
||||
{ "time": 0.8, "name": null }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
spine-love/data/head.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
spine-love/data/left-ankle.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
spine-love/data/left-arm.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
spine-love/data/left-foot.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
spine-love/data/left-hand.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
spine-love/data/left-lower-leg.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
spine-love/data/left-pant-bottom.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
spine-love/data/left-shoulder.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
spine-love/data/left-upper-leg.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
spine-love/data/neck.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
spine-love/data/pelvis.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
spine-love/data/right-ankle.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
spine-love/data/right-arm.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
spine-love/data/right-foot-idle.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
spine-love/data/right-foot.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
spine-love/data/right-hand.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
spine-love/data/right-lower-leg.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
spine-love/data/right-pant-bottom.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spine-love/data/right-shoulder.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
spine-love/data/right-upper-leg.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
787
spine-love/data/spineboy.json
Normal file
@ -0,0 +1,787 @@
|
||||
{
|
||||
"bones": [
|
||||
{ "name": "root" },
|
||||
{ "name": "hip", "parent": "root", "x": 0.64, "y": 114.41 },
|
||||
{ "name": "left upper leg", "parent": "hip", "length": 50.39, "x": 14.45, "y": 2.81, "rotation": -89.09 },
|
||||
{ "name": "left lower leg", "parent": "left upper leg", "length": 56.45, "x": 51.78, "y": 3.46, "rotation": -16.65 },
|
||||
{ "name": "left foot", "parent": "left lower leg", "length": 46.5, "x": 64.02, "y": -8.67, "rotation": 102.43 },
|
||||
{ "name": "right upper leg", "parent": "hip", "length": 45.76, "x": -18.27, "rotation": -101.13 },
|
||||
{ "name": "right lower leg", "parent": "right upper leg", "length": 58.52, "x": 50.21, "y": 0.6, "rotation": -10.7 },
|
||||
{ "name": "right foot", "parent": "right lower leg", "length": 45.45, "x": 64.88, "y": 0.04, "rotation": 110.3 },
|
||||
{ "name": "torso", "parent": "hip", "length": 85.82, "x": -6.42, "y": 1.97, "rotation": 94.95 },
|
||||
{ "name": "neck", "parent": "torso", "length": 18.38, "x": 83.64, "y": -1.78, "rotation": 0.9 },
|
||||
{ "name": "head", "parent": "neck", "length": 68.28, "x": 19.09, "y": 6.97, "rotation": -8.94 },
|
||||
{ "name": "right shoulder", "parent": "torso", "length": 49.95, "x": 81.9, "y": 6.79, "rotation": 130.6 },
|
||||
{ "name": "right arm", "parent": "right shoulder", "length": 36.74, "x": 49.95, "y": -0.12, "rotation": 40.12 },
|
||||
{ "name": "right hand", "parent": "right arm", "length": 15.32, "x": 36.9, "y": 0.34, "rotation": 2.35 },
|
||||
{ "name": "left shoulder", "parent": "torso", "length": 44.19, "x": 78.96, "y": -15.75, "rotation": -156.96 },
|
||||
{ "name": "left arm", "parent": "left shoulder", "length": 35.62, "x": 44.19, "y": -0.01, "rotation": 28.16 },
|
||||
{ "name": "left hand", "parent": "left arm", "length": 11.52, "x": 35.62, "y": 0.07, "rotation": 2.7 },
|
||||
{ "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.57 }
|
||||
],
|
||||
"slots": [
|
||||
{ "name": "left shoulder", "bone": "left shoulder", "attachment": "left-shoulder" },
|
||||
{ "name": "left arm", "bone": "left arm", "attachment": "left-arm" },
|
||||
{ "name": "left hand", "bone": "left hand", "attachment": "left-hand" },
|
||||
{ "name": "left foot", "bone": "left foot", "attachment": "left-foot" },
|
||||
{ "name": "left lower leg", "bone": "left lower leg", "attachment": "left-lower-leg" },
|
||||
{ "name": "left upper leg", "bone": "left upper leg", "attachment": "left-upper-leg" },
|
||||
{ "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" },
|
||||
{ "name": "right foot", "bone": "right foot", "attachment": "right-foot" },
|
||||
{ "name": "right lower leg", "bone": "right lower leg", "attachment": "right-lower-leg" },
|
||||
{ "name": "right upper leg", "bone": "right upper leg", "attachment": "right-upper-leg" },
|
||||
{ "name": "torso", "bone": "torso", "attachment": "torso" },
|
||||
{ "name": "neck", "bone": "neck", "attachment": "neck" },
|
||||
{ "name": "head", "bone": "head", "attachment": "head" },
|
||||
{ "name": "eyes", "bone": "head", "attachment": "eyes" },
|
||||
{ "name": "right shoulder", "bone": "right shoulder", "attachment": "right-shoulder" },
|
||||
{ "name": "right arm", "bone": "right arm", "attachment": "right-arm" },
|
||||
{ "name": "right hand", "bone": "right hand", "attachment": "right-hand" }
|
||||
],
|
||||
"skins": {
|
||||
"default": {
|
||||
"left shoulder": {
|
||||
"left-shoulder": { "x": 23.74, "y": 0.11, "rotation": 62.01, "width": 34, "height": 53 }
|
||||
},
|
||||
"left arm": {
|
||||
"left-arm": { "x": 15.11, "y": -0.44, "rotation": 33.84, "width": 35, "height": 29 }
|
||||
},
|
||||
"left hand": {
|
||||
"left-hand": { "x": 0.75, "y": 1.86, "rotation": 31.14, "width": 35, "height": 38 }
|
||||
},
|
||||
"left foot": {
|
||||
"left-foot": { "x": 24.35, "y": 8.88, "rotation": 3.32, "width": 65, "height": 30 }
|
||||
},
|
||||
"left lower leg": {
|
||||
"left-lower-leg": { "x": 24.55, "y": -1.92, "rotation": 105.75, "width": 49, "height": 64 }
|
||||
},
|
||||
"left upper leg": {
|
||||
"left-upper-leg": { "x": 26.12, "y": -1.85, "rotation": 89.09, "width": 33, "height": 67 }
|
||||
},
|
||||
"pelvis": {
|
||||
"pelvis": { "x": -4.83, "y": 10.62, "width": 63, "height": 47 }
|
||||
},
|
||||
"right foot": {
|
||||
"right-foot": { "x": 19.02, "y": 8.47, "rotation": 1.52, "width": 67, "height": 30 }
|
||||
},
|
||||
"right lower leg": {
|
||||
"right-lower-leg": { "x": 23.28, "y": -2.59, "rotation": 111.83, "width": 51, "height": 64 }
|
||||
},
|
||||
"right upper leg": {
|
||||
"right-upper-leg": { "x": 23.03, "y": 0.25, "rotation": 101.13, "width": 44, "height": 70 }
|
||||
},
|
||||
"torso": {
|
||||
"torso": { "x": 44.57, "y": -7.08, "rotation": -94.95, "width": 68, "height": 92 }
|
||||
},
|
||||
"neck": {
|
||||
"neck": { "x": 9.42, "y": -3.66, "rotation": -100.15, "width": 34, "height": 28 }
|
||||
},
|
||||
"head": {
|
||||
"head": { "x": 53.94, "y": -5.75, "rotation": -86.9, "width": 121, "height": 132 }
|
||||
},
|
||||
"eyes": {
|
||||
"eyes": { "x": 28.94, "y": -32.92, "rotation": -86.9, "width": 34, "height": 27 },
|
||||
"eyes-closed": { "x": 28.77, "y": -32.86, "rotation": -86.9, "width": 34, "height": 27 }
|
||||
},
|
||||
"right shoulder": {
|
||||
"right-shoulder": { "x": 25.86, "y": 0.03, "rotation": 134.44, "width": 52, "height": 51 }
|
||||
},
|
||||
"right arm": {
|
||||
"right-arm": { "x": 18.34, "y": -2.64, "rotation": 94.32, "width": 21, "height": 45 }
|
||||
},
|
||||
"right hand": {
|
||||
"right-hand": { "x": 6.82, "y": 1.25, "rotation": 91.96, "width": 32, "height": 32 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"animations": {
|
||||
"walk": {
|
||||
"bones": {
|
||||
"left upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -26.55 },
|
||||
{ "time": 0.1333, "angle": -8.78 },
|
||||
{ "time": 0.2666, "angle": 9.51 },
|
||||
{ "time": 0.4, "angle": 30.74 },
|
||||
{ "time": 0.5333, "angle": 25.33 },
|
||||
{ "time": 0.6666, "angle": 26.11 },
|
||||
{ "time": 0.8, "angle": -7.7 },
|
||||
{ "time": 0.9333, "angle": -21.19 },
|
||||
{ "time": 1.0666, "angle": -26.55 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -3, "y": -2.25 },
|
||||
{ "time": 0.4, "x": -2.18, "y": -2.25 },
|
||||
{ "time": 1.0666, "x": -3, "y": -2.25 }
|
||||
]
|
||||
},
|
||||
"right upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 42.45 },
|
||||
{ "time": 0.1333, "angle": 52.1 },
|
||||
{ "time": 0.2666, "angle": 5.96 },
|
||||
{ "time": 0.5333, "angle": -16.93 },
|
||||
{ "time": 0.6666, "angle": 1.89 },
|
||||
{
|
||||
"time": 0.8,
|
||||
"angle": 28.06,
|
||||
"curve": [ 0.462, 0.11, 1, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.9333,
|
||||
"angle": 58.68,
|
||||
"curve": [ 0.5, 0.02, 1, 1 ]
|
||||
},
|
||||
{ "time": 1.0666, "angle": 42.45 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 8.11, "y": -2.36 },
|
||||
{ "time": 0.1333, "x": 10.03, "y": -2.56 },
|
||||
{ "time": 0.4, "x": 2.76, "y": -2.97 },
|
||||
{ "time": 0.5333, "x": 2.76, "y": -2.81 },
|
||||
{ "time": 0.9333, "x": 8.67, "y": -2.54 },
|
||||
{ "time": 1.0666, "x": 8.11, "y": -2.36 }
|
||||
]
|
||||
},
|
||||
"left lower leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -10.21 },
|
||||
{ "time": 0.1333, "angle": -55.64 },
|
||||
{ "time": 0.2666, "angle": -68.12 },
|
||||
{ "time": 0.5333, "angle": 5.11 },
|
||||
{ "time": 0.6666, "angle": -28.29 },
|
||||
{ "time": 0.8, "angle": 4.08 },
|
||||
{ "time": 0.9333, "angle": 3.53 },
|
||||
{ "time": 1.0666, "angle": -10.21 }
|
||||
]
|
||||
},
|
||||
"left foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -3.69 },
|
||||
{ "time": 0.1333, "angle": -10.42 },
|
||||
{ "time": 0.2666, "angle": -17.14 },
|
||||
{ "time": 0.4, "angle": -2.83 },
|
||||
{ "time": 0.5333, "angle": -3.87 },
|
||||
{ "time": 0.6666, "angle": 2.78 },
|
||||
{ "time": 0.8, "angle": 1.68 },
|
||||
{ "time": 0.9333, "angle": -8.54 },
|
||||
{ "time": 1.0666, "angle": -3.69 }
|
||||
]
|
||||
},
|
||||
"right shoulder": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 20.89,
|
||||
"curve": [ 0.264, 0, 0.75, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": 3.72,
|
||||
"curve": [ 0.272, 0, 0.841, 1 ]
|
||||
},
|
||||
{ "time": 0.6666, "angle": -278.28 },
|
||||
{ "time": 1.0666, "angle": 20.89 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -7.84, "y": 7.19 },
|
||||
{ "time": 0.1333, "x": -6.36, "y": 6.42 },
|
||||
{ "time": 0.6666, "x": -11.07, "y": 5.25 },
|
||||
{ "time": 1.0666, "x": -7.84, "y": 7.19 }
|
||||
]
|
||||
},
|
||||
"right arm": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": -4.02,
|
||||
"curve": [ 0.267, 0, 0.804, 0.99 ]
|
||||
},
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": -13.99,
|
||||
"curve": [ 0.341, 0, 1, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6666,
|
||||
"angle": 36.54,
|
||||
"curve": [ 0.307, 0, 0.787, 0.99 ]
|
||||
},
|
||||
{ "time": 1.0666, "angle": -4.02 }
|
||||
]
|
||||
},
|
||||
"right hand": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 22.92 },
|
||||
{ "time": 0.4, "angle": -8.97 },
|
||||
{ "time": 0.6666, "angle": 0.51 },
|
||||
{ "time": 1.0666, "angle": 22.92 }
|
||||
]
|
||||
},
|
||||
"left shoulder": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -1.47 },
|
||||
{ "time": 0.1333, "angle": 13.6 },
|
||||
{ "time": 0.6666, "angle": 280.74 },
|
||||
{ "time": 1.0666, "angle": -1.47 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -1.76, "y": 0.56 },
|
||||
{ "time": 0.6666, "x": -2.47, "y": 8.14 },
|
||||
{ "time": 1.0666, "x": -1.76, "y": 0.56 }
|
||||
]
|
||||
},
|
||||
"left hand": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 11.58,
|
||||
"curve": [ 0.169, 0.37, 0.632, 1.55 ]
|
||||
},
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": 28.13,
|
||||
"curve": [ 0.692, 0, 0.692, 0.99 ]
|
||||
},
|
||||
{
|
||||
"time": 0.6666,
|
||||
"angle": -27.42,
|
||||
"curve": [ 0.117, 0.41, 0.738, 1.76 ]
|
||||
},
|
||||
{ "time": 0.8, "angle": -36.32 },
|
||||
{ "time": 1.0666, "angle": 11.58 }
|
||||
]
|
||||
},
|
||||
"left arm": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -8.27 },
|
||||
{ "time": 0.1333, "angle": 18.43 },
|
||||
{ "time": 0.6666, "angle": 0.88 },
|
||||
{ "time": 1.0666, "angle": -8.27 }
|
||||
]
|
||||
},
|
||||
"torso": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -10.28 },
|
||||
{
|
||||
"time": 0.1333,
|
||||
"angle": -15.38,
|
||||
"curve": [ 0.545, 0, 1, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.4,
|
||||
"angle": -9.78,
|
||||
"curve": [ 0.58, 0.17, 1, 1 ]
|
||||
},
|
||||
{ "time": 0.6666, "angle": -15.75 },
|
||||
{ "time": 0.9333, "angle": -7.06 },
|
||||
{ "time": 1.0666, "angle": -10.28 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -3.67, "y": 1.68 },
|
||||
{ "time": 0.1333, "x": -3.67, "y": 0.68 },
|
||||
{ "time": 0.4, "x": -3.67, "y": 1.97 },
|
||||
{ "time": 0.6666, "x": -3.67, "y": -0.14 },
|
||||
{ "time": 1.0666, "x": -3.67, "y": 1.68 }
|
||||
]
|
||||
},
|
||||
"right foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -5.25 },
|
||||
{ "time": 0.2666, "angle": -4.08 },
|
||||
{ "time": 0.4, "angle": -6.45 },
|
||||
{ "time": 0.5333, "angle": -5.39 },
|
||||
{ "time": 0.8, "angle": -11.68 },
|
||||
{ "time": 0.9333, "angle": 0.46 },
|
||||
{ "time": 1.0666, "angle": -5.25 }
|
||||
]
|
||||
},
|
||||
"right lower leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -3.39 },
|
||||
{ "time": 0.1333, "angle": -45.53 },
|
||||
{ "time": 0.2666, "angle": -2.59 },
|
||||
{ "time": 0.5333, "angle": -19.53 },
|
||||
{ "time": 0.6666, "angle": -64.8 },
|
||||
{
|
||||
"time": 0.8,
|
||||
"angle": -82.56,
|
||||
"curve": [ 0.557, 0.18, 1, 1 ]
|
||||
},
|
||||
{ "time": 1.0666, "angle": -3.39 }
|
||||
]
|
||||
},
|
||||
"hip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.0666, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0 },
|
||||
{
|
||||
"time": 0.1333,
|
||||
"x": 0,
|
||||
"y": -7.61,
|
||||
"curve": [ 0.272, 0.86, 1, 1 ]
|
||||
},
|
||||
{ "time": 0.4, "x": 0, "y": 8.7 },
|
||||
{ "time": 0.5333, "x": 0, "y": -0.41 },
|
||||
{
|
||||
"time": 0.6666,
|
||||
"x": 0,
|
||||
"y": -7.05,
|
||||
"curve": [ 0.235, 0.89, 1, 1 ]
|
||||
},
|
||||
{ "time": 0.8, "x": 0, "y": 2.92 },
|
||||
{ "time": 0.9333, "x": 0, "y": 6.78 },
|
||||
{ "time": 1.0666, "x": 0, "y": 0 }
|
||||
]
|
||||
},
|
||||
"neck": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 3.6 },
|
||||
{ "time": 0.1333, "angle": 17.49 },
|
||||
{ "time": 0.2666, "angle": 6.1 },
|
||||
{ "time": 0.4, "angle": 3.45 },
|
||||
{ "time": 0.5333, "angle": 5.17 },
|
||||
{ "time": 0.6666, "angle": 18.36 },
|
||||
{ "time": 0.8, "angle": 6.09 },
|
||||
{ "time": 0.9333, "angle": 2.28 },
|
||||
{ "time": 1.0666, "angle": 3.6 }
|
||||
]
|
||||
},
|
||||
"head": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 3.6,
|
||||
"curve": [ 0, 0, 0.704, 1.61 ]
|
||||
},
|
||||
{ "time": 0.1666, "angle": -0.2 },
|
||||
{ "time": 0.2666, "angle": 6.1 },
|
||||
{ "time": 0.4, "angle": 3.45 },
|
||||
{
|
||||
"time": 0.5333,
|
||||
"angle": 5.17,
|
||||
"curve": [ 0, 0, 0.704, 1.61 ]
|
||||
},
|
||||
{ "time": 0.7, "angle": 1.1 },
|
||||
{ "time": 0.8, "angle": 6.09 },
|
||||
{ "time": 0.9333, "angle": 2.28 },
|
||||
{ "time": 1.0666, "angle": 3.6 }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"jump": {
|
||||
"bones": {
|
||||
"hip": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "angle": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "angle": 0 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -11.57, "y": -3 },
|
||||
{ "time": 0.2333, "x": -16.2, "y": -19.43 },
|
||||
{
|
||||
"time": 0.3333,
|
||||
"x": 7.66,
|
||||
"y": -8.48,
|
||||
"curve": [ 0.057, 0.06, 0.712, 1 ]
|
||||
},
|
||||
{ "time": 0.3666, "x": 15.38, "y": 5.01 },
|
||||
{ "time": 0.4666, "x": -7.84, "y": 57.22 },
|
||||
{
|
||||
"time": 0.6,
|
||||
"x": -10.81,
|
||||
"y": 96.34,
|
||||
"curve": [ 0.241, 0, 1, 1 ]
|
||||
},
|
||||
{ "time": 0.7333, "x": -7.01, "y": 54.7 },
|
||||
{ "time": 0.8, "x": -10.58, "y": 32.2 },
|
||||
{ "time": 0.9333, "x": -31.99, "y": 0.45 },
|
||||
{ "time": 1.0666, "x": -12.48, "y": -29.47 },
|
||||
{ "time": 1.3666, "x": -11.57, "y": -3 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 17.13 },
|
||||
{ "time": 0.2333, "angle": 44.35 },
|
||||
{ "time": 0.3333, "angle": 16.46 },
|
||||
{ "time": 0.4, "angle": -9.88 },
|
||||
{ "time": 0.4666, "angle": -11.42 },
|
||||
{ "time": 0.5666, "angle": 23.46 },
|
||||
{ "time": 0.7666, "angle": 71.82 },
|
||||
{ "time": 0.9333, "angle": 65.53 },
|
||||
{ "time": 1.0666, "angle": 51.01 },
|
||||
{ "time": 1.3666, "angle": 17.13 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -3, "y": -2.25, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": -3, "y": -2.25, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": -3, "y": -2.25 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left lower leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -16.25 },
|
||||
{ "time": 0.2333, "angle": -52.21 },
|
||||
{ "time": 0.4, "angle": 15.04 },
|
||||
{ "time": 0.4666, "angle": -8.95 },
|
||||
{ "time": 0.5666, "angle": -39.53 },
|
||||
{ "time": 0.7666, "angle": -27.27 },
|
||||
{ "time": 0.9333, "angle": -3.52 },
|
||||
{ "time": 1.0666, "angle": -61.92 },
|
||||
{ "time": 1.3666, "angle": -16.25 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0.33 },
|
||||
{ "time": 0.2333, "angle": 6.2 },
|
||||
{ "time": 0.3333, "angle": 14.73 },
|
||||
{ "time": 0.4, "angle": -15.54 },
|
||||
{ "time": 0.4333, "angle": -21.2 },
|
||||
{ "time": 0.5666, "angle": -7.55 },
|
||||
{ "time": 0.7666, "angle": -0.67 },
|
||||
{ "time": 0.9333, "angle": -0.58 },
|
||||
{ "time": 1.0666, "angle": 14.64 },
|
||||
{ "time": 1.3666, "angle": 0.33 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right upper leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 25.97 },
|
||||
{ "time": 0.2333, "angle": 46.43 },
|
||||
{ "time": 0.3333, "angle": 22.61 },
|
||||
{ "time": 0.4, "angle": 2.13 },
|
||||
{
|
||||
"time": 0.4666,
|
||||
"angle": 0.04,
|
||||
"curve": [ 0, 0, 0.637, 0.98 ]
|
||||
},
|
||||
{ "time": 0.6, "angle": 65.55 },
|
||||
{ "time": 0.7666, "angle": 64.93 },
|
||||
{ "time": 0.9333, "angle": 41.08 },
|
||||
{ "time": 1.0666, "angle": 66.25 },
|
||||
{ "time": 1.3666, "angle": 25.97 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 5.74, "y": 0.61 },
|
||||
{ "time": 0.2333, "x": 4.79, "y": 1.79 },
|
||||
{ "time": 0.3333, "x": 6.05, "y": -4.55 },
|
||||
{ "time": 0.9333, "x": 4.79, "y": 1.79, "curve": "stepped" },
|
||||
{ "time": 1.0666, "x": 4.79, "y": 1.79 },
|
||||
{ "time": 1.3666, "x": 5.74, "y": 0.61 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right lower leg": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -27.46 },
|
||||
{ "time": 0.2333, "angle": -64.03 },
|
||||
{ "time": 0.4, "angle": -48.36 },
|
||||
{ "time": 0.5666, "angle": -76.86 },
|
||||
{ "time": 0.7666, "angle": -26.89 },
|
||||
{ "time": 0.9, "angle": -18.97 },
|
||||
{ "time": 0.9333, "angle": -14.18 },
|
||||
{ "time": 1.0666, "angle": -80.45 },
|
||||
{ "time": 1.3666, "angle": -27.46 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right foot": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 1.08 },
|
||||
{ "time": 0.2333, "angle": 16.02 },
|
||||
{ "time": 0.3, "angle": 12.94 },
|
||||
{ "time": 0.3333, "angle": 15.16 },
|
||||
{ "time": 0.4, "angle": -14.7 },
|
||||
{ "time": 0.4333, "angle": -12.85 },
|
||||
{ "time": 0.4666, "angle": -19.18 },
|
||||
{ "time": 0.5666, "angle": -15.82 },
|
||||
{ "time": 0.6, "angle": -3.59 },
|
||||
{ "time": 0.7666, "angle": -3.56 },
|
||||
{ "time": 0.9333, "angle": 1.86 },
|
||||
{ "time": 1.0666, "angle": 16.02 },
|
||||
{ "time": 1.3666, "angle": 1.08 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"torso": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -13.35 },
|
||||
{ "time": 0.2333, "angle": -48.95 },
|
||||
{ "time": 0.4333, "angle": -35.77 },
|
||||
{ "time": 0.6, "angle": -4.59 },
|
||||
{ "time": 0.7666, "angle": 14.61 },
|
||||
{ "time": 0.9333, "angle": 15.74 },
|
||||
{ "time": 1.0666, "angle": -32.44 },
|
||||
{ "time": 1.3666, "angle": -13.35 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -3.67, "y": 1.68, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": -3.67, "y": 1.68, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": -3.67, "y": 1.68 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"neck": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 12.78 },
|
||||
{ "time": 0.2333, "angle": 16.46 },
|
||||
{ "time": 0.4, "angle": 26.49 },
|
||||
{ "time": 0.6, "angle": 15.51 },
|
||||
{ "time": 0.7666, "angle": 1.34 },
|
||||
{ "time": 0.9333, "angle": 2.35 },
|
||||
{ "time": 1.0666, "angle": 6.08 },
|
||||
{ "time": 1.3, "angle": 21.23 },
|
||||
{ "time": 1.3666, "angle": 12.78 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"head": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 5.19 },
|
||||
{ "time": 0.2333, "angle": 20.27 },
|
||||
{ "time": 0.4, "angle": 15.27 },
|
||||
{ "time": 0.6, "angle": -24.69 },
|
||||
{ "time": 0.7666, "angle": -11.02 },
|
||||
{ "time": 0.9333, "angle": -24.38 },
|
||||
{ "time": 1.0666, "angle": 11.99 },
|
||||
{ "time": 1.3, "angle": 4.86 },
|
||||
{ "time": 1.3666, "angle": 5.19 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left shoulder": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 0.05,
|
||||
"curve": [ 0, 0, 0.62, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.2333,
|
||||
"angle": 279.66,
|
||||
"curve": [ 0.218, 0.67, 0.66, 0.99 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5,
|
||||
"angle": 62.27,
|
||||
"curve": [ 0.462, 0, 0.764, 0.58 ]
|
||||
},
|
||||
{ "time": 0.9333, "angle": 28.91 },
|
||||
{ "time": 1.0666, "angle": -8.62 },
|
||||
{ "time": 1.1666, "angle": -18.43 },
|
||||
{ "time": 1.3666, "angle": 0.05 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -1.76, "y": 0.56, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": -1.76, "y": 0.56, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": -1.76, "y": 0.56 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left hand": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 11.58, "curve": "stepped" },
|
||||
{ "time": 0.9333, "angle": 11.58, "curve": "stepped" },
|
||||
{ "time": 1.3666, "angle": 11.58 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"left arm": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0.51 },
|
||||
{ "time": 0.4333, "angle": 12.82 },
|
||||
{ "time": 0.6, "angle": 47.55 },
|
||||
{ "time": 0.9333, "angle": 12.82 },
|
||||
{ "time": 1.1666, "angle": -6.5 },
|
||||
{ "time": 1.3666, "angle": 0.51 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right shoulder": {
|
||||
"rotate": [
|
||||
{
|
||||
"time": 0,
|
||||
"angle": 43.82,
|
||||
"curve": [ 0, 0, 0.62, 1 ]
|
||||
},
|
||||
{
|
||||
"time": 0.2333,
|
||||
"angle": -8.74,
|
||||
"curve": [ 0.304, 0.58, 0.709, 0.97 ]
|
||||
},
|
||||
{
|
||||
"time": 0.5333,
|
||||
"angle": -208.02,
|
||||
"curve": [ 0.462, 0, 0.764, 0.58 ]
|
||||
},
|
||||
{ "time": 0.9333, "angle": -246.72 },
|
||||
{ "time": 1.0666, "angle": -307.13 },
|
||||
{ "time": 1.1666, "angle": 37.15 },
|
||||
{ "time": 1.3666, "angle": 43.82 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": -7.84, "y": 7.19, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": -7.84, "y": 7.19, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": -7.84, "y": 7.19 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right arm": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": -4.02 },
|
||||
{ "time": 0.6, "angle": 17.5 },
|
||||
{ "time": 0.9333, "angle": -4.02 },
|
||||
{ "time": 1.1666, "angle": -16.72 },
|
||||
{ "time": 1.3666, "angle": -4.02 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"right hand": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 22.92, "curve": "stepped" },
|
||||
{ "time": 0.9333, "angle": 22.92, "curve": "stepped" },
|
||||
{ "time": 1.3666, "angle": 22.92 }
|
||||
],
|
||||
"translate": [
|
||||
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 0, "y": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
},
|
||||
"root": {
|
||||
"rotate": [
|
||||
{ "time": 0, "angle": 0 },
|
||||
{ "time": 0.4333, "angle": -14.52 },
|
||||
{ "time": 0.8, "angle": 9.86 },
|
||||
{ "time": 1.3666, "angle": 0 }
|
||||
],
|
||||
"scale": [
|
||||
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
|
||||
{ "time": 1.3666, "x": 1, "y": 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
spine-love/data/torso.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
32
spine-love/main.lua
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
local spine = require "spine-love.spine"
|
||||
|
||||
local json = spine.SkeletonJson.new()
|
||||
json.scale = 1
|
||||
local skeletonData = json:readSkeletonDataFile("data/spineboy.json")
|
||||
local walkAnimation = skeletonData:findAnimation("walk")
|
||||
|
||||
local skeleton = spine.Skeleton.new(skeletonData)
|
||||
function skeleton:createImage (attachment)
|
||||
-- Customize where images are loaded.
|
||||
return love.graphics.newImage("data/" .. attachment.name .. ".png")
|
||||
end
|
||||
skeleton.x = 150
|
||||
skeleton.y = 325
|
||||
skeleton.flipX = false
|
||||
skeleton.flipY = false
|
||||
skeleton.debugBones = true -- Omit or set to false to not draw debug lines on top of the images.
|
||||
skeleton.debugSlots = false
|
||||
skeleton:setToBindPose()
|
||||
|
||||
local animationTime = 0
|
||||
function love.update (delta)
|
||||
animationTime = animationTime + delta
|
||||
walkAnimation:apply(skeleton, animationTime, true)
|
||||
skeleton:updateWorldTransform()
|
||||
end
|
||||
|
||||
function love.draw ()
|
||||
love.graphics.setColor(255, 255, 255)
|
||||
skeleton:draw()
|
||||
end
|
||||
791
spine-love/spine-love/dkjson.lua
Normal file
@ -0,0 +1,791 @@
|
||||
-- Module options:
|
||||
local always_try_using_lpeg = true
|
||||
|
||||
--[==[
|
||||
|
||||
David Kolf's JSON module for Lua 5.1/5.2
|
||||
========================================
|
||||
|
||||
*Version 2.2*
|
||||
|
||||
This module writes no global values, not even the module table.
|
||||
Import it using
|
||||
|
||||
json = require ("dkjson")
|
||||
|
||||
Exported functions and values:
|
||||
|
||||
`json.encode (object [, state])`
|
||||
--------------------------------
|
||||
|
||||
Create a string representing the object. `Object` can be a table,
|
||||
a string, a number, a boolean, `nil`, `json.null` or any object with
|
||||
a function `__tojson` in its metatable. A table can only use strings
|
||||
and numbers as keys and its values have to be valid objects as
|
||||
well. It raises an error for any invalid data types or reference
|
||||
cycles.
|
||||
|
||||
`state` is an optional table with the following fields:
|
||||
|
||||
- `indent`
|
||||
When `indent` (a boolean) is set, the created string will contain
|
||||
newlines and indentations. Otherwise it will be one long line.
|
||||
- `keyorder`
|
||||
`keyorder` is an array to specify the ordering of keys in the
|
||||
encoded output. If an object has keys which are not in this array
|
||||
they are written after the sorted keys.
|
||||
- `level`
|
||||
This is the initial level of indentation used when `indent` is
|
||||
set. For each level two spaces are added. When absent it is set
|
||||
to 0.
|
||||
- `buffer`
|
||||
`buffer` is an array to store the strings for the result so they
|
||||
can be concatenated at once. When it isn't given, the encode
|
||||
function will create it temporary and will return the
|
||||
concatenated result.
|
||||
- `bufferlen`
|
||||
When `bufferlen` is set, it has to be the index of the last
|
||||
element of `buffer`.
|
||||
- `tables`
|
||||
`tables` is a set to detect reference cycles. It is created
|
||||
temporary when absent. Every table that is currently processed
|
||||
is used as key, the value is `true`.
|
||||
|
||||
When `state.buffer` was set, the return value will be `true` on
|
||||
success. Without `state.buffer` the return value will be a string.
|
||||
|
||||
`json.decode (string [, position [, null]])`
|
||||
--------------------------------------------
|
||||
|
||||
Decode `string` starting at `position` or at 1 if `position` was
|
||||
omitted.
|
||||
|
||||
`null` is an optional value to be returned for null values. The
|
||||
default is `nil`, but you could set it to `json.null` or any other
|
||||
value.
|
||||
|
||||
The return values are the object or `nil`, the position of the next
|
||||
character that doesn't belong to the object, and in case of errors
|
||||
an error message.
|
||||
|
||||
Two metatables are created. Every array or object that is decoded gets
|
||||
a metatable with the `__jsontype` field set to either `array` or
|
||||
`object`. If you want to provide your own metatables use the syntax
|
||||
|
||||
json.decode (string, position, null, objectmeta, arraymeta)
|
||||
|
||||
To prevent the assigning of metatables pass `nil`:
|
||||
|
||||
json.decode (string, position, null, nil)
|
||||
|
||||
`<metatable>.__jsonorder`
|
||||
-------------------------
|
||||
|
||||
`__jsonorder` can overwrite the `keyorder` for a specific table.
|
||||
|
||||
`<metatable>.__jsontype`
|
||||
------------------------
|
||||
|
||||
`__jsontype` can be either `"array"` or `"object"`. This value is only
|
||||
checked for empty tables. (The default for empty tables is `"array"`).
|
||||
|
||||
`<metatable>.__tojson (self, state)`
|
||||
------------------------------------
|
||||
|
||||
You can provide your own `__tojson` function in a metatable. In this
|
||||
function you can either add directly to the buffer and return true,
|
||||
or you can return a string. On errors nil and a message should be
|
||||
returned.
|
||||
|
||||
`json.null`
|
||||
-----------
|
||||
|
||||
You can use this value for setting explicit `null` values.
|
||||
|
||||
`json.version`
|
||||
--------------
|
||||
|
||||
Set to `"dkjson 2.2"`.
|
||||
|
||||
`json.quotestring (string)`
|
||||
---------------------------
|
||||
|
||||
Quote a UTF-8 string and escape critical characters using JSON
|
||||
escape sequences. This function is only necessary when you build
|
||||
your own `__tojson` functions.
|
||||
|
||||
`json.addnewline (state)`
|
||||
-------------------------
|
||||
|
||||
When `state.indent` is set, add a newline to `state.buffer` and spaces
|
||||
according to `state.level`.
|
||||
|
||||
LPeg support
|
||||
------------
|
||||
|
||||
When the local configuration variable `always_try_using_lpeg` is set,
|
||||
this module tries to load LPeg to replace the `decode` function. The
|
||||
speed increase is significant. You can get the LPeg module at
|
||||
<http://www.inf.puc-rio.br/~roberto/lpeg/>.
|
||||
When LPeg couldn't be loaded, the pure Lua functions stay active.
|
||||
|
||||
In case you don't want this module to require LPeg on its own,
|
||||
disable the option `always_try_using_lpeg` in the options section at
|
||||
the top of the module.
|
||||
|
||||
In this case you can later load LPeg support using
|
||||
|
||||
### `json.use_lpeg ()`
|
||||
|
||||
Require the LPeg module and replace the functions `quotestring` and
|
||||
and `decode` with functions that use LPeg patterns.
|
||||
This function returns the module table, so you can load the module
|
||||
using:
|
||||
|
||||
json = require "dkjson".use_lpeg()
|
||||
|
||||
Alternatively you can use `pcall` so the JSON module still works when
|
||||
LPeg isn't found.
|
||||
|
||||
json = require "dkjson"
|
||||
pcall (json.use_lpeg)
|
||||
|
||||
### `json.using_lpeg`
|
||||
|
||||
This variable is set to `true` when LPeg was loaded successfully.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
You can contact the author by sending an e-mail to 'kolf' at the
|
||||
e-mail provider 'gmx.de'.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
*Copyright (C) 2010, 2011, 2012 David Heiko Kolf*
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
<!-- This documentation can be parsed using Markdown to generate HTML.
|
||||
The source code is enclosed in a HTML comment so it won't be displayed
|
||||
by browsers, but it should be removed from the final HTML file as
|
||||
it isn't a valid HTML comment (and wastes space).
|
||||
-->
|
||||
|
||||
<!--]==]
|
||||
|
||||
-- global dependencies:
|
||||
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
|
||||
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
|
||||
local error, require, pcall, select = error, require, pcall, select
|
||||
local floor, huge = math.floor, math.huge
|
||||
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
||||
string.rep, string.gsub, string.sub, string.byte, string.char,
|
||||
string.find, string.len, string.format
|
||||
local concat = table.concat
|
||||
|
||||
local _ENV = nil -- blocking globals in Lua 5.2
|
||||
|
||||
local json = { version = "dkjson 2.2" }
|
||||
|
||||
pcall (function()
|
||||
-- Enable access to blocked metatables.
|
||||
-- Don't worry, this module doesn't change anything in them.
|
||||
local debmeta = require "debug".getmetatable
|
||||
if debmeta then getmetatable = debmeta end
|
||||
end)
|
||||
|
||||
json.null = setmetatable ({}, {
|
||||
__tojson = function () return "null" end
|
||||
})
|
||||
|
||||
local function isarray (tbl)
|
||||
local max, n, arraylen = 0, 0, 0
|
||||
for k,v in pairs (tbl) do
|
||||
if k == 'n' and type(v) == 'number' then
|
||||
arraylen = v
|
||||
if v > max then
|
||||
max = v
|
||||
end
|
||||
else
|
||||
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
|
||||
return false
|
||||
end
|
||||
if k > max then
|
||||
max = k
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
if max > 10 and max > arraylen and max > n * 2 then
|
||||
return false -- don't create an array with too many holes
|
||||
end
|
||||
return true, max
|
||||
end
|
||||
|
||||
local escapecodes = {
|
||||
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
|
||||
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
|
||||
}
|
||||
|
||||
local function escapeutf8 (uchar)
|
||||
local value = escapecodes[uchar]
|
||||
if value then
|
||||
return value
|
||||
end
|
||||
local a, b, c, d = strbyte (uchar, 1, 4)
|
||||
a, b, c, d = a or 0, b or 0, c or 0, d or 0
|
||||
if a <= 0x7f then
|
||||
value = a
|
||||
elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
|
||||
value = (a - 0xc0) * 0x40 + b - 0x80
|
||||
elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
|
||||
value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
|
||||
elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
|
||||
value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
|
||||
else
|
||||
return ""
|
||||
end
|
||||
if value <= 0xffff then
|
||||
return strformat ("\\u%.4x", value)
|
||||
elseif value <= 0x10ffff then
|
||||
-- encode as UTF-16 surrogate pair
|
||||
value = value - 0x10000
|
||||
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
|
||||
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function fsub (str, pattern, repl)
|
||||
-- gsub always builds a new string in a buffer, even when no match
|
||||
-- exists. First using find should be more efficient when most strings
|
||||
-- don't contain the pattern.
|
||||
if strfind (str, pattern) then
|
||||
return gsub (str, pattern, repl)
|
||||
else
|
||||
return str
|
||||
end
|
||||
end
|
||||
|
||||
local function quotestring (value)
|
||||
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
|
||||
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
|
||||
if strfind (value, "[\194\216\220\225\226\239]") then
|
||||
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
|
||||
value = fsub (value, "\216[\128-\132]", escapeutf8)
|
||||
value = fsub (value, "\220\143", escapeutf8)
|
||||
value = fsub (value, "\225\158[\180\181]", escapeutf8)
|
||||
value = fsub (value, "\226\128[\140-\143\168\175]", escapeutf8)
|
||||
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
|
||||
value = fsub (value, "\239\187\191", escapeutf8)
|
||||
value = fsub (value, "\239\191[\176\191]", escapeutf8)
|
||||
end
|
||||
return "\"" .. value .. "\""
|
||||
end
|
||||
json.quotestring = quotestring
|
||||
|
||||
local function addnewline2 (level, buffer, buflen)
|
||||
buffer[buflen+1] = "\n"
|
||||
buffer[buflen+2] = strrep (" ", level)
|
||||
buflen = buflen + 2
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.addnewline (state)
|
||||
if state.indent then
|
||||
state.bufferlen = addnewline2 (state.level or 0,
|
||||
state.buffer, state.bufferlen or #(state.buffer))
|
||||
end
|
||||
end
|
||||
|
||||
local encode2 -- forward declaration
|
||||
|
||||
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
local kt = type (key)
|
||||
if kt ~= 'string' and kt ~= 'number' then
|
||||
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
|
||||
end
|
||||
if prev then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ","
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level, buffer, buflen)
|
||||
end
|
||||
buffer[buflen+1] = quotestring (key)
|
||||
buffer[buflen+2] = ":"
|
||||
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder)
|
||||
end
|
||||
|
||||
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder)
|
||||
local valtype = type (value)
|
||||
local valmeta = getmetatable (value)
|
||||
valmeta = type (valmeta) == 'table' and valmeta -- only tables
|
||||
local valtojson = valmeta and valmeta.__tojson
|
||||
if valtojson then
|
||||
if tables[value] then
|
||||
return nil, "reference cycle"
|
||||
end
|
||||
tables[value] = true
|
||||
local state = {
|
||||
indent = indent, level = level, buffer = buffer,
|
||||
bufferlen = buflen, tables = tables, keyorder = globalorder
|
||||
}
|
||||
local ret, msg = valtojson (value, state)
|
||||
if not ret then return nil, msg end
|
||||
tables[value] = nil
|
||||
buflen = state.bufferlen
|
||||
if type (ret) == 'string' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ret
|
||||
end
|
||||
elseif value == nil then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "null"
|
||||
elseif valtype == 'number' then
|
||||
local s
|
||||
if value ~= value or value >= huge or -value >= huge then
|
||||
-- This is the behaviour of the original JSON implementation.
|
||||
s = "null"
|
||||
else
|
||||
s = tostring (value)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = s
|
||||
elseif valtype == 'boolean' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = value and "true" or "false"
|
||||
elseif valtype == 'string' then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = quotestring (value)
|
||||
elseif valtype == 'table' then
|
||||
if tables[value] then
|
||||
return nil, "reference cycle"
|
||||
end
|
||||
tables[value] = true
|
||||
level = level + 1
|
||||
local isa, n = isarray (value)
|
||||
if n == 0 and valmeta and valmeta.__jsontype == 'object' then
|
||||
isa = false
|
||||
end
|
||||
local msg
|
||||
if isa then -- JSON array
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "["
|
||||
for i = 1, n do
|
||||
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
if i < n then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ","
|
||||
end
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "]"
|
||||
else -- JSON object
|
||||
local prev = false
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "{"
|
||||
local order = valmeta and valmeta.__jsonorder or globalorder
|
||||
if order then
|
||||
local used = {}
|
||||
n = #order
|
||||
for i = 1, n do
|
||||
local k = order[i]
|
||||
local v = value[k]
|
||||
if v then
|
||||
used[k] = true
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
for k,v in pairs (value) do
|
||||
if not used[k] then
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
else -- unordered
|
||||
for k,v in pairs (value) do
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
|
||||
if not buflen then return nil, msg end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level - 1, buffer, buflen)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "}"
|
||||
end
|
||||
tables[value] = nil
|
||||
else
|
||||
return nil, "type '" .. valtype .. "' is not supported by JSON."
|
||||
end
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.encode (value, state)
|
||||
state = state or {}
|
||||
local oldbuffer = state.buffer
|
||||
local buffer = oldbuffer or {}
|
||||
local ret, msg = encode2 (value, state.indent, state.level or 0,
|
||||
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
|
||||
if not ret then
|
||||
error (msg, 2)
|
||||
elseif oldbuffer then
|
||||
state.bufferlen = ret
|
||||
return true
|
||||
else
|
||||
return concat (buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local function loc (str, where)
|
||||
local line, pos, linepos = 1, 1, 0
|
||||
while true do
|
||||
pos = strfind (str, "\n", pos, true)
|
||||
if pos and pos < where then
|
||||
line = line + 1
|
||||
linepos = pos
|
||||
pos = pos + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return "line " .. line .. ", column " .. (where - linepos)
|
||||
end
|
||||
|
||||
local function unterminated (str, what, where)
|
||||
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
|
||||
end
|
||||
|
||||
local function scanwhite (str, pos)
|
||||
while true do
|
||||
pos = strfind (str, "%S", pos)
|
||||
if not pos then return nil end
|
||||
if strsub (str, pos, pos + 2) == "\239\187\191" then
|
||||
-- UTF-8 Byte Order Mark
|
||||
pos = pos + 3
|
||||
else
|
||||
return pos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local escapechars = {
|
||||
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
|
||||
["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
|
||||
}
|
||||
|
||||
local function unichar (value)
|
||||
if value < 0 then
|
||||
return nil
|
||||
elseif value <= 0x007f then
|
||||
return strchar (value)
|
||||
elseif value <= 0x07ff then
|
||||
return strchar (0xc0 + floor(value/0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0xffff then
|
||||
return strchar (0xe0 + floor(value/0x1000),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0x10ffff then
|
||||
return strchar (0xf0 + floor(value/0x40000),
|
||||
0x80 + (floor(value/0x1000) % 0x40),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function scanstring (str, pos)
|
||||
local lastpos = pos + 1
|
||||
local buffer, n = {}, 0
|
||||
while true do
|
||||
local nextpos = strfind (str, "[\"\\]", lastpos)
|
||||
if not nextpos then
|
||||
return unterminated (str, "string", pos)
|
||||
end
|
||||
if nextpos > lastpos then
|
||||
n = n + 1
|
||||
buffer[n] = strsub (str, lastpos, nextpos - 1)
|
||||
end
|
||||
if strsub (str, nextpos, nextpos) == "\"" then
|
||||
lastpos = nextpos + 1
|
||||
break
|
||||
else
|
||||
local escchar = strsub (str, nextpos + 1, nextpos + 1)
|
||||
local value
|
||||
if escchar == "u" then
|
||||
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
|
||||
if value then
|
||||
local value2
|
||||
if 0xD800 <= value and value <= 0xDBff then
|
||||
-- we have the high surrogate of UTF-16. Check if there is a
|
||||
-- low surrogate escaped nearby to combine them.
|
||||
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
|
||||
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
|
||||
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
|
||||
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
|
||||
else
|
||||
value2 = nil -- in case it was out of range for a low surrogate
|
||||
end
|
||||
end
|
||||
end
|
||||
value = value and unichar (value)
|
||||
if value then
|
||||
if value2 then
|
||||
lastpos = nextpos + 12
|
||||
else
|
||||
lastpos = nextpos + 6
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not value then
|
||||
value = escapechars[escchar] or escchar
|
||||
lastpos = nextpos + 2
|
||||
end
|
||||
n = n + 1
|
||||
buffer[n] = value
|
||||
end
|
||||
end
|
||||
if n == 1 then
|
||||
return buffer[1], lastpos
|
||||
elseif n > 1 then
|
||||
return concat (buffer), lastpos
|
||||
else
|
||||
return "", lastpos
|
||||
end
|
||||
end
|
||||
|
||||
local scanvalue -- forward declaration
|
||||
|
||||
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
|
||||
local len = strlen (str)
|
||||
local tbl, n = {}, 0
|
||||
local pos = startpos + 1
|
||||
if what == 'object' then
|
||||
setmetatable (tbl, objectmeta)
|
||||
else
|
||||
setmetatable (tbl, arraymeta)
|
||||
end
|
||||
while true do
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local char = strsub (str, pos, pos)
|
||||
if char == closechar then
|
||||
return tbl, pos + 1
|
||||
end
|
||||
local val1, err
|
||||
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
char = strsub (str, pos, pos)
|
||||
if char == ":" then
|
||||
if val1 == nil then
|
||||
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
|
||||
end
|
||||
pos = scanwhite (str, pos + 1)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local val2
|
||||
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
tbl[val1] = val2
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
char = strsub (str, pos, pos)
|
||||
else
|
||||
n = n + 1
|
||||
tbl[n] = val1
|
||||
end
|
||||
if char == "," then
|
||||
pos = pos + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
|
||||
pos = pos or 1
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then
|
||||
return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
|
||||
end
|
||||
local char = strsub (str, pos, pos)
|
||||
if char == "{" then
|
||||
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "[" then
|
||||
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "\"" then
|
||||
return scanstring (str, pos)
|
||||
else
|
||||
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
|
||||
if pstart then
|
||||
local number = tonumber (strsub (str, pstart, pend))
|
||||
if number then
|
||||
return number, pend + 1
|
||||
end
|
||||
end
|
||||
pstart, pend = strfind (str, "^%a%w*", pos)
|
||||
if pstart then
|
||||
local name = strsub (str, pstart, pend)
|
||||
if name == "true" then
|
||||
return true, pend + 1
|
||||
elseif name == "false" then
|
||||
return false, pend + 1
|
||||
elseif name == "null" then
|
||||
return nullval, pend + 1
|
||||
end
|
||||
end
|
||||
return nil, pos, "no valid JSON value at " .. loc (str, pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function optionalmetatables(...)
|
||||
if select("#", ...) > 0 then
|
||||
return ...
|
||||
else
|
||||
return {__jsontype = 'object'}, {__jsontype = 'array'}
|
||||
end
|
||||
end
|
||||
|
||||
function json.decode (str, pos, nullval, ...)
|
||||
local objectmeta, arraymeta = optionalmetatables(...)
|
||||
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
end
|
||||
|
||||
function json.use_lpeg ()
|
||||
local g = require ("lpeg")
|
||||
local pegmatch = g.match
|
||||
local P, S, R, V = g.P, g.S, g.R, g.V
|
||||
|
||||
local function ErrorCall (str, pos, msg, state)
|
||||
if not state.msg then
|
||||
state.msg = msg .. " at " .. loc (str, pos)
|
||||
state.pos = pos
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function Err (msg)
|
||||
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
|
||||
end
|
||||
|
||||
local Space = (S" \n\r\t" + P"\239\187\191")^0
|
||||
|
||||
local PlainChar = 1 - S"\"\\\n\r"
|
||||
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
|
||||
local HexDigit = R("09", "af", "AF")
|
||||
local function UTF16Surrogate (match, pos, high, low)
|
||||
high, low = tonumber (high, 16), tonumber (low, 16)
|
||||
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
||||
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
local function UTF16BMP (hex)
|
||||
return unichar (tonumber (hex, 16))
|
||||
end
|
||||
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
|
||||
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
|
||||
local Char = UnicodeEscape + EscapeSequence + PlainChar
|
||||
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
|
||||
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
|
||||
local Fractal = P"." * R"09"^0
|
||||
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
|
||||
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/tonumber
|
||||
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
|
||||
local SimpleValue = Number + String + Constant
|
||||
local ArrayContent, ObjectContent
|
||||
|
||||
-- The functions parsearray and parseobject parse only a single value/pair
|
||||
-- at a time and store them directly to avoid hitting the LPeg limits.
|
||||
local function parsearray (str, pos, nullval, state)
|
||||
local obj, cont
|
||||
local npos
|
||||
local t, nt = {}, 0
|
||||
repeat
|
||||
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
|
||||
if not npos then break end
|
||||
pos = npos
|
||||
nt = nt + 1
|
||||
t[nt] = obj
|
||||
until cont == 'last'
|
||||
return pos, setmetatable (t, state.arraymeta)
|
||||
end
|
||||
|
||||
local function parseobject (str, pos, nullval, state)
|
||||
local obj, key, cont
|
||||
local npos
|
||||
local t = {}
|
||||
repeat
|
||||
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
|
||||
if not npos then break end
|
||||
pos = npos
|
||||
t[key] = obj
|
||||
until cont == 'last'
|
||||
return pos, setmetatable (t, state.objectmeta)
|
||||
end
|
||||
|
||||
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
|
||||
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
|
||||
local Value = Space * (Array + Object + SimpleValue)
|
||||
local ExpectedValue = Value + Space * Err "value expected"
|
||||
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
||||
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
|
||||
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
||||
local DecodeValue = ExpectedValue * g.Cp ()
|
||||
|
||||
function json.decode (str, pos, nullval, ...)
|
||||
local state = {}
|
||||
state.objectmeta, state.arraymeta = optionalmetatables(...)
|
||||
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
|
||||
if state.msg then
|
||||
return nil, state.pos, state.msg
|
||||
else
|
||||
return obj, retpos
|
||||
end
|
||||
end
|
||||
|
||||
-- use this function only once:
|
||||
json.use_lpeg = function () return json end
|
||||
|
||||
json.using_lpeg = true
|
||||
|
||||
return json -- so you can get the module using json = require "dkjson".use_lpeg()
|
||||
end
|
||||
|
||||
if always_try_using_lpeg then
|
||||
pcall (json.use_lpeg)
|
||||
end
|
||||
|
||||
return json
|
||||
|
||||
-->
|
||||
187
spine-love/spine-love/spine.lua
Normal file
@ -0,0 +1,187 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2013, Esoteric Software
|
||||
-- Copyright (c) 2013, Iliyas Jorio
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Redistribution and use in source and binary forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- 1. Redistributions of source code must retain the above copyright notice, this
|
||||
-- list of conditions and the following disclaimer.
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer in the documentation
|
||||
-- and/or other materials provided with the distribution.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
-- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
spine = {}
|
||||
|
||||
spine.utils = require "spine-lua.utils"
|
||||
spine.SkeletonJson = require "spine-lua.SkeletonJson"
|
||||
spine.SkeletonData = require "spine-lua.SkeletonData"
|
||||
spine.BoneData = require "spine-lua.BoneData"
|
||||
spine.SlotData = require "spine-lua.SlotData"
|
||||
spine.Skin = require "spine-lua.Skin"
|
||||
spine.RegionAttachment = require "spine-lua.RegionAttachment"
|
||||
spine.Skeleton = require "spine-lua.Skeleton"
|
||||
spine.Bone = require "spine-lua.Bone"
|
||||
spine.Slot = require "spine-lua.Slot"
|
||||
spine.AttachmentLoader = require "spine-lua.AttachmentLoader"
|
||||
spine.Animation = require "spine-lua.Animation"
|
||||
|
||||
spine.utils.readFile = function (fileName, base)
|
||||
local path = fileName
|
||||
if base then path = base .. '/' .. path end
|
||||
return love.filesystem.read(path)
|
||||
end
|
||||
|
||||
local json = require "spine-love.dkjson"
|
||||
spine.utils.readJSON = function (text)
|
||||
return json.decode(text)
|
||||
end
|
||||
|
||||
spine.Skeleton.failed = {} -- Placeholder for an image that failed to load.
|
||||
|
||||
spine.Skeleton.new_super = spine.Skeleton.new
|
||||
function spine.Skeleton.new (skeletonData, group)
|
||||
local self = spine.Skeleton.new_super(skeletonData)
|
||||
|
||||
-- createImage can customize where images are found.
|
||||
function self:createImage (attachment)
|
||||
return love.graphics.newImage(attachment.name .. ".png")
|
||||
end
|
||||
|
||||
function self:draw()
|
||||
if not self.images then self.images = {} end
|
||||
local images = self.images
|
||||
|
||||
for i,slot in ipairs(self.drawOrder) do
|
||||
local attachment = slot.attachment
|
||||
local image = images[attachment]
|
||||
if not attachment then
|
||||
-- Attachment is gone, remove the image.
|
||||
if image then
|
||||
images[attachment] = nil
|
||||
end
|
||||
else
|
||||
-- Create new image.
|
||||
if not image then
|
||||
image = self:createImage(attachment)
|
||||
if image then
|
||||
local imageWidth = image:getWidth()
|
||||
local imageHeight = image:getHeight()
|
||||
attachment.widthRatio = attachment.width / imageWidth
|
||||
attachment.heightRatio = attachment.height / imageHeight
|
||||
attachment.originX = imageWidth / 2
|
||||
attachment.originY = imageHeight / 2
|
||||
else
|
||||
print("Error creating image: " .. attachment.name)
|
||||
image = spine.Skeleton.failed
|
||||
end
|
||||
self.images[attachment] = image
|
||||
end
|
||||
-- Draw,
|
||||
if image ~= spine.Skeleton.failed then
|
||||
local x = slot.bone.worldX + attachment.x * slot.bone.m00 + attachment.y * slot.bone.m01
|
||||
local y = slot.bone.worldY + attachment.x * slot.bone.m10 + attachment.y * slot.bone.m11
|
||||
local rotation = slot.bone.worldRotation + attachment.rotation
|
||||
local xScale = slot.bone.worldScaleX + attachment.scaleX - 1
|
||||
local yScale = slot.bone.worldScaleY + attachment.scaleY - 1
|
||||
if self.flipX then
|
||||
xScale = -xScale
|
||||
rotation = -rotation
|
||||
end
|
||||
if self.flipY then
|
||||
yScale = -yScale
|
||||
rotation = -rotation
|
||||
end
|
||||
love.graphics.setColor(slot.r, slot.g, slot.b, slot.a)
|
||||
love.graphics.draw(image,
|
||||
self.x + x,
|
||||
self.y - y,
|
||||
-rotation * 3.1415927 / 180,
|
||||
xScale * attachment.widthRatio,
|
||||
yScale * attachment.heightRatio,
|
||||
attachment.originX,
|
||||
attachment.originY)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Debug bones.
|
||||
if self.debugBones then
|
||||
for i,bone in ipairs(self.bones) do
|
||||
local xScale
|
||||
local yScale
|
||||
local rotation = -bone.worldRotation
|
||||
|
||||
if self.flipX then
|
||||
xScale = -1
|
||||
rotation = -rotation
|
||||
else
|
||||
xScale = 1
|
||||
end
|
||||
|
||||
if self.flipY then
|
||||
yScale = -1
|
||||
rotation = -rotation
|
||||
else
|
||||
yScale = 1
|
||||
end
|
||||
|
||||
love.graphics.push()
|
||||
love.graphics.translate(self.x + bone.worldX, self.y - bone.worldY)
|
||||
love.graphics.rotate(rotation * 3.1415927 / 180)
|
||||
love.graphics.scale(xScale, yScale)
|
||||
love.graphics.setColor(255, 0, 0)
|
||||
love.graphics.line(0, 0, bone.data.length, 0)
|
||||
love.graphics.setColor(0, 255, 0)
|
||||
love.graphics.circle('fill', 0, 0, 3)
|
||||
love.graphics.pop()
|
||||
end
|
||||
end
|
||||
|
||||
-- Debug slots.
|
||||
if self.debugSlots then
|
||||
love.graphics.setColor(0, 0, 255, 128)
|
||||
for i,slot in ipairs(self.drawOrder) do
|
||||
local attachment = slot.attachment
|
||||
if attachment then
|
||||
local x = slot.bone.worldX + attachment.x * slot.bone.m00 + attachment.y * slot.bone.m01
|
||||
local y = slot.bone.worldY + attachment.x * slot.bone.m10 + attachment.y * slot.bone.m11
|
||||
local rotation = slot.bone.worldRotation + attachment.rotation
|
||||
local xScale = slot.bone.worldScaleX + attachment.scaleX - 1
|
||||
local yScale = slot.bone.worldScaleY + attachment.scaleY - 1
|
||||
if self.flipX then
|
||||
xScale = -xScale
|
||||
rotation = -rotation
|
||||
end
|
||||
if self.flipY then
|
||||
yScale = -yScale
|
||||
rotation = -rotation
|
||||
end
|
||||
love.graphics.push()
|
||||
love.graphics.translate(self.x + x, self.y - y)
|
||||
love.graphics.rotate(-rotation * 3.1415927 / 180)
|
||||
love.graphics.scale(xScale, yScale)
|
||||
love.graphics.rectangle('line', -attachment.width / 2, -attachment.height / 2, attachment.width, attachment.height)
|
||||
love.graphics.pop()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return spine
|
||||