init
This commit is contained in:
parent
4b45c8fba1
commit
347403ad4d
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"configurations": [
|
||||
//run love in current dir
|
||||
{
|
||||
"name": "love",
|
||||
"type": "f5anything",
|
||||
"request": "launch",
|
||||
"command": "love --console .",
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {
|
||||
"PATH": "${env:PATH}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
BIN
assets/images/backgrounds/bg0.png
Normal file
BIN
assets/images/backgrounds/bg0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
assets/images/spritesheets/player.gif
Normal file
BIN
assets/images/spritesheets/player.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
519
assets/images/spritesheets/player.json
Normal file
519
assets/images/spritesheets/player.json
Normal file
@ -0,0 +1,519 @@
|
||||
{ "frames": [
|
||||
{
|
||||
"filename": "Sprite-0002 0.aseprite",
|
||||
"frame": { "x": 140, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 1.aseprite",
|
||||
"frame": { "x": 0, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 2.aseprite",
|
||||
"frame": { "x": 140, "y": 320, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 3.aseprite",
|
||||
"frame": { "x": 0, "y": 320, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 4.aseprite",
|
||||
"frame": { "x": 840, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 5.aseprite",
|
||||
"frame": { "x": 700, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 6.aseprite",
|
||||
"frame": { "x": 560, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 7.aseprite",
|
||||
"frame": { "x": 420, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 8.aseprite",
|
||||
"frame": { "x": 280, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 9.aseprite",
|
||||
"frame": { "x": 140, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 10.aseprite",
|
||||
"frame": { "x": 280, "y": 320, "w": 140, "h": 150 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 150 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 11.aseprite",
|
||||
"frame": { "x": 420, "y": 320, "w": 140, "h": 150 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 150 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 12.aseprite",
|
||||
"frame": { "x": 0, "y": 620, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 13.aseprite",
|
||||
"frame": { "x": 840, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 14.aseprite",
|
||||
"frame": { "x": 700, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 15.aseprite",
|
||||
"frame": { "x": 560, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 16.aseprite",
|
||||
"frame": { "x": 420, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 17.aseprite",
|
||||
"frame": { "x": 420, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 18.aseprite",
|
||||
"frame": { "x": 280, "y": 610, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 19.aseprite",
|
||||
"frame": { "x": 140, "y": 480, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 20.aseprite",
|
||||
"frame": { "x": 0, "y": 480, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 21.aseprite",
|
||||
"frame": { "x": 840, "y": 470, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 22.aseprite",
|
||||
"frame": { "x": 700, "y": 470, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 23.aseprite",
|
||||
"frame": { "x": 560, "y": 470, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 24.aseprite",
|
||||
"frame": { "x": 140, "y": 620, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 25.aseprite",
|
||||
"frame": { "x": 420, "y": 470, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 26.aseprite",
|
||||
"frame": { "x": 840, "y": 320, "w": 140, "h": 150 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 150 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 27.aseprite",
|
||||
"frame": { "x": 700, "y": 320, "w": 140, "h": 150 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 150 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 28.aseprite",
|
||||
"frame": { "x": 280, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 29.aseprite",
|
||||
"frame": { "x": 280, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 30.aseprite",
|
||||
"frame": { "x": 420, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 31.aseprite",
|
||||
"frame": { "x": 560, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 32.aseprite",
|
||||
"frame": { "x": 700, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 33.aseprite",
|
||||
"frame": { "x": 420, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 34.aseprite",
|
||||
"frame": { "x": 420, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 35.aseprite",
|
||||
"frame": { "x": 840, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 36.aseprite",
|
||||
"frame": { "x": 0, "y": 160, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 37.aseprite",
|
||||
"frame": { "x": 420, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 38.aseprite",
|
||||
"frame": { "x": 280, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 65535
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 39.aseprite",
|
||||
"frame": { "x": 280, "y": 0, "w": 140, "h": 160 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 0, "w": 140, "h": 160 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 40.aseprite",
|
||||
"frame": { "x": 560, "y": 320, "w": 140, "h": 150 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 10, "w": 140, "h": 150 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 41.aseprite",
|
||||
"frame": { "x": 280, "y": 470, "w": 140, "h": 140 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 20, "w": 140, "h": 140 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 42.aseprite",
|
||||
"frame": { "x": 280, "y": 750, "w": 140, "h": 130 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 30, "w": 140, "h": 130 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 43.aseprite",
|
||||
"frame": { "x": 420, "y": 750, "w": 140, "h": 120 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 40, "w": 140, "h": 120 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 44.aseprite",
|
||||
"frame": { "x": 560, "y": 750, "w": 140, "h": 110 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 50, "w": 140, "h": 110 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 45.aseprite",
|
||||
"frame": { "x": 700, "y": 750, "w": 140, "h": 100 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 60, "w": 140, "h": 100 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 46.aseprite",
|
||||
"frame": { "x": 840, "y": 750, "w": 140, "h": 90 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 70, "w": 140, "h": 90 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 47.aseprite",
|
||||
"frame": { "x": 0, "y": 760, "w": 140, "h": 80 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 80, "w": 140, "h": 80 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 48.aseprite",
|
||||
"frame": { "x": 140, "y": 760, "w": 140, "h": 70 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 10, "y": 90, "w": 140, "h": 70 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 49.aseprite",
|
||||
"frame": { "x": 140, "y": 830, "w": 120, "h": 60 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 20, "y": 100, "w": 120, "h": 60 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 50.aseprite",
|
||||
"frame": { "x": 0, "y": 840, "w": 100, "h": 50 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 30, "y": 110, "w": 100, "h": 50 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 51.aseprite",
|
||||
"frame": { "x": 840, "y": 840, "w": 100, "h": 40 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 30, "y": 120, "w": 100, "h": 40 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 52.aseprite",
|
||||
"frame": { "x": 700, "y": 850, "w": 60, "h": 30 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 50, "y": 130, "w": 60, "h": 30 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 53.aseprite",
|
||||
"frame": { "x": 760, "y": 850, "w": 60, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 50, "y": 140, "w": 60, "h": 20 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
},
|
||||
{
|
||||
"filename": "Sprite-0002 54.aseprite",
|
||||
"frame": { "x": 560, "y": 860, "w": 60, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"spriteSourceSize": { "x": 50, "y": 150, "w": 60, "h": 10 },
|
||||
"sourceSize": { "w": 160, "h": 160 },
|
||||
"duration": 1
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.x-dev",
|
||||
"image": "player.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 980, "h": 890 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
{ "name": "Jump", "from": 0, "to": 27, "direction": "forward" },
|
||||
{ "name": "Idle", "from": 28, "to": 29, "direction": "forward" },
|
||||
{ "name": "Walk_left", "from": 30, "to": 33, "direction": "forward" },
|
||||
{ "name": "Walk_right", "from": 34, "to": 37, "direction": "forward" },
|
||||
{ "name": "Default", "from": 38, "to": 38, "direction": "forward" },
|
||||
{ "name": "Die", "from": 39, "to": 54, "direction": "forward" }
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
BIN
assets/images/spritesheets/player.png
Normal file
BIN
assets/images/spritesheets/player.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
assets/sounds/effects/coin.ogg
Normal file
BIN
assets/sounds/effects/coin.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/die.ogg
Normal file
BIN
assets/sounds/effects/die.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/explosion.ogg
Normal file
BIN
assets/sounds/effects/explosion.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/jump.ogg
Normal file
BIN
assets/sounds/effects/jump.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/powerup.ogg
Normal file
BIN
assets/sounds/effects/powerup.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/revive.ogg
Normal file
BIN
assets/sounds/effects/revive.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/select.ogg
Normal file
BIN
assets/sounds/effects/select.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/effects/shoot.ogg
Normal file
BIN
assets/sounds/effects/shoot.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track0.ogg
Normal file
BIN
assets/sounds/music/track0.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track1.ogg
Normal file
BIN
assets/sounds/music/track1.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track10.ogg
Normal file
BIN
assets/sounds/music/track10.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track11.ogg
Normal file
BIN
assets/sounds/music/track11.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track2.ogg
Normal file
BIN
assets/sounds/music/track2.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track3.ogg
Normal file
BIN
assets/sounds/music/track3.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track4.ogg
Normal file
BIN
assets/sounds/music/track4.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track5.ogg
Normal file
BIN
assets/sounds/music/track5.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track6.ogg
Normal file
BIN
assets/sounds/music/track6.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track7.ogg
Normal file
BIN
assets/sounds/music/track7.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track8.ogg
Normal file
BIN
assets/sounds/music/track8.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/music/track9.ogg
Normal file
BIN
assets/sounds/music/track9.ogg
Normal file
Binary file not shown.
51
conf.lua
Normal file
51
conf.lua
Normal file
@ -0,0 +1,51 @@
|
||||
function love.conf(t)
|
||||
t.identity = nil -- The name of the save directory (string)
|
||||
t.appendidentity = false -- Search files in source directory before save directory (boolean)
|
||||
t.version = "11.4" -- The LÖVE version this game was made for (string)
|
||||
t.console = true -- Attach a console (boolean, Windows only)
|
||||
t.accelerometerjoystick = true -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
|
||||
t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean)
|
||||
t.gammacorrect = true -- Enable gamma-correct rendering, when supported by the system (boolean)
|
||||
|
||||
t.audio.mic = false -- Request and use microphone capabilities in Android (boolean)
|
||||
t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only)
|
||||
|
||||
t.window.title = "Weeeeeeeee" -- The window title (string)
|
||||
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
|
||||
t.window.width = 1024 -- The window width (number)
|
||||
t.window.height = 768 -- The window height (number)
|
||||
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
||||
t.window.resizable = false -- Let the window be user-resizable (boolean)
|
||||
t.window.minwidth = 1 -- Minimum window width if the window is resizable (number)
|
||||
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
|
||||
t.window.fullscreen = false -- Enable fullscreen (boolean)
|
||||
t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string)
|
||||
t.window.vsync = 1 -- Vertical sync mode (number)
|
||||
t.window.msaa = 0 -- The number of samples to use with multi-sampled antialiasing (number)
|
||||
t.window.depth = nil -- The number of bits per sample in the depth buffer
|
||||
t.window.stencil = nil -- The number of bits per sample in the stencil buffer
|
||||
t.window.display = 1 -- Index of the monitor to show the window in (number)
|
||||
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
|
||||
t.window.usedpiscale = true -- Enable automatic DPI scaling when highdpi is set to true as well (boolean)
|
||||
t.window.x = nil -- The x-coordinate of the window's position in the specified display (number)
|
||||
t.window.y = nil -- The y-coordinate of the window's position in the specified display (number)
|
||||
|
||||
t.modules.audio = true -- Enable the audio module (boolean)
|
||||
t.modules.data = true -- Enable the data module (boolean)
|
||||
t.modules.event = true -- Enable the event module (boolean)
|
||||
t.modules.font = true -- Enable the font module (boolean)
|
||||
t.modules.graphics = true -- Enable the graphics module (boolean)
|
||||
t.modules.image = true -- Enable the image module (boolean)
|
||||
t.modules.joystick = true -- Enable the joystick module (boolean)
|
||||
t.modules.keyboard = true -- Enable the keyboard module (boolean)
|
||||
t.modules.math = true -- Enable the math module (boolean)
|
||||
t.modules.mouse = true -- Enable the mouse module (boolean)
|
||||
t.modules.physics = true -- Enable the physics module (boolean)
|
||||
t.modules.sound = true -- Enable the sound module (boolean)
|
||||
t.modules.system = true -- Enable the system module (boolean)
|
||||
t.modules.thread = true -- Enable the thread module (boolean)
|
||||
t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update
|
||||
t.modules.touch = true -- Enable the touch module (boolean)
|
||||
t.modules.video = true -- Enable the video module (boolean)
|
||||
t.modules.window = true -- Enable the window module (boolean)
|
||||
end
|
106
libs/cron.lua
Normal file
106
libs/cron.lua
Normal file
@ -0,0 +1,106 @@
|
||||
local cron = {
|
||||
__VERSION = 'cron.lua 2.0.0',
|
||||
__DESCRIPTION = 'Time-related functions for lua',
|
||||
__URL = 'https://github.com/kikito/cron.lua',
|
||||
__LICENSE = [[
|
||||
Copyright (c) 2011 Enrique García Cota
|
||||
|
||||
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.
|
||||
]]
|
||||
}
|
||||
|
||||
-- Private functions
|
||||
|
||||
local function isCallable(callback)
|
||||
local tc = type(callback)
|
||||
if tc == 'function' then return true end
|
||||
if tc == 'table' then
|
||||
local mt = getmetatable(callback)
|
||||
return type(mt) == 'table' and type(mt.__call) == 'function'
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function checkPositiveInteger(name, value)
|
||||
if type(value) ~= "number" or value < 0 then
|
||||
error(name .. " must be a positive number")
|
||||
end
|
||||
end
|
||||
|
||||
local Clock = {}
|
||||
local Clock_mt = {__index = Clock}
|
||||
|
||||
local function newClock(time, callback, update, ...)
|
||||
checkPositiveInteger('time', time)
|
||||
assert(isCallable(callback), "callback must be a function")
|
||||
|
||||
return setmetatable({
|
||||
time = time,
|
||||
callback = callback,
|
||||
args = {...},
|
||||
running = 0,
|
||||
update = update
|
||||
}, Clock_mt)
|
||||
end
|
||||
|
||||
local function updateAfterClock(self, dt) -- returns true if expired
|
||||
checkPositiveInteger('dt', dt)
|
||||
|
||||
if self.running >= self.time then return true end
|
||||
|
||||
self.running = self.running + dt
|
||||
|
||||
if self.running >= self.time then
|
||||
self.callback(unpack(self.args))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function updateEveryClock(self, dt)
|
||||
checkPositiveInteger('dt', dt)
|
||||
|
||||
self.running = self.running + dt
|
||||
|
||||
while self.running >= self.time do
|
||||
self.callback(unpack(self.args))
|
||||
self.running = self.running - self.time
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Clock:reset(running)
|
||||
running = running or 0
|
||||
checkPositiveInteger('running', running)
|
||||
|
||||
self.running = running
|
||||
end
|
||||
|
||||
|
||||
function cron.after(time, callback, ...)
|
||||
return newClock(time, callback, updateAfterClock, ...)
|
||||
end
|
||||
|
||||
function cron.every(time, callback, ...)
|
||||
return newClock(time, callback, updateEveryClock, ...)
|
||||
end
|
||||
|
||||
return cron
|
||||
|
400
libs/json.lua
Normal file
400
libs/json.lua
Normal file
@ -0,0 +1,400 @@
|
||||
--
|
||||
-- json.lua
|
||||
--
|
||||
-- Copyright (c) 2018 rxi
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
local json = { _version = "0.1.1" }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local encode
|
||||
|
||||
local escape_char_map = {
|
||||
[ "\\" ] = "\\\\",
|
||||
[ "\"" ] = "\\\"",
|
||||
[ "\b" ] = "\\b",
|
||||
[ "\f" ] = "\\f",
|
||||
[ "\n" ] = "\\n",
|
||||
[ "\r" ] = "\\r",
|
||||
[ "\t" ] = "\\t",
|
||||
}
|
||||
|
||||
local escape_char_map_inv = { [ "\\/" ] = "/" }
|
||||
for k, v in pairs(escape_char_map) do
|
||||
escape_char_map_inv[v] = k
|
||||
end
|
||||
|
||||
|
||||
local function escape_char(c)
|
||||
return escape_char_map[c] or string.format("\\u%04x", c:byte())
|
||||
end
|
||||
|
||||
|
||||
local function encode_nil(val)
|
||||
return "null"
|
||||
end
|
||||
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if val[1] ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= "number" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then
|
||||
error("invalid table: sparse array")
|
||||
end
|
||||
-- Encode
|
||||
for i, v in ipairs(val) do
|
||||
table.insert(res, encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
|
||||
local type_func_map = {
|
||||
[ "nil" ] = encode_nil,
|
||||
[ "table" ] = encode_table,
|
||||
[ "string" ] = encode_string,
|
||||
[ "number" ] = encode_number,
|
||||
[ "boolean" ] = tostring,
|
||||
}
|
||||
|
||||
|
||||
encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then
|
||||
return f(val, stack)
|
||||
end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.encode(val)
|
||||
return ( encode(val) )
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do
|
||||
res[ select(i, ...) ] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {
|
||||
[ "true" ] = true,
|
||||
[ "false" ] = false,
|
||||
[ "null" ] = nil,
|
||||
}
|
||||
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do
|
||||
if set[str:sub(i, i)] ~= negate then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error( string.format("%s at line %d col %d", msg, line_count, col_count) )
|
||||
end
|
||||
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = math.floor
|
||||
if n <= 0x7f then
|
||||
return string.char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return string.char(f(n / 64) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
|
||||
f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
end
|
||||
error( string.format("invalid unicode codepoint '%x'", n) )
|
||||
end
|
||||
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber( s:sub(3, 6), 16 )
|
||||
local n2 = tonumber( s:sub(9, 12), 16 )
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function parse_string(str, i)
|
||||
local has_unicode_escape = false
|
||||
local has_surrogate_escape = false
|
||||
local has_escape = false
|
||||
local last
|
||||
for j = i + 1, #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
end
|
||||
|
||||
if last == 92 then -- "\\" (escape char)
|
||||
if x == 117 then -- "u" (unicode escape sequence)
|
||||
local hex = str:sub(j + 1, j + 5)
|
||||
if not hex:find("%x%x%x%x") then
|
||||
decode_error(str, j, "invalid unicode escape in string")
|
||||
end
|
||||
if hex:find("^[dD][89aAbB]") then
|
||||
has_surrogate_escape = true
|
||||
else
|
||||
has_unicode_escape = true
|
||||
end
|
||||
else
|
||||
local c = string.char(x)
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j, "invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
has_escape = true
|
||||
end
|
||||
last = nil
|
||||
|
||||
elseif x == 34 then -- '"' (end of string)
|
||||
local s = str:sub(i + 1, j - 1)
|
||||
if has_surrogate_escape then
|
||||
s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape)
|
||||
end
|
||||
if has_unicode_escape then
|
||||
s = s:gsub("\\u....", parse_unicode_escape)
|
||||
end
|
||||
if has_escape then
|
||||
s = s:gsub("\\.", escape_char_map_inv)
|
||||
end
|
||||
return s, j + 1
|
||||
|
||||
else
|
||||
last = x
|
||||
end
|
||||
end
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then
|
||||
decode_error(str, i, "invalid number '" .. s .. "'")
|
||||
end
|
||||
return n, x
|
||||
end
|
||||
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local char_func_map = {
|
||||
[ '"' ] = parse_string,
|
||||
[ "0" ] = parse_number,
|
||||
[ "1" ] = parse_number,
|
||||
[ "2" ] = parse_number,
|
||||
[ "3" ] = parse_number,
|
||||
[ "4" ] = parse_number,
|
||||
[ "5" ] = parse_number,
|
||||
[ "6" ] = parse_number,
|
||||
[ "7" ] = parse_number,
|
||||
[ "8" ] = parse_number,
|
||||
[ "9" ] = parse_number,
|
||||
[ "-" ] = parse_number,
|
||||
[ "t" ] = parse_literal,
|
||||
[ "f" ] = parse_literal,
|
||||
[ "n" ] = parse_literal,
|
||||
[ "[" ] = parse_array,
|
||||
[ "{" ] = parse_object,
|
||||
}
|
||||
|
||||
|
||||
parse = function(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then
|
||||
return f(str, idx)
|
||||
end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.decode(str)
|
||||
if type(str) ~= "string" then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then
|
||||
decode_error(str, idx, "trailing garbage")
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
return json
|
351
libs/peachy.lua
Normal file
351
libs/peachy.lua
Normal file
@ -0,0 +1,351 @@
|
||||
--- A parser/renderer for Aseprite animations in LÖVE.
|
||||
-- @classmod peachy
|
||||
|
||||
local peachy = {
|
||||
_VERSION = "1.0.0-alpha",
|
||||
_DESCRIPTION = "A parser/renderer for Aseprite animations in LÖVE.",
|
||||
_URL = "https://github.com/josh-perry/peachy",
|
||||
_LICENSE = [[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Josh Perry
|
||||
|
||||
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.
|
||||
]]
|
||||
}
|
||||
|
||||
local PATH = select('1', ...):match(".+%.") or ""
|
||||
local json = require(PATH.."libs/json")
|
||||
local cron = require(PATH.."libs/cron")
|
||||
|
||||
peachy.__index = peachy
|
||||
|
||||
--- Creates a new Peachy animation object.
|
||||
--
|
||||
-- If imageData isn't specified then Peachy will attempt to load it using the
|
||||
-- filename from the JSON data.
|
||||
--
|
||||
-- If no initial tag is set then the object will be paused (i.e. not displayed) with no tag.
|
||||
-- The animation will start playing immediately once created.
|
||||
--
|
||||
-- @usage
|
||||
-- -- Load the image ourselves and set animation tag to "Spin".
|
||||
-- -- Will start playing immediately.
|
||||
-- spinner = peachy.new("spinner.json", love.graphics.newImage("spinner.png"), "Spin")
|
||||
--
|
||||
-- @tparam string dataFile a path to an Aseprite JSON file. It is also possible to pass a predecoded table,
|
||||
-- which is useful for performance when creating large amounts of the same animation.
|
||||
-- @tparam Image imageData a LÖVE image to animate.
|
||||
-- @tparam string initialTag the name of the animation tag to use initially.
|
||||
-- @return the new Peachy object.
|
||||
function peachy.new(dataFile, imageData, initialTag)
|
||||
assert(dataFile ~= nil, "No JSON data!")
|
||||
|
||||
local self = setmetatable({}, peachy)
|
||||
|
||||
--store the path to the passed json file
|
||||
self.json_path = dataFile
|
||||
|
||||
-- check if datafile is a lua table (i.e. pre decoded)
|
||||
if type(dataFile) == 'table' then
|
||||
self._jsonData = dataFile
|
||||
else
|
||||
-- Read the data
|
||||
self._jsonData = json.decode(love.filesystem.read(dataFile))
|
||||
end
|
||||
|
||||
-- Load the image
|
||||
self.image = imageData or love.graphics.newImage(self._jsonData.meta.image)
|
||||
|
||||
self:_checkImageSize()
|
||||
|
||||
self:_initializeFrames()
|
||||
self:_initializeTags()
|
||||
|
||||
self.paused = true
|
||||
|
||||
self.tag = nil
|
||||
self.tagName = nil
|
||||
self.direction = nil
|
||||
|
||||
if initialTag then
|
||||
self:setTag(initialTag)
|
||||
self.paused = false
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Switch to a different animation tag.
|
||||
-- In the case that we're attempting to switch to the animation currently playing,
|
||||
-- nothing will happen.
|
||||
--
|
||||
-- @tparam string tag the animation tag name to switch to.
|
||||
function peachy:setTag(tag)
|
||||
assert(tag, "No animation tag specified!")
|
||||
assert(self.frameTags[tag], "Tag "..tag.." not found in frametags!")
|
||||
|
||||
if self.tag == self.frameTags[tag] then
|
||||
return
|
||||
end
|
||||
|
||||
self.tagName = tag
|
||||
self.tag = self.frameTags[self.tagName]
|
||||
self.frameIndex = nil
|
||||
self.direction = self.tag.direction
|
||||
|
||||
if self.direction == "pingpong" then
|
||||
self.direction = "forward"
|
||||
end
|
||||
|
||||
self:nextFrame()
|
||||
end
|
||||
|
||||
--- Jump to a particular frame index (1-based indexes) in the current animation.
|
||||
--
|
||||
-- Errors if the frame is outside the tag's frame range.
|
||||
--
|
||||
-- @usage
|
||||
-- -- Go to the 4th frame
|
||||
-- sound:setFrame(4)
|
||||
--
|
||||
-- @tparam number frame the frame index to jump to.
|
||||
function peachy:setFrame(frame)
|
||||
if frame < 1 or frame > #self.tag.frames then
|
||||
error("Frame "..frame.." is out of range of tag '"..self.tagName.."' (1.."..#self.tag.frames..")")
|
||||
end
|
||||
|
||||
self.frameIndex = frame
|
||||
|
||||
self.frame = self.tag.frames[self.frameIndex]
|
||||
self.frameTimer = cron.after(self.frame.duration, self.nextFrame, self)
|
||||
end
|
||||
|
||||
--- Get the current frame of the current animation
|
||||
-- @usage
|
||||
-- Get the 2nd frame
|
||||
-- local f = sound:getFrame()
|
||||
--
|
||||
function peachy:getFrame()
|
||||
return self.frameIndex
|
||||
end
|
||||
|
||||
--- Get the json path passed in the object
|
||||
-- @usage
|
||||
-- Get the (string) JSON path
|
||||
-- local str_json = obj:getJSON()
|
||||
--
|
||||
function peachy:getJSON()
|
||||
return self.json_path
|
||||
end
|
||||
|
||||
--- Draw the animation's current frame in a specified location.
|
||||
-- @tparam number x the x position.
|
||||
-- @tparam number y the y position.
|
||||
-- @tparam number rot the rotation to draw at.
|
||||
-- @tparam number sx the x scaling.
|
||||
-- @tparam number sy the y scaling.
|
||||
-- @tparam number ox the origin offset x.
|
||||
-- @tparam number oy the origin offset y.
|
||||
function peachy:draw(x, y, rot, sx, sy, ox, oy)
|
||||
if not self.frame then
|
||||
return
|
||||
end
|
||||
|
||||
love.graphics.draw(self.image, self.frame.quad, x, y, rot or 0, sx or 1, sy or 1, ox or 0, oy or 0)
|
||||
end
|
||||
|
||||
--- Update the animation.
|
||||
-- @tparam number dt frame delta. Should be called from love.update and given the dt.
|
||||
function peachy:update(dt)
|
||||
assert(dt, "No dt passed into update!")
|
||||
|
||||
if self.paused then
|
||||
return
|
||||
end
|
||||
|
||||
-- If we're trying to play an animation and it's nil or hasn't been set up
|
||||
-- properly then error
|
||||
assert(self.tag, "No animation tag has been set!")
|
||||
assert(self.frameTimer, "Frame timer hasn't been initialized!")
|
||||
|
||||
-- Update timer in milliseconds since that's how Aseprite stores durations
|
||||
self.frameTimer:update(dt * 1000)
|
||||
end
|
||||
|
||||
--- Move to the next frame.
|
||||
-- Internal: unless you want to skip frames, this generally will not ever
|
||||
-- need to be called manually.
|
||||
function peachy:nextFrame()
|
||||
local forward = self.direction == "forward"
|
||||
|
||||
if forward then
|
||||
self.frameIndex = (self.frameIndex or 0) + 1
|
||||
else
|
||||
self.frameIndex = (self.frameIndex or #self.tag.frames + 1) - 1
|
||||
end
|
||||
|
||||
-- Looping
|
||||
if forward and self.frameIndex > #self.tag.frames then
|
||||
if self.tag.direction == "pingpong" then
|
||||
self:_pingpongBounce()
|
||||
else
|
||||
self.frameIndex = 1
|
||||
end
|
||||
self:call_onLoop()
|
||||
elseif not forward and self.frameIndex < 1 then
|
||||
if self.tag.direction == "pingpong" then
|
||||
self:_pingpongBounce()
|
||||
else
|
||||
self.frameIndex = #self.tag.frames
|
||||
self:call_onLoop()
|
||||
end
|
||||
end
|
||||
|
||||
-- Get next frame
|
||||
self.frame = self.tag.frames[self.frameIndex]
|
||||
|
||||
self.frameTimer = cron.after(self.frame.duration, self.nextFrame, self)
|
||||
end
|
||||
|
||||
--- Check for callbacks
|
||||
function peachy:call_onLoop()
|
||||
if self.callback_onLoop then self.callback_onLoop(unpack(self.args_onLoop)) end
|
||||
end
|
||||
|
||||
--- Pauses the animation.
|
||||
function peachy:pause()
|
||||
self.paused = true
|
||||
end
|
||||
|
||||
--- Unpauses the animation.
|
||||
function peachy:play()
|
||||
self.paused = false
|
||||
end
|
||||
|
||||
--- Stops the animation (pause it then return to first frame or last if specified)
|
||||
function peachy:stop(onLast)
|
||||
local index = 1
|
||||
self.paused = true
|
||||
if onLast then index = #self.tag.frames end
|
||||
self:setFrame(index)
|
||||
end
|
||||
|
||||
--- Adds a callback function that will be called when the animation loops
|
||||
function peachy:onLoop(fn, ...)
|
||||
self.callback_onLoop = fn
|
||||
self.args_onLoop = {...}
|
||||
end
|
||||
|
||||
--- Toggle between playing/paused.
|
||||
function peachy:togglePlay()
|
||||
if self.paused then
|
||||
self:play()
|
||||
else
|
||||
self:pause()
|
||||
end
|
||||
end
|
||||
|
||||
--- Provides width stored in the metadata of a current frame
|
||||
function peachy:getWidth()
|
||||
return self._jsonData.frames[self.frameIndex].frame.w
|
||||
end
|
||||
|
||||
--- Provides height stored in the metadata of a current frame
|
||||
function peachy:getHeight()
|
||||
return self._jsonData.frames[self.frameIndex].frame.h
|
||||
end
|
||||
|
||||
--- Provides dimensions stored in the metadata of a current frame
|
||||
function peachy:getDimensions()
|
||||
return self:getWidth(), self:getHeight()
|
||||
end
|
||||
|
||||
--- Internal: handles the ping-pong animation type.
|
||||
--
|
||||
-- Should only be called when we actually want to bounce.
|
||||
-- Swaps the direction.
|
||||
function peachy:_pingpongBounce()
|
||||
-- We need to increment/decrement frame index by 2 because
|
||||
-- at this point we've already gone to the next frame
|
||||
if self.direction == "forward" then
|
||||
self.direction = "reverse"
|
||||
self.frameIndex = self.frameIndex - 2
|
||||
else
|
||||
self.direction = "forward"
|
||||
self.frameIndex = self.frameIndex + 2
|
||||
end
|
||||
end
|
||||
|
||||
--- Internal: loads all of the frames
|
||||
--
|
||||
-- Loads quads and frame duration data from the JSON.
|
||||
--
|
||||
-- Called from peachy.new
|
||||
function peachy:_initializeFrames()
|
||||
assert(self._jsonData ~= nil, "No JSON data!")
|
||||
assert(self._jsonData.meta ~= nil, "No metadata in JSON!")
|
||||
assert(self._jsonData.frames ~= nil, "No frame data in JSON!")
|
||||
|
||||
-- Initialize all the quads
|
||||
self.frames = {}
|
||||
for _, frameData in ipairs(self._jsonData.frames) do
|
||||
local frame = {}
|
||||
|
||||
local fd = frameData.frame
|
||||
frame.quad = love.graphics.newQuad(fd.x, fd.y, fd.w, fd.h, self._jsonData.meta.size.w, self._jsonData.meta.size.h)
|
||||
frame.duration = frameData.duration
|
||||
|
||||
table.insert(self.frames, frame)
|
||||
end
|
||||
end
|
||||
|
||||
--- Internal: loads all of the animation tags
|
||||
--
|
||||
-- Called from peachy.new
|
||||
function peachy:_initializeTags()
|
||||
assert(self._jsonData ~= nil, "No JSON data!")
|
||||
assert(self._jsonData.meta ~= nil, "No metadata in JSON!")
|
||||
assert(self._jsonData.meta.frameTags ~= nil, "No frame tags in JSON! Make sure you exported them in Aseprite!")
|
||||
|
||||
self.frameTags = {}
|
||||
|
||||
for _, frameTag in ipairs(self._jsonData.meta.frameTags) do
|
||||
local ft = {}
|
||||
ft.direction = frameTag.direction
|
||||
ft.frames = {}
|
||||
|
||||
for frame = frameTag.from + 1, frameTag.to + 1 do
|
||||
table.insert(ft.frames, self.frames[frame])
|
||||
end
|
||||
|
||||
self.frameTags[frameTag.name] = ft
|
||||
end
|
||||
end
|
||||
|
||||
--- Internal: checks that the loaded image size matches the metadata
|
||||
--
|
||||
-- Called from peachy.new
|
||||
function peachy:_checkImageSize()
|
||||
local imageWidth, imageHeight = self._jsonData.meta.size.w, self._jsonData.meta.size.h
|
||||
assert(imageWidth == self.image:getWidth(), "Image width metadata doesn't match actual width of file")
|
||||
assert(imageHeight == self.image:getHeight(), "Image height metadata doesn't match actual height of file")
|
||||
end
|
||||
|
||||
return peachy
|
38
main.lua
Normal file
38
main.lua
Normal file
@ -0,0 +1,38 @@
|
||||
--load peachy
|
||||
peachy = require("libs/peachy")
|
||||
|
||||
--load player
|
||||
player = require("modules/player")
|
||||
|
||||
--load content_loader
|
||||
local content_loader = require("modules/content_loader")
|
||||
spritesheets = content_loader.spritesheets
|
||||
sound_effects = content_loader.sound_effects
|
||||
backgrounds = content_loader.backgrounds
|
||||
music = content_loader.music
|
||||
|
||||
--load globals
|
||||
local globals = require("modules/globals")
|
||||
local game = globals.game
|
||||
|
||||
--load draw_callback
|
||||
draw_mod = require("modules/draw_callback")
|
||||
local draw_callback = draw_mod.draw
|
||||
local drawerinit = draw_mod.drawerinit
|
||||
|
||||
--load update_callback
|
||||
update_mod = require("modules/update_callback")
|
||||
local update_callback = update_mod.update
|
||||
local updateinit = update_mod.updateinit
|
||||
|
||||
drawerinit(spritesheets, player, game)
|
||||
updateinit(game)
|
||||
player:init(sound_effects, spritesheets, game)
|
||||
|
||||
function love.draw()
|
||||
draw_callback()
|
||||
end
|
||||
|
||||
function love.update(dt)
|
||||
update_callback(dt)
|
||||
end
|
64
modules/content_loader.lua
Normal file
64
modules/content_loader.lua
Normal file
@ -0,0 +1,64 @@
|
||||
--import media
|
||||
--import spritesheets
|
||||
local spritesheets = {}
|
||||
--load jsons
|
||||
--load player jumping
|
||||
spritesheets["player_jump"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Jump")
|
||||
--load player walking left
|
||||
spritesheets["player_walk_left"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Walk_left")
|
||||
--load player walking right
|
||||
spritesheets["player_walk_right"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Walk_right")
|
||||
--load player idle
|
||||
spritesheets["player_idle"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Idle")
|
||||
--load player dying
|
||||
spritesheets["player_die"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Die")
|
||||
--load player DEFAULT
|
||||
spritesheets["player_default"] = peachy.new("assets/images/spritesheets/player.json", love.graphics.newImage("assets/images/spritesheets/player.png"), "Default")
|
||||
|
||||
--load backgrounds
|
||||
local backgrounds = {}
|
||||
for i, file in ipairs(love.filesystem.getDirectoryItems("assets/images/backgrounds")) do
|
||||
if file:find(".png") then
|
||||
--load backgrounds
|
||||
print(i)
|
||||
backgrounds[i] = love.graphics.newImage("assets/images/backgrounds/"..file)
|
||||
end
|
||||
end
|
||||
--load sound effects
|
||||
local sound_effects = {}
|
||||
for i, file in ipairs(love.filesystem.getDirectoryItems("assets/sounds/effects")) do
|
||||
if file:find(".ogg") then
|
||||
--load sound effects
|
||||
local keyname = file:gsub(".ogg", "")
|
||||
sound = love.audio.newSource("assets/sounds/effects/"..file, "static")
|
||||
sound_effects[keyname] = {}
|
||||
sound_effects[keyname].volume = 1
|
||||
sound_effects[keyname].timer = love.timer.getTime()
|
||||
sound_effects[keyname].first_play = true
|
||||
sound_effects[keyname].sound = sound
|
||||
sound_effects[keyname].duration = sound:getDuration()
|
||||
sound_effects[keyname].timer_min = sound:getDuration() * 2
|
||||
sound_effects[keyname].play = function(self)
|
||||
if (love.timer.getTime() - self.timer) >= self.timer_min or self.first_play then
|
||||
self.timer = love.timer.getTime()
|
||||
self.first_play = false
|
||||
self.sound:setVolume(self.volume)
|
||||
self.sound:play()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--load music
|
||||
local music = {}
|
||||
for i, file in ipairs(love.filesystem.getDirectoryItems("assets/sounds/music")) do
|
||||
if file:find(".ogg") then
|
||||
--load music
|
||||
music[file:sub(1, -5)] = love.audio.newSource("assets/sounds/music/"..file, "stream")
|
||||
end
|
||||
end
|
||||
return {
|
||||
spritesheets = spritesheets,
|
||||
backgrounds = backgrounds,
|
||||
sound_effects = sound_effects,
|
||||
music = music
|
||||
}
|
33
modules/draw_callback.lua
Normal file
33
modules/draw_callback.lua
Normal file
@ -0,0 +1,33 @@
|
||||
local spritesheets = {}
|
||||
local player = {}
|
||||
local game = {}
|
||||
|
||||
function drawerinit(spritesheetst, playert, gamex)
|
||||
spritesheets = spritesheetst
|
||||
player = playert
|
||||
game = gamex
|
||||
end
|
||||
|
||||
local function draw()
|
||||
--draw background
|
||||
love.graphics.draw(backgrounds[game.level], 0, 0)
|
||||
--draw player_animation
|
||||
player.animation:draw(player.x, player.y)
|
||||
if player.state == "idle" then
|
||||
spritesheets["player_idle"]:draw(player.x, player.y)
|
||||
elseif player.state == "walk_left" then
|
||||
spritesheets["player_walk_left"]:draw(player.x, player.y)
|
||||
elseif player.state == "walk_right" then
|
||||
spritesheets["player_walk_right"]:draw(player.x, player.y)
|
||||
elseif player.state == "jump" then
|
||||
spritesheets["player_jump"]:draw(player.x, player.y)
|
||||
elseif player.state == "die" then
|
||||
spritesheets["player_die"]:draw(player.x, player.y)
|
||||
else
|
||||
spritesheets["player_default"]:draw(player.x, player.y)
|
||||
end
|
||||
end
|
||||
return {
|
||||
drawerinit = drawerinit,
|
||||
draw = draw
|
||||
}
|
13
modules/globals.lua
Normal file
13
modules/globals.lua
Normal file
@ -0,0 +1,13 @@
|
||||
local game = {}
|
||||
game.debug = true
|
||||
game.width = 1024
|
||||
game.height = 768
|
||||
game.title = "Weeeeeeeee"
|
||||
game.version = "0.0.1"
|
||||
game.fullscreen = false
|
||||
game.level = 1
|
||||
game.die_animation_elapsed = false
|
||||
|
||||
return {
|
||||
game = game
|
||||
}
|
80
modules/player.lua
Normal file
80
modules/player.lua
Normal file
@ -0,0 +1,80 @@
|
||||
local player = {}
|
||||
player.x = 0
|
||||
player.y = 500
|
||||
player.width = 160
|
||||
player.height = 160
|
||||
player.speed = 200
|
||||
player.jump_height = 500
|
||||
player.state = "idle"
|
||||
player.direction = "right"
|
||||
player.alive = true
|
||||
player.init = function(self, sound_effects, spritesheets, game)
|
||||
self.sound_effects = sound_effects
|
||||
self.spritesheets = spritesheets
|
||||
self.game = game
|
||||
player.animation = spritesheets["player_idle"]
|
||||
end
|
||||
|
||||
player.walk_right = function(self, dt)
|
||||
if self.x < self.game.width - self.width and self.alive then
|
||||
self.x = self.x + self.speed * dt
|
||||
self.state = "walk_right"
|
||||
self.direction = "right"
|
||||
self.animation = self.spritesheets["player_walk_right"]
|
||||
end
|
||||
end
|
||||
player.walk_left = function(self, dt)
|
||||
if self.x > 0 and self.alive then
|
||||
self.x = self.x - self.speed * dt
|
||||
self.state = "walk_left"
|
||||
self.direction = "left"
|
||||
self.animation = self.spritesheets["player_walk_left"]
|
||||
end
|
||||
end
|
||||
player.jump = function(self, dt)
|
||||
if self.y > 0 and self.alive then
|
||||
self.y = self.y - self.jump_height * dt
|
||||
self.state = "jump"
|
||||
self.animation = self.spritesheets["player_jump"]
|
||||
self.sound_effects["jump"]:play()
|
||||
end
|
||||
end
|
||||
player.down = function(self, dt)
|
||||
if self.y < self.game.height - self.height and self.alive then
|
||||
self.y = self.y + self.jump_height * dt
|
||||
self.state = "jump"
|
||||
self.animation = self.spritesheets["player_jump"]
|
||||
self.sound_effects["jump"]:play()
|
||||
end
|
||||
end
|
||||
player.die = function(self, dt)
|
||||
if self.alive then
|
||||
self.alive = false
|
||||
self.state = "die"
|
||||
self.animation = self.spritesheets["player_die"]
|
||||
self.sound_effects["die"]:play()
|
||||
die_animation_elapsed = false
|
||||
end
|
||||
end
|
||||
player.revive = function(self, dt)
|
||||
if not self.alive then
|
||||
self.alive = true
|
||||
self.state = "idle"
|
||||
self.animation = self.spritesheets["player_default"]
|
||||
self.sound_effects["revive"]:play()
|
||||
die_animation_elapsed = false
|
||||
end
|
||||
end
|
||||
player.idle = function(self, dt)
|
||||
if self.alive then
|
||||
self.state = "idle"
|
||||
self.animation = self.spritesheets["player_idle"]
|
||||
end
|
||||
end
|
||||
player.default = function(self, dt)
|
||||
if self.alive then
|
||||
self.state = "default"
|
||||
self.animation = self.spritesheets["player_default"]
|
||||
end
|
||||
end
|
||||
return player
|
54
modules/update_callback.lua
Normal file
54
modules/update_callback.lua
Normal file
@ -0,0 +1,54 @@
|
||||
local game = {}
|
||||
|
||||
local function updateinit(gamex)
|
||||
game = gamex
|
||||
end
|
||||
|
||||
local function update(dt)
|
||||
--update player_animation
|
||||
if spritesheets["player_die"]:getFrame() ~= 16 and not game.die_animation_elapsed then
|
||||
spritesheets["player_die"]:update(dt)
|
||||
else
|
||||
game.die_animation_elapsed = true
|
||||
end
|
||||
if player.alive then
|
||||
spritesheets["player_jump"]:update(dt)
|
||||
spritesheets["player_walk_left"]:update(dt)
|
||||
spritesheets["player_walk_right"]:update(dt)
|
||||
spritesheets["player_idle"]:update(dt)
|
||||
spritesheets["player_default"]:update(dt)
|
||||
end
|
||||
|
||||
--get keyboard
|
||||
local key = love.keyboard.isDown
|
||||
--move player
|
||||
if key("d") then
|
||||
player:walk_right(dt)
|
||||
elseif key("a") then
|
||||
player:walk_left(dt)
|
||||
else
|
||||
player:idle(dt)
|
||||
end
|
||||
--jump player
|
||||
if key("w") then
|
||||
player:jump(dt)
|
||||
end
|
||||
if game.debug then
|
||||
if key("s") then
|
||||
player:down(dt)
|
||||
end
|
||||
if key("f") then
|
||||
--die
|
||||
player:die(dt)
|
||||
game.die_animation_elapsed = false
|
||||
elseif key("g") then
|
||||
--revive player
|
||||
player:revive(dt)
|
||||
game.die_animation_elapsed = false
|
||||
end
|
||||
end
|
||||
end
|
||||
return {
|
||||
update = update,
|
||||
updateinit = updateinit
|
||||
}
|
97
test.tldr
Normal file
97
test.tldr
Normal file
@ -0,0 +1,97 @@
|
||||
{
|
||||
"document": {
|
||||
"id": "doc",
|
||||
"name": "New Document",
|
||||
"version": 15.3,
|
||||
"pages": {
|
||||
"page": {
|
||||
"id": "page",
|
||||
"name": "Page 1",
|
||||
"childIndex": 1,
|
||||
"shapes": {
|
||||
"feba193a-4518-4953-0fd0-31a3c7550237": {
|
||||
"id": "feba193a-4518-4953-0fd0-31a3c7550237",
|
||||
"type": "draw",
|
||||
"name": "Draw",
|
||||
"parentId": "page",
|
||||
"childIndex": 1,
|
||||
"point": [
|
||||
786,
|
||||
360.5
|
||||
],
|
||||
"rotation": 0,
|
||||
"style": {
|
||||
"color": "black",
|
||||
"size": "small",
|
||||
"isFilled": false,
|
||||
"dash": "draw",
|
||||
"scale": 1
|
||||
},
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
],
|
||||
"isComplete": true
|
||||
},
|
||||
"c3e4d223-d03e-4cd0-278b-53b9ae1164f0": {
|
||||
"id": "c3e4d223-d03e-4cd0-278b-53b9ae1164f0",
|
||||
"type": "draw",
|
||||
"name": "Draw",
|
||||
"parentId": "page",
|
||||
"childIndex": 2,
|
||||
"point": [
|
||||
2315.63,
|
||||
1240.9
|
||||
],
|
||||
"rotation": 0,
|
||||
"style": {
|
||||
"color": "black",
|
||||
"size": "small",
|
||||
"isFilled": false,
|
||||
"dash": "draw",
|
||||
"scale": 1
|
||||
},
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
],
|
||||
"isComplete": true
|
||||
}
|
||||
},
|
||||
"bindings": {}
|
||||
}
|
||||
},
|
||||
"pageStates": {
|
||||
"page": {
|
||||
"id": "page",
|
||||
"selectedIds": [],
|
||||
"camera": {
|
||||
"point": [
|
||||
0,
|
||||
-79.5
|
||||
],
|
||||
"zoom": 1
|
||||
},
|
||||
"editingId": null
|
||||
}
|
||||
},
|
||||
"assets": {}
|
||||
},
|
||||
"assets": {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user