added support for changing volume of audio
This commit is contained in:
parent
760bdafe1c
commit
14c029e31f
BIN
dist/demo_assets/sounds/title.mp3
vendored
Normal file
BIN
dist/demo_assets/sounds/title.mp3
vendored
Normal file
Binary file not shown.
BIN
dist/hw4_assets/fonts/NoPixel.ttf
vendored
BIN
dist/hw4_assets/fonts/NoPixel.ttf
vendored
Binary file not shown.
BIN
dist/hw4_assets/sounds/jump-3.wav
vendored
BIN
dist/hw4_assets/sounds/jump-3.wav
vendored
Binary file not shown.
BIN
dist/hw4_assets/sprites/2bitbackground.png
vendored
BIN
dist/hw4_assets/sprites/2bitbackground.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB |
BIN
dist/hw4_assets/sprites/coin.png
vendored
BIN
dist/hw4_assets/sprites/coin.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 190 B |
22
dist/hw4_assets/spritesheets/ghostBunny.json
vendored
22
dist/hw4_assets/spritesheets/ghostBunny.json
vendored
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"name": "GhostBunny",
|
|
||||||
"spriteSheetImage": "ghostBunny.png",
|
|
||||||
"spriteWidth": 16,
|
|
||||||
"spriteHeight": 16,
|
|
||||||
"columns": 5,
|
|
||||||
"rows": 1,
|
|
||||||
"animations": [
|
|
||||||
{
|
|
||||||
"name": "IDLE",
|
|
||||||
"frames": [ {"index": 0, "duration": 1} ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "WALK",
|
|
||||||
"frames": [ {"index": 0, "duration": 16}, {"index": 1, "duration": 16}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "DYING",
|
|
||||||
"frames": [ {"index": 2, "duration": 8}, {"index": 3, "duration": 8}, {"index": 4, "duration": 8}]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
BIN
dist/hw4_assets/spritesheets/ghostBunny.png
vendored
BIN
dist/hw4_assets/spritesheets/ghostBunny.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 367 B |
26
dist/hw4_assets/spritesheets/hopper.json
vendored
26
dist/hw4_assets/spritesheets/hopper.json
vendored
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Hopper",
|
|
||||||
"spriteSheetImage": "hopper.png",
|
|
||||||
"spriteWidth": 16,
|
|
||||||
"spriteHeight": 16,
|
|
||||||
"columns": 15,
|
|
||||||
"rows": 1,
|
|
||||||
"animations": [
|
|
||||||
{
|
|
||||||
"name": "IDLE",
|
|
||||||
"frames": [ {"index": 0, "duration": 1} ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "WALK",
|
|
||||||
"frames": [ {"index": 0, "duration": 16}, {"index": 1, "duration": 16}, {"index": 2, "duration": 16}, {"index": 3, "duration": 16}, {"index": 4, "duration": 16}, {"index": 5, "duration": 16}, {"index": 6, "duration": 16}, {"index": 7, "duration": 16} ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JUMP",
|
|
||||||
"frames":[ {"index": 8, "duration": 8}, {"index": 9, "duration": 8}, {"index": 10, "duration": 8}, {"index": 11, "duration": 8}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "DYING",
|
|
||||||
"frames":[ {"index": 12, "duration": 8}, {"index": 13, "duration": 8}, {"index": 14, "duration": 8} ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
BIN
dist/hw4_assets/spritesheets/hopper.png
vendored
BIN
dist/hw4_assets/spritesheets/hopper.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 641 B |
27
dist/hw4_assets/spritesheets/platformPlayer.json
vendored
27
dist/hw4_assets/spritesheets/platformPlayer.json
vendored
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"name": "PlatformPlayer",
|
|
||||||
"spriteSheetImage": "platformPlayer.png",
|
|
||||||
"spriteWidth": 16,
|
|
||||||
"spriteHeight": 16,
|
|
||||||
"columns": 7,
|
|
||||||
"rows": 1,
|
|
||||||
"durationType": "time",
|
|
||||||
"animations": [
|
|
||||||
{
|
|
||||||
"name": "IDLE",
|
|
||||||
"frames": [ {"index": 0, "duration": 540}, {"index": 1, "duration": 16}, {"index": 2, "duration": 16}, {"index": 3, "duration": 16}, {"index": 0, "duration": 360}, {"index": 1, "duration": 16}, {"index": 2, "duration": 16}, {"index": 3, "duration": 16}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "WALK",
|
|
||||||
"frames": [ {"index": 0, "duration": 16}, {"index": 4, "duration": 16}, {"index": 0, "duration": 16}, {"index": 5, "duration": 16} ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JUMP",
|
|
||||||
"frames":[ {"index": 6, "duration": 32}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "FALL",
|
|
||||||
"frames":[ {"index": 4, "duration": 32}]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
BIN
dist/hw4_assets/spritesheets/platformPlayer.png
vendored
BIN
dist/hw4_assets/spritesheets/platformPlayer.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 300 B |
558
dist/hw4_assets/tilemaps/level1.json
vendored
558
dist/hw4_assets/tilemaps/level1.json
vendored
|
@ -1,558 +0,0 @@
|
||||||
{ "compressionlevel":-1,
|
|
||||||
"editorsettings":
|
|
||||||
{
|
|
||||||
"export":
|
|
||||||
{
|
|
||||||
"format":"json",
|
|
||||||
"target":"platformer.json"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height":20,
|
|
||||||
"infinite":false,
|
|
||||||
"layers":[
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 43, 0, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 54, 55, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 62, 63, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
"height":20,
|
|
||||||
"id":2,
|
|
||||||
"name":"Background",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":0
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 20, 20, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 11, 12, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 12, 12, 12, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 23, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 16, 12, 12, 12, 31, 32, 12, 12, 12, 12, 12, 12, 9, 12, 12, 12, 12, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 7, 20, 20, 20, 20, 20, 20, 8, 12, 12, 12, 12, 10, 12, 23, 24, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 16, 12, 12, 13, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 12, 31, 32, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 19, 20, 20, 20, 20, 13, 0, 0, 0, 0, 0, 0, 11, 20, 20, 20, 20, 20, 20, 20, 8, 12, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 2, 2, 2, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 10, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 2, 2, 2, 2, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 10, 12, 12, 12, 12, 12, 12, 10, 15, 4, 4, 4, 4, 4, 4, 12, 12],
|
|
||||||
"height":20,
|
|
||||||
"id":1,
|
|
||||||
"name":"Main",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"ground"
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"draworder":"topdown",
|
|
||||||
"id":4,
|
|
||||||
"name":"Coins",
|
|
||||||
"objects":[
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":2,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":256,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":3,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":272,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":4,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":368,
|
|
||||||
"y":288
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":5,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":384,
|
|
||||||
"y":288
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":6,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":400,
|
|
||||||
"y":288
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":7,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":688,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":8,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":688,
|
|
||||||
"y":288
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":9,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":688,
|
|
||||||
"y":304
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":10,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":784,
|
|
||||||
"y":256
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":11,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":832,
|
|
||||||
"y":256
|
|
||||||
}],
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":1
|
|
||||||
}],
|
|
||||||
"type":"objectgroup",
|
|
||||||
"visible":true,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 64, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 57, 0, 59, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 57, 0, 0, 0, 0, 61, 0, 40, 0, 0, 0, 0, 0, 0, 56, 59, 0, 59, 0, 0, 0, 58, 0, 0, 0, 0, 61, 0, 0, 49, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
"height":20,
|
|
||||||
"id":3,
|
|
||||||
"name":"Foreground",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":2
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
}],
|
|
||||||
"nextlayerid":5,
|
|
||||||
"nextobjectid":14,
|
|
||||||
"orientation":"orthogonal",
|
|
||||||
"renderorder":"right-down",
|
|
||||||
"tiledversion":"1.3.4",
|
|
||||||
"tileheight":16,
|
|
||||||
"tilesets":[
|
|
||||||
{
|
|
||||||
"columns":8,
|
|
||||||
"firstgid":1,
|
|
||||||
"image":"platformer.png",
|
|
||||||
"imageheight":128,
|
|
||||||
"imagewidth":128,
|
|
||||||
"margin":0,
|
|
||||||
"name":"platformer_tileset",
|
|
||||||
"spacing":0,
|
|
||||||
"tilecount":64,
|
|
||||||
"tileheight":16,
|
|
||||||
"tilewidth":16
|
|
||||||
}],
|
|
||||||
"tilewidth":16,
|
|
||||||
"type":"map",
|
|
||||||
"version":1.2,
|
|
||||||
"width":64
|
|
||||||
}
|
|
901
dist/hw4_assets/tilemaps/level2.json
vendored
901
dist/hw4_assets/tilemaps/level2.json
vendored
|
@ -1,901 +0,0 @@
|
||||||
{ "compressionlevel":-1,
|
|
||||||
"editorsettings":
|
|
||||||
{
|
|
||||||
"export":
|
|
||||||
{
|
|
||||||
"target":"."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height":20,
|
|
||||||
"infinite":false,
|
|
||||||
"layers":[
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 36, 36, 36, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 44, 44, 44, 0, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 0, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 36, 36, 36, 0, 0, 0, 0, 0, 0, 44, 44, 44, 54, 55, 44, 44, 44, 44, 44, 44, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 54, 55, 44, 44, 0, 0, 0, 0, 0, 0, 0, 44, 44, 62, 63, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 62, 63, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
"height":20,
|
|
||||||
"id":2,
|
|
||||||
"name":"Background",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":0
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 12, 13, 0, 0, 0, 0, 0, 30, 0, 0, 3, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 3, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 10, 12, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 11, 10, 12, 12, 13, 0, 0, 0, 0, 0, 0, 11, 12, 7, 20, 20, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 11, 10, 13, 0, 0, 14, 0, 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 0, 0, 30, 0, 0, 0, 0, 0, 11, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 11, 12, 13, 0, 0, 14, 0, 0, 11, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 10, 13, 0, 0, 0, 0, 0, 0, 19, 20, 20, 29, 0, 14, 0, 0, 19, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 27, 20, 20, 20, 20, 21, 0, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 11, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 10, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 19, 20, 21, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 5, 0, 0, 0, 0, 0, 0, 11, 12, 10, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 12, 12, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 13, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 12, 12, 4, 5, 0, 0, 0, 0, 3, 4, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 11, 12, 12, 12, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 21, 0, 0, 0, 0, 0, 0, 11, 10, 12, 12, 12, 12, 12, 15, 4, 4, 4, 4, 16, 12, 12, 12, 12, 12, 13, 1, 1, 1, 1, 1, 1, 11, 12, 12, 12, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
||||||
"height":20,
|
|
||||||
"id":3,
|
|
||||||
"name":"Main",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"ground"
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"draworder":"topdown",
|
|
||||||
"id":4,
|
|
||||||
"name":"Coins",
|
|
||||||
"objects":[
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":1,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":272,
|
|
||||||
"y":80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":2,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":288,
|
|
||||||
"y":80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":3,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":112,
|
|
||||||
"y":80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":4,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":64,
|
|
||||||
"y":128
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":5,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":160,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":6,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":176,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":7,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":192,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":8,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":208,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":9,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":384,
|
|
||||||
"y":176
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":10,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":400,
|
|
||||||
"y":176
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":11,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":384,
|
|
||||||
"y":192
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":12,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":400,
|
|
||||||
"y":192
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":13,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":400,
|
|
||||||
"y":208
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":14,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":704,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":15,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":720,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":16,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":752,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":17,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":736,
|
|
||||||
"y":272
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gid":25,
|
|
||||||
"height":16,
|
|
||||||
"id":18,
|
|
||||||
"name":"",
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Group",
|
|
||||||
"type":"string",
|
|
||||||
"value":"coin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"HasPhysics",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsCollidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"IsTrigger",
|
|
||||||
"type":"bool",
|
|
||||||
"value":true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerGroup",
|
|
||||||
"type":"string",
|
|
||||||
"value":"player"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"TriggerOnEnter",
|
|
||||||
"type":"string",
|
|
||||||
"value":"PlayerHitCoin"
|
|
||||||
}],
|
|
||||||
"rotation":0,
|
|
||||||
"type":"",
|
|
||||||
"visible":true,
|
|
||||||
"width":16,
|
|
||||||
"x":768,
|
|
||||||
"y":272
|
|
||||||
}],
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":1
|
|
||||||
}],
|
|
||||||
"type":"objectgroup",
|
|
||||||
"visible":true,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 40, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 48, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 56, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 2, 0, 64, 0, 0, 0, 0, 56, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 2, 2, 2, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 57, 2, 0, 0, 0, 0, 0, 0, 0, 64, 57, 0, 61, 60, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 59, 0, 0, 59, 0, 0, 0, 0, 0, 2, 59, 58, 0, 59, 0, 0, 58, 2, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
"height":20,
|
|
||||||
"id":1,
|
|
||||||
"name":"Foreground",
|
|
||||||
"opacity":1,
|
|
||||||
"properties":[
|
|
||||||
{
|
|
||||||
"name":"Collidable",
|
|
||||||
"type":"bool",
|
|
||||||
"value":false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Depth",
|
|
||||||
"type":"int",
|
|
||||||
"value":2
|
|
||||||
}],
|
|
||||||
"type":"tilelayer",
|
|
||||||
"visible":true,
|
|
||||||
"width":64,
|
|
||||||
"x":0,
|
|
||||||
"y":0
|
|
||||||
}],
|
|
||||||
"nextlayerid":5,
|
|
||||||
"nextobjectid":19,
|
|
||||||
"orientation":"orthogonal",
|
|
||||||
"renderorder":"right-down",
|
|
||||||
"tiledversion":"1.3.4",
|
|
||||||
"tileheight":16,
|
|
||||||
"tilesets":[
|
|
||||||
{
|
|
||||||
"columns":8,
|
|
||||||
"firstgid":1,
|
|
||||||
"image":"platformer.png",
|
|
||||||
"imageheight":128,
|
|
||||||
"imagewidth":128,
|
|
||||||
"margin":0,
|
|
||||||
"name":"platformer_tileset",
|
|
||||||
"spacing":0,
|
|
||||||
"tilecount":64,
|
|
||||||
"tileheight":16,
|
|
||||||
"tilewidth":16
|
|
||||||
}],
|
|
||||||
"tilewidth":16,
|
|
||||||
"type":"map",
|
|
||||||
"version":1.2,
|
|
||||||
"width":64
|
|
||||||
}
|
|
BIN
dist/hw4_assets/tilemaps/platformer.png
vendored
BIN
dist/hw4_assets/tilemaps/platformer.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
|
@ -1,71 +0,0 @@
|
||||||
import Idle from "./Idle";
|
|
||||||
import Jump from "./Jump";
|
|
||||||
import Walk from "./Walk";
|
|
||||||
import GameNode from "../../Wolfie2D/Nodes/GameNode";
|
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import StateMachineAI from "../../Wolfie2D/AI/StateMachineAI";
|
|
||||||
import { HW4_Events } from "../hw4_enums";
|
|
||||||
import { EaseFunctionType } from "../../Wolfie2D/Utils/EaseFunctions";
|
|
||||||
|
|
||||||
export enum EnemyStates {
|
|
||||||
IDLE = "idle",
|
|
||||||
WALK = "walk",
|
|
||||||
JUMP = "jump",
|
|
||||||
PREVIOUS = "previous"
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class EnemyController extends StateMachineAI {
|
|
||||||
owner: GameNode;
|
|
||||||
jumpy: boolean;
|
|
||||||
direction: Vec2 = Vec2.ZERO;
|
|
||||||
velocity: Vec2 = Vec2.ZERO;
|
|
||||||
speed: number = 200;
|
|
||||||
|
|
||||||
initializeAI(owner: GameNode, options: Record<string, any>){
|
|
||||||
this.owner = owner;
|
|
||||||
this.jumpy = options.jumpy ? options.jumpy : false;
|
|
||||||
|
|
||||||
this.receiver.subscribe(HW4_Events.PLAYER_MOVE);
|
|
||||||
if(this.jumpy){
|
|
||||||
this.receiver.subscribe(HW4_Events.PLAYER_JUMP);
|
|
||||||
this.speed = 100;
|
|
||||||
|
|
||||||
// Give the owner a tween for the jump
|
|
||||||
owner.tweens.add("jump", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 300,
|
|
||||||
effects: [
|
|
||||||
{
|
|
||||||
property: "rotation",
|
|
||||||
resetOnComplete: true,
|
|
||||||
start: -3.14/8,
|
|
||||||
end: 3.14/8,
|
|
||||||
ease: EaseFunctionType.IN_OUT_SINE
|
|
||||||
}
|
|
||||||
],
|
|
||||||
reverseOnComplete: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let idle = new Idle(this, owner);
|
|
||||||
this.addState(EnemyStates.IDLE, idle);
|
|
||||||
let walk = new Walk(this, owner);
|
|
||||||
this.addState(EnemyStates.WALK, walk);
|
|
||||||
let jump = new Jump(this, owner);
|
|
||||||
this.addState(EnemyStates.JUMP, jump);
|
|
||||||
|
|
||||||
this.initialize(EnemyStates.IDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeState(stateName: string): void {
|
|
||||||
|
|
||||||
if(stateName === EnemyStates.JUMP){
|
|
||||||
this.stack.push(this.stateMap.get(stateName));
|
|
||||||
}
|
|
||||||
super.changeState(stateName);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
import State from "../../Wolfie2D/DataTypes/State/State";
|
|
||||||
import StateMachine from "../../Wolfie2D/DataTypes/State/StateMachine";
|
|
||||||
import GameEvent from "../../Wolfie2D/Events/GameEvent";
|
|
||||||
import GameNode from "../../Wolfie2D/Nodes/GameNode";
|
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import EnemyController from "./EnemyController";
|
|
||||||
|
|
||||||
export default abstract class EnemyState extends State {
|
|
||||||
owner: GameNode;
|
|
||||||
gravity: number = 1000;
|
|
||||||
parent: EnemyController
|
|
||||||
|
|
||||||
constructor(parent: StateMachine, owner: GameNode){
|
|
||||||
super(parent);
|
|
||||||
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent): void {}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
// Do gravity
|
|
||||||
this.parent.velocity.y += this.gravity*deltaT;
|
|
||||||
|
|
||||||
if(this.owner.onWall){
|
|
||||||
// Flip around
|
|
||||||
this.parent.direction.x *= -1;
|
|
||||||
(<AnimatedSprite>this.owner).invertX = !(<AnimatedSprite>this.owner).invertX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
import GameEvent from "../../Wolfie2D/Events/GameEvent";
|
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { HW4_Events } from "../hw4_enums";
|
|
||||||
import { EnemyStates } from "./EnemyController";
|
|
||||||
import OnGround from "./OnGround";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The idle enemy state. Enemies don't do anything until the player comes near them.
|
|
||||||
*/
|
|
||||||
export default class Idle extends OnGround {
|
|
||||||
onEnter(): void {
|
|
||||||
this.parent.speed = this.parent.speed;
|
|
||||||
(<AnimatedSprite>this.owner).animation.play("IDLE", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
(<AnimatedSprite>this.owner).animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent) {
|
|
||||||
if(event.type === HW4_Events.PLAYER_MOVE){
|
|
||||||
let pos = event.data.get("position");
|
|
||||||
if(this.owner.position.x - pos.x < (64*10)){
|
|
||||||
this.finished(EnemyStates.WALK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
this.parent.velocity.x = 0;
|
|
||||||
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { EnemyStates } from "./EnemyController";
|
|
||||||
import EnemyState from "./EnemyState";
|
|
||||||
|
|
||||||
export default class Jump extends EnemyState {
|
|
||||||
|
|
||||||
onEnter(): void {
|
|
||||||
(<AnimatedSprite>this.owner).animation.play("JUMP", true);
|
|
||||||
(<AnimatedSprite>this.owner).tweens.play("jump", true);
|
|
||||||
this.gravity = 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
if(this.owner.onGround){
|
|
||||||
this.finished(EnemyStates.PREVIOUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.owner.onCeiling){
|
|
||||||
this.parent.velocity.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.velocity.x += this.parent.direction.x * this.parent.speed/3.5 - 0.3*this.parent.velocity.x;
|
|
||||||
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
(<AnimatedSprite>this.owner).animation.stop();
|
|
||||||
(<AnimatedSprite>this.owner).tweens.stop("jump");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
import GameEvent from "../../Wolfie2D/Events/GameEvent";
|
|
||||||
import { EnemyStates } from "./EnemyController";
|
|
||||||
import EnemyState from "./EnemyState";
|
|
||||||
|
|
||||||
export default class OnGround extends EnemyState {
|
|
||||||
onEnter(): void {}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent): void {
|
|
||||||
super.handleInput(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
if(this.parent.velocity.y > 0){
|
|
||||||
this.parent.velocity.y = 0;
|
|
||||||
}
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
if(!this.owner.onGround && this.parent.jumpy && this.owner.active){
|
|
||||||
this.finished(EnemyStates.JUMP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { EnemyStates } from "./EnemyController";
|
|
||||||
import OnGround from "./OnGround";
|
|
||||||
|
|
||||||
export default class Walk extends OnGround {
|
|
||||||
time: number;
|
|
||||||
|
|
||||||
onEnter(): void {
|
|
||||||
if(this.parent.direction.isZero()){
|
|
||||||
this.parent.direction = new Vec2(-1, 0);
|
|
||||||
(<AnimatedSprite>this.owner).invertX = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
(<AnimatedSprite>this.owner).animation.play("WALK", true);
|
|
||||||
|
|
||||||
this.time = Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
if(this.parent.jumpy && (Date.now() - this.time > 500)){
|
|
||||||
this.finished(EnemyStates.JUMP);
|
|
||||||
this.parent.velocity.y = -300;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.velocity.x = this.parent.direction.x * this.parent.speed;
|
|
||||||
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
(<AnimatedSprite>this.owner).animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
import StateMachineAI from "../../Wolfie2D/AI/StateMachineAI";
|
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import Debug from "../../Wolfie2D/Debug/Debug";
|
|
||||||
import GameNode from "../../Wolfie2D/Nodes/GameNode";
|
|
||||||
import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite";
|
|
||||||
import OrthogonalTilemap from "../../Wolfie2D/Nodes/Tilemaps/OrthogonalTilemap";
|
|
||||||
import Fall from "./PlayerStates/Fall";
|
|
||||||
import Idle from "./PlayerStates/Idle";
|
|
||||||
import InAir from "./PlayerStates/InAir";
|
|
||||||
import Jump from "./PlayerStates/Jump";
|
|
||||||
import Run from "./PlayerStates/Run";
|
|
||||||
import Walk from "./PlayerStates/Walk";
|
|
||||||
|
|
||||||
export enum PlayerType {
|
|
||||||
PLATFORMER = "platformer",
|
|
||||||
TOPDOWN = "topdown"
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum PlayerStates {
|
|
||||||
IDLE = "idle",
|
|
||||||
WALK = "walk",
|
|
||||||
RUN = "run",
|
|
||||||
JUMP = "jump",
|
|
||||||
FALL = "fall",
|
|
||||||
PREVIOUS = "previous"
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class PlayerController extends StateMachineAI {
|
|
||||||
protected owner: GameNode;
|
|
||||||
velocity: Vec2 = Vec2.ZERO;
|
|
||||||
speed: number = 200;
|
|
||||||
MIN_SPEED: number = 200;
|
|
||||||
MAX_SPEED: number = 300;
|
|
||||||
tilemap: OrthogonalTilemap;
|
|
||||||
coin: Sprite;
|
|
||||||
|
|
||||||
initializeAI(owner: GameNode, options: Record<string, any>){
|
|
||||||
this.owner = owner;
|
|
||||||
|
|
||||||
this.initializePlatformer();
|
|
||||||
|
|
||||||
this.tilemap = this.owner.getScene().getTilemap(options.tilemap) as OrthogonalTilemap;
|
|
||||||
this.coin = this.owner.getScene().add.sprite("coin", "coinLayer");
|
|
||||||
this.coin.scale.set(2, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
initializePlatformer(): void {
|
|
||||||
this.speed = 400;
|
|
||||||
|
|
||||||
let idle = new Idle(this, this.owner);
|
|
||||||
this.addState(PlayerStates.IDLE, idle);
|
|
||||||
let walk = new Walk(this, this.owner);
|
|
||||||
this.addState(PlayerStates.WALK, walk);
|
|
||||||
let run = new Run(this, this.owner);
|
|
||||||
this.addState(PlayerStates.RUN, run);
|
|
||||||
let jump = new Jump(this, this.owner);
|
|
||||||
this.addState(PlayerStates.JUMP, jump);
|
|
||||||
let fall = new Fall(this, this.owner);
|
|
||||||
this.addState(PlayerStates.FALL, fall);
|
|
||||||
|
|
||||||
this.initialize(PlayerStates.IDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeState(stateName: string): void {
|
|
||||||
// If we jump or fall, push the state so we can go back to our current state later
|
|
||||||
// unless we're going from jump to fall or something
|
|
||||||
if((stateName === PlayerStates.JUMP || stateName === PlayerStates.FALL) && !(this.stack.peek() instanceof InAir)){
|
|
||||||
this.stack.push(this.stateMap.get(stateName));
|
|
||||||
}
|
|
||||||
|
|
||||||
super.changeState(stateName);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
if(this.currentState instanceof Jump){
|
|
||||||
Debug.log("playerstate", "Player State: Jump");
|
|
||||||
} else if (this.currentState instanceof Walk){
|
|
||||||
Debug.log("playerstate", "Player State: Walk");
|
|
||||||
} else if (this.currentState instanceof Run){
|
|
||||||
Debug.log("playerstate", "Player State: Run");
|
|
||||||
} else if (this.currentState instanceof Idle){
|
|
||||||
Debug.log("playerstate", "Player State: Idle");
|
|
||||||
} else if(this.currentState instanceof Fall){
|
|
||||||
Debug.log("playerstate", "Player State: Fall");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
|
||||||
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import InAir from "./InAir";
|
|
||||||
|
|
||||||
export default class Fall extends InAir {
|
|
||||||
owner: AnimatedSprite;
|
|
||||||
|
|
||||||
onEnter(options: Record<string, any>): void {
|
|
||||||
this.owner.animation.play("FALL", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent): void {}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
this.owner.animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import Input from "../../../Wolfie2D/Input/Input";
|
|
||||||
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { PlayerStates } from "../PlayerController";
|
|
||||||
import OnGround from "./OnGround";
|
|
||||||
|
|
||||||
export default class Idle extends OnGround {
|
|
||||||
owner: AnimatedSprite;
|
|
||||||
|
|
||||||
onEnter(options: Record<string, any>): void {
|
|
||||||
this.parent.speed = this.parent.MIN_SPEED;
|
|
||||||
this.owner.animation.play("IDLE", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
let dir = this.getInputDirection();
|
|
||||||
|
|
||||||
if(!dir.isZero() && dir.y === 0){
|
|
||||||
if(Input.isPressed("run")){
|
|
||||||
this.finished(PlayerStates.RUN);
|
|
||||||
} else {
|
|
||||||
this.finished(PlayerStates.WALK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.velocity.x = 0;
|
|
||||||
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
this.owner.animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
|
||||||
import { PlayerStates } from "../PlayerController";
|
|
||||||
import PlayerState from "./PlayerState";
|
|
||||||
|
|
||||||
export default abstract class InAir extends PlayerState {
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
let dir = this.getInputDirection();
|
|
||||||
|
|
||||||
this.parent.velocity.x += dir.x * this.parent.speed/3.5 - 0.3*this.parent.velocity.x;
|
|
||||||
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
|
|
||||||
if(this.owner.onGround){
|
|
||||||
this.finished(PlayerStates.PREVIOUS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
|
||||||
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { EaseFunctionType } from "../../../Wolfie2D/Utils/EaseFunctions";
|
|
||||||
import { HW4_Events } from "../../hw4_enums";
|
|
||||||
import { PlayerStates } from "../PlayerController";
|
|
||||||
import InAir from "./InAir";
|
|
||||||
|
|
||||||
export default class Jump extends InAir {
|
|
||||||
owner: AnimatedSprite;
|
|
||||||
|
|
||||||
onEnter(options: Record<string, any>): void {
|
|
||||||
this.owner.animation.play("JUMP", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent): void {}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
if(this.owner.onCeiling){
|
|
||||||
this.parent.velocity.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're falling, go to the fall state
|
|
||||||
if(this.parent.velocity.y >= 0){
|
|
||||||
this.finished(PlayerStates.FALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.owner.collidedWithTilemap && this.owner.onCeiling){
|
|
||||||
// We collided with a tilemap above us. First, get the tile right above us
|
|
||||||
this.handleCoinblockCollision();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
this.owner.animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCoinblockCollision(){
|
|
||||||
let pos = this.owner.position.clone();
|
|
||||||
|
|
||||||
// Go up plus some extra
|
|
||||||
pos.y -= (this.owner.collisionShape.halfSize.y + 10);
|
|
||||||
pos.x -= 16;
|
|
||||||
let rowCol = this.parent.tilemap.getColRowAt(pos);
|
|
||||||
let tile1 = this.parent.tilemap.getTileAtRowCol(rowCol);
|
|
||||||
pos.x += 16;
|
|
||||||
rowCol = this.parent.tilemap.getColRowAt(pos);
|
|
||||||
let tile2 = this.parent.tilemap.getTileAtRowCol(rowCol);
|
|
||||||
pos.x += 16;
|
|
||||||
rowCol = this.parent.tilemap.getColRowAt(pos);
|
|
||||||
let tile3 = this.parent.tilemap.getTileAtRowCol(rowCol);
|
|
||||||
|
|
||||||
let t1 = tile1 === 17;
|
|
||||||
let t2 = tile2 === 17;
|
|
||||||
let t3 = tile3 === 17;
|
|
||||||
let air1 = tile1 === 0;
|
|
||||||
let air2 = tile2 === 0;
|
|
||||||
let air3 = tile3 === 0;
|
|
||||||
let majority = (t1 && t2) || (t1 && t3) || (t2 && t3) || (t1 && t2 && t3);
|
|
||||||
let minorityButAir = (t1 && air2 && air3) || (air1 && t2 && air3) || (air1 && air2 && t3);
|
|
||||||
|
|
||||||
// If coin block, change to empty coin block
|
|
||||||
if(majority || minorityButAir){
|
|
||||||
if(minorityButAir){
|
|
||||||
// Get the correct position
|
|
||||||
if(t1){
|
|
||||||
pos.x -= 32;
|
|
||||||
} else if(t2){
|
|
||||||
pos.x -= 16;
|
|
||||||
}
|
|
||||||
rowCol = this.parent.tilemap.getColRowAt(pos);
|
|
||||||
} else {
|
|
||||||
pos.x -= 16;
|
|
||||||
rowCol = this.parent.tilemap.getColRowAt(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.tilemap.setTileAtRowCol(rowCol, 18);
|
|
||||||
this.emitter.fireEvent(HW4_Events.PLAYER_HIT_COIN_BLOCK);
|
|
||||||
|
|
||||||
let tileSize = this.parent.tilemap.getTileSize();
|
|
||||||
this.parent.coin.position.copy(rowCol.scale(tileSize.x, tileSize.y).add(tileSize.scaled(0.5)));
|
|
||||||
|
|
||||||
// Animate collision
|
|
||||||
this.parent.coin.tweens.add("coin", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 300,
|
|
||||||
effects: [{
|
|
||||||
property: "positionY",
|
|
||||||
resetOnComplete: false,
|
|
||||||
start: this.parent.coin.position.y,
|
|
||||||
end: this.parent.coin.position.y - 2*tileSize.y,
|
|
||||||
ease: EaseFunctionType.OUT_SINE
|
|
||||||
},
|
|
||||||
{
|
|
||||||
property: "alpha",
|
|
||||||
resetOnComplete: false,
|
|
||||||
start: 1,
|
|
||||||
end: 0,
|
|
||||||
ease: EaseFunctionType.OUT_SINE
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
this.parent.coin.tweens.play("coin");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
|
||||||
import Input from "../../../Wolfie2D/Input/Input";
|
|
||||||
import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
|
|
||||||
import MathUtils from "../../../Wolfie2D/Utils/MathUtils";
|
|
||||||
import PlayerState from "./PlayerState";
|
|
||||||
|
|
||||||
export default class OnGround extends PlayerState {
|
|
||||||
onEnter(options: Record<string, any>): void {}
|
|
||||||
|
|
||||||
handleInput(event: GameEvent): void {}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
if(this.parent.velocity.y > 0){
|
|
||||||
this.parent.velocity.y = 0;
|
|
||||||
}
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
let direction = this.getInputDirection();
|
|
||||||
|
|
||||||
if(direction.x !== 0){
|
|
||||||
(<Sprite>this.owner).invertX = MathUtils.sign(direction.x) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Input.isJustPressed("jump")){
|
|
||||||
this.finished("jump");
|
|
||||||
this.parent.velocity.y = -500;
|
|
||||||
if(this.parent.velocity.x !== 0){
|
|
||||||
this.owner.tweens.play("flip");
|
|
||||||
}
|
|
||||||
} else if(!this.owner.onGround){
|
|
||||||
this.finished("jump");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
import State from "../../../Wolfie2D/DataTypes/State/State";
|
|
||||||
import StateMachine from "../../../Wolfie2D/DataTypes/State/StateMachine";
|
|
||||||
import Vec2 from "../../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import Input from "../../../Wolfie2D/Input/Input";
|
|
||||||
import GameNode from "../../../Wolfie2D/Nodes/GameNode";
|
|
||||||
import PlayerController from "../PlayerController";
|
|
||||||
|
|
||||||
|
|
||||||
export default abstract class PlayerState extends State {
|
|
||||||
owner: GameNode;
|
|
||||||
gravity: number = 1000;
|
|
||||||
parent: PlayerController;
|
|
||||||
|
|
||||||
constructor(parent: StateMachine, owner: GameNode){
|
|
||||||
super(parent);
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
getInputDirection(): Vec2 {
|
|
||||||
let direction = Vec2.ZERO;
|
|
||||||
direction.x = (Input.isPressed("left") ? -1 : 0) + (Input.isPressed("right") ? 1 : 0);
|
|
||||||
direction.y = (Input.isJustPressed("jump") ? -1 : 0);
|
|
||||||
return direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
// Do gravity
|
|
||||||
this.parent.velocity.y += this.gravity*deltaT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
import Input from "../../../Wolfie2D/Input/Input";
|
|
||||||
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { HW4_Events } from "../../hw4_enums";
|
|
||||||
import { PlayerStates } from "../PlayerController";
|
|
||||||
import OnGround from "./OnGround";
|
|
||||||
|
|
||||||
export default class Run extends OnGround {
|
|
||||||
owner: AnimatedSprite;
|
|
||||||
|
|
||||||
onEnter(options: Record<string, any>): void {
|
|
||||||
this.parent.speed = this.parent.MAX_SPEED;
|
|
||||||
this.owner.animation.play("WALK", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
let dir = this.getInputDirection();
|
|
||||||
|
|
||||||
if(dir.isZero()){
|
|
||||||
this.finished(PlayerStates.IDLE);
|
|
||||||
} else {
|
|
||||||
if(!Input.isPressed("run")){
|
|
||||||
this.finished(PlayerStates.WALK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.velocity.x = dir.x * this.parent.speed
|
|
||||||
|
|
||||||
this.emitter.fireEvent(HW4_Events.PLAYER_MOVE, {position: this.owner.position.clone()});
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
this.owner.animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
import Input from "../../../Wolfie2D/Input/Input";
|
|
||||||
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import { HW4_Events } from "../../hw4_enums";
|
|
||||||
import { PlayerStates } from "../PlayerController";
|
|
||||||
import OnGround from "./OnGround";
|
|
||||||
|
|
||||||
export default class Walk extends OnGround {
|
|
||||||
owner: AnimatedSprite;
|
|
||||||
|
|
||||||
onEnter(options: Record<string, any>): void {
|
|
||||||
this.parent.speed = this.parent.MIN_SPEED;
|
|
||||||
this.owner.animation.play("WALK", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
super.update(deltaT);
|
|
||||||
|
|
||||||
let dir = this.getInputDirection();
|
|
||||||
|
|
||||||
if(dir.isZero()){
|
|
||||||
this.finished(PlayerStates.IDLE);
|
|
||||||
} else {
|
|
||||||
if(Input.isPressed("run")){
|
|
||||||
this.finished(PlayerStates.RUN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent.velocity.x = dir.x * this.parent.speed
|
|
||||||
|
|
||||||
this.emitter.fireEvent(HW4_Events.PLAYER_MOVE, {position: this.owner.position.clone()});
|
|
||||||
this.owner.move(this.parent.velocity.scaled(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
onExit(): Record<string, any> {
|
|
||||||
this.owner.animation.stop();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,362 +0,0 @@
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import Input from "../../Wolfie2D/Input/Input";
|
|
||||||
import { TweenableProperties } from "../../Wolfie2D/Nodes/GameNode";
|
|
||||||
import { GraphicType } from "../../Wolfie2D/Nodes/Graphics/GraphicTypes";
|
|
||||||
import Rect from "../../Wolfie2D/Nodes/Graphics/Rect";
|
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import Label from "../../Wolfie2D/Nodes/UIElements/Label";
|
|
||||||
import { UIElementType } from "../../Wolfie2D/Nodes/UIElements/UIElementTypes";
|
|
||||||
import Scene from "../../Wolfie2D/Scene/Scene";
|
|
||||||
import Timer from "../../Wolfie2D/Timing/Timer";
|
|
||||||
import Color from "../../Wolfie2D/Utils/Color";
|
|
||||||
import { EaseFunctionType } from "../../Wolfie2D/Utils/EaseFunctions";
|
|
||||||
import EnemyController from "../Enemies/EnemyController";
|
|
||||||
import { HW4_Events } from "../hw4_enums";
|
|
||||||
import PlayerController from "../Player/PlayerController";
|
|
||||||
|
|
||||||
export default class GameLevel extends Scene {
|
|
||||||
// Every level will have a player, which will be an animated sprite
|
|
||||||
protected playerSpawn: Vec2;
|
|
||||||
protected player: AnimatedSprite;
|
|
||||||
|
|
||||||
// Labels for the UI
|
|
||||||
protected static coinCount: number = 0;
|
|
||||||
protected coinCountLabel: Label;
|
|
||||||
protected static livesCount: number = 3;
|
|
||||||
protected livesCountLabel: Label;
|
|
||||||
|
|
||||||
// Stuff to end the level and go to the next level
|
|
||||||
protected levelEndArea: Rect;
|
|
||||||
protected nextLevel: new (...args: any) => GameLevel;
|
|
||||||
protected levelEndTimer: Timer;
|
|
||||||
protected levelEndLabel: Label;
|
|
||||||
|
|
||||||
// Screen fade in/out for level start and end
|
|
||||||
protected levelTransitionTimer: Timer;
|
|
||||||
protected levelTransitionScreen: Rect;
|
|
||||||
|
|
||||||
startScene(): void {
|
|
||||||
// Do the game level standard initializations
|
|
||||||
this.initLayers();
|
|
||||||
this.initViewport();
|
|
||||||
this.initPlayer();
|
|
||||||
this.subscribeToEvents();
|
|
||||||
this.addUI();
|
|
||||||
|
|
||||||
// Initialize the timers
|
|
||||||
this.levelTransitionTimer = new Timer(500);
|
|
||||||
this.levelEndTimer = new Timer(3000, () => {
|
|
||||||
// After the level end timer ends, fade to black and then go to the next scene
|
|
||||||
this.levelTransitionScreen.tweens.play("fadeIn");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Start the black screen fade out
|
|
||||||
this.levelTransitionScreen.tweens.play("fadeOut");
|
|
||||||
|
|
||||||
// Initially disable player movement
|
|
||||||
Input.disableInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScene(deltaT: number){
|
|
||||||
// Handle events and update the UI if needed
|
|
||||||
while(this.receiver.hasNextEvent()){
|
|
||||||
let event = this.receiver.getNextEvent();
|
|
||||||
|
|
||||||
switch(event.type){
|
|
||||||
case HW4_Events.PLAYER_HIT_COIN:
|
|
||||||
{
|
|
||||||
// Hit a coin
|
|
||||||
let coin;
|
|
||||||
if(event.data.get("node") === this.player.id){
|
|
||||||
// Other is coin, disable
|
|
||||||
coin = this.sceneGraph.getNode(event.data.get("other"));
|
|
||||||
} else {
|
|
||||||
// Node is coin, disable
|
|
||||||
coin = this.sceneGraph.getNode(event.data.get("node"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove from physics and scene
|
|
||||||
coin.active = false;
|
|
||||||
coin.visible = false;
|
|
||||||
|
|
||||||
// Increment our number of coins
|
|
||||||
this.incPlayerCoins(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.PLAYER_HIT_COIN_BLOCK:
|
|
||||||
{
|
|
||||||
// Hit a coin block, so increment our number of coins
|
|
||||||
this.incPlayerCoins(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.PLAYER_HIT_ENEMY:
|
|
||||||
{
|
|
||||||
let node = this.sceneGraph.getNode(event.data.get("node"));
|
|
||||||
let other = this.sceneGraph.getNode(event.data.get("other"));
|
|
||||||
|
|
||||||
if(node === this.player){
|
|
||||||
// Node is player, other is enemy
|
|
||||||
this.handlePlayerEnemyCollision(<AnimatedSprite>node, <AnimatedSprite>other);
|
|
||||||
} else {
|
|
||||||
// Other is player, node is enemy
|
|
||||||
this.handlePlayerEnemyCollision(<AnimatedSprite>other,<AnimatedSprite>node);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.ENEMY_DIED:
|
|
||||||
{
|
|
||||||
// An enemy finished its dying animation, hide it
|
|
||||||
let node = this.sceneGraph.getNode(event.data.get("owner"));
|
|
||||||
node.visible = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.PLAYER_ENTERED_LEVEL_END:
|
|
||||||
{
|
|
||||||
if(!this.levelEndTimer.hasRun() && this.levelEndTimer.isStopped()){
|
|
||||||
// The player has reached the end of the level
|
|
||||||
this.levelEndTimer.start();
|
|
||||||
this.levelEndLabel.tweens.play("slideIn");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.LEVEL_START:
|
|
||||||
{
|
|
||||||
// Re-enable controls
|
|
||||||
console.log("Enabling input");
|
|
||||||
Input.enableInput();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HW4_Events.LEVEL_END:
|
|
||||||
{
|
|
||||||
// Go to the next level
|
|
||||||
if(this.nextLevel){
|
|
||||||
console.log("Going to next level!");
|
|
||||||
let sceneOptions = {
|
|
||||||
physics: {
|
|
||||||
groupNames: ["ground", "player", "enemy", "coin"],
|
|
||||||
collisions:
|
|
||||||
[
|
|
||||||
[0, 1, 1, 0],
|
|
||||||
[1, 0, 0, 1],
|
|
||||||
[1, 0, 0, 0],
|
|
||||||
[0, 1, 0, 0]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.sceneManager.changeToScene(this.nextLevel, {}, sceneOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If player falls into a pit, kill them off and reset their position
|
|
||||||
if(this.player.position.y > 100*64){
|
|
||||||
this.incPlayerLife(-1);
|
|
||||||
this.respawnPlayer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected initLayers(): void {
|
|
||||||
// Add a layer behind the tilemap for coinblock animation
|
|
||||||
this.addLayer("coinLayer", -50);
|
|
||||||
|
|
||||||
// Add a layer for UI
|
|
||||||
this.addUILayer("UI");
|
|
||||||
|
|
||||||
// Add a layer for players and enemies
|
|
||||||
this.addLayer("primary", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected initViewport(): void {
|
|
||||||
this.viewport.enableZoom();
|
|
||||||
this.viewport.setZoomLevel(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected subscribeToEvents(){
|
|
||||||
this.receiver.subscribe([
|
|
||||||
HW4_Events.PLAYER_HIT_COIN,
|
|
||||||
HW4_Events.PLAYER_HIT_COIN_BLOCK,
|
|
||||||
HW4_Events.PLAYER_HIT_ENEMY,
|
|
||||||
HW4_Events.ENEMY_DIED,
|
|
||||||
HW4_Events.PLAYER_ENTERED_LEVEL_END,
|
|
||||||
HW4_Events.LEVEL_START,
|
|
||||||
HW4_Events.LEVEL_END
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected addUI(){
|
|
||||||
// In-game labels
|
|
||||||
this.coinCountLabel = <Label>this.add.uiElement(UIElementType.LABEL, "UI", {position: new Vec2(80, 30), text: "Coins: " + GameLevel.coinCount});
|
|
||||||
this.coinCountLabel.textColor = Color.WHITE
|
|
||||||
this.coinCountLabel.font = "NoPixel";
|
|
||||||
this.livesCountLabel = <Label>this.add.uiElement(UIElementType.LABEL, "UI", {position: new Vec2(500, 30), text: "Lives: " + GameLevel.livesCount});
|
|
||||||
this.livesCountLabel.textColor = Color.WHITE
|
|
||||||
this.livesCountLabel.font = "NoPixel";
|
|
||||||
|
|
||||||
// End of level label (start off screen)
|
|
||||||
this.levelEndLabel = <Label>this.add.uiElement(UIElementType.LABEL, "UI", {position: new Vec2(-300, 200), text: "Level Complete"});
|
|
||||||
this.levelEndLabel.size.set(1200, 60);
|
|
||||||
this.levelEndLabel.borderRadius = 0;
|
|
||||||
this.levelEndLabel.backgroundColor = new Color(34, 32, 52);
|
|
||||||
this.levelEndLabel.textColor = Color.WHITE;
|
|
||||||
this.levelEndLabel.fontSize = 48;
|
|
||||||
this.levelEndLabel.font = "NoPixel";
|
|
||||||
|
|
||||||
// Add a tween to move the label on screen
|
|
||||||
this.levelEndLabel.tweens.add("slideIn", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 1000,
|
|
||||||
effects: [
|
|
||||||
{
|
|
||||||
property: TweenableProperties.posX,
|
|
||||||
start: -300,
|
|
||||||
end: 300,
|
|
||||||
ease: EaseFunctionType.OUT_SINE
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this.levelTransitionScreen = <Rect>this.add.graphic(GraphicType.RECT, "UI", {position: new Vec2(300, 200), size: new Vec2(600, 400)});
|
|
||||||
this.levelTransitionScreen.color = new Color(34, 32, 52);
|
|
||||||
this.levelTransitionScreen.alpha = 1;
|
|
||||||
|
|
||||||
this.levelTransitionScreen.tweens.add("fadeIn", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 1000,
|
|
||||||
effects: [
|
|
||||||
{
|
|
||||||
property: TweenableProperties.alpha,
|
|
||||||
start: 0,
|
|
||||||
end: 1,
|
|
||||||
ease: EaseFunctionType.IN_OUT_QUAD
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onEnd: HW4_Events.LEVEL_END
|
|
||||||
});
|
|
||||||
|
|
||||||
this.levelTransitionScreen.tweens.add("fadeOut", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 1000,
|
|
||||||
effects: [
|
|
||||||
{
|
|
||||||
property: TweenableProperties.alpha,
|
|
||||||
start: 1,
|
|
||||||
end: 0,
|
|
||||||
ease: EaseFunctionType.IN_OUT_QUAD
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onEnd: HW4_Events.LEVEL_START
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected initPlayer(): void {
|
|
||||||
// Add the player
|
|
||||||
this.player = this.add.animatedSprite("player", "primary");
|
|
||||||
this.player.scale.set(2, 2);
|
|
||||||
if(!this.playerSpawn){
|
|
||||||
console.warn("Player spawn was never set - setting spawn to (0, 0)");
|
|
||||||
this.playerSpawn = Vec2.ZERO;
|
|
||||||
}
|
|
||||||
this.player.position.copy(this.playerSpawn);
|
|
||||||
this.player.addPhysics();
|
|
||||||
this.player.addAI(PlayerController, {playerType: "platformer", tilemap: "Main"});
|
|
||||||
|
|
||||||
// Add triggers on colliding with coins or coinBlocks
|
|
||||||
this.player.setGroup("player");
|
|
||||||
|
|
||||||
// Add a tween animation for the player jump
|
|
||||||
this.player.tweens.add("flip", {
|
|
||||||
startDelay: 0,
|
|
||||||
duration: 500,
|
|
||||||
effects: [
|
|
||||||
{
|
|
||||||
property: "rotation",
|
|
||||||
start: 0,
|
|
||||||
end: 2*Math.PI,
|
|
||||||
ease: EaseFunctionType.IN_OUT_QUAD
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this.viewport.follow(this.player);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected addLevelEnd(startingTile: Vec2, size: Vec2): void {
|
|
||||||
this.levelEndArea = <Rect>this.add.graphic(GraphicType.RECT, "primary", {position: startingTile.add(size.scaled(0.5)).scale(32), size: size.scale(32)});
|
|
||||||
this.levelEndArea.addPhysics(undefined, undefined, false, true);
|
|
||||||
this.levelEndArea.setTrigger("player", HW4_Events.PLAYER_ENTERED_LEVEL_END, null);
|
|
||||||
this.levelEndArea.color = new Color(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected addEnemy(spriteKey: string, tilePos: Vec2, aiOptions: Record<string, any>): void {
|
|
||||||
let enemy = this.add.animatedSprite(spriteKey, "primary");
|
|
||||||
enemy.position.set(tilePos.x*32, tilePos.y*32);
|
|
||||||
enemy.scale.set(2, 2);
|
|
||||||
enemy.addPhysics();
|
|
||||||
enemy.addAI(EnemyController, aiOptions);
|
|
||||||
enemy.setGroup("enemy");
|
|
||||||
enemy.setTrigger("player", HW4_Events.PLAYER_HIT_ENEMY, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected handlePlayerEnemyCollision(player: AnimatedSprite, enemy: AnimatedSprite) {
|
|
||||||
// Get the vector of the direction from the player to the enemy
|
|
||||||
let dir = player.position.dirTo(enemy.position);
|
|
||||||
|
|
||||||
if((<EnemyController>enemy.ai).jumpy){
|
|
||||||
// If it's a jumpy enemy, we want to hit it from the bottom
|
|
||||||
if(dir.dot(Vec2.UP) > 0.5){
|
|
||||||
enemy.disablePhysics();
|
|
||||||
enemy.tweens.stopAll();
|
|
||||||
enemy.animation.play("DYING", false, HW4_Events.ENEMY_DIED);
|
|
||||||
|
|
||||||
// Stop the player's jump for some feedback
|
|
||||||
(<PlayerController>player.ai).velocity.y = 0;
|
|
||||||
} else {
|
|
||||||
this.incPlayerLife(-1);
|
|
||||||
this.respawnPlayer();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If not, we want to hit it from the top
|
|
||||||
if(dir.dot(Vec2.DOWN) > 0.5){
|
|
||||||
enemy.disablePhysics();
|
|
||||||
enemy.animation.play("DYING", false, HW4_Events.ENEMY_DIED);
|
|
||||||
|
|
||||||
// Give the player a slight jump boost
|
|
||||||
let playerVel = (<PlayerController>player.ai).velocity;
|
|
||||||
if(playerVel.y < 0){
|
|
||||||
// We're going up - unlikely, but still check
|
|
||||||
playerVel.y += 0.2*(<PlayerController>player.ai).velocity.y;
|
|
||||||
} else {
|
|
||||||
// We're going down, invert our bounce, but dampen it
|
|
||||||
playerVel.y = -0.5 * (<PlayerController>player.ai).velocity.y;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.incPlayerLife(-1);
|
|
||||||
this.respawnPlayer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected incPlayerLife(amt: number): void {
|
|
||||||
GameLevel.livesCount += amt;
|
|
||||||
this.livesCountLabel.text = "Lives: " + GameLevel.livesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected incPlayerCoins(amt: number): void {
|
|
||||||
GameLevel.coinCount += amt;
|
|
||||||
this.coinCountLabel.text = "Coins: " + GameLevel.coinCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected respawnPlayer(): void {
|
|
||||||
this.player.position.copy(this.playerSpawn);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import Debug from "../../Wolfie2D/Debug/Debug";
|
|
||||||
import GameLevel from "./GameLevel";
|
|
||||||
import Level2 from "./Level2";
|
|
||||||
|
|
||||||
export default class Level1 extends GameLevel {
|
|
||||||
loadScene(): void {
|
|
||||||
this.load.image("background", "hw4_assets/sprites/2bitbackground.png");
|
|
||||||
this.load.image("coin", "hw4_assets/sprites/coin.png");
|
|
||||||
this.load.tilemap("level1", "hw4_assets/tilemaps/level1.json");
|
|
||||||
this.load.spritesheet("player", "hw4_assets/spritesheets/platformPlayer.json");
|
|
||||||
this.load.spritesheet("hopper", "hw4_assets/spritesheets/hopper.json");
|
|
||||||
this.load.spritesheet("bunny", "hw4_assets/spritesheets/ghostBunny.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
startScene(): void {
|
|
||||||
// Add a background layer and set the background image on it
|
|
||||||
this.addParallaxLayer("bg", new Vec2(0.25, 0), -100);
|
|
||||||
let bg = this.add.sprite("background", "bg");
|
|
||||||
bg.scale.set(2, 2);
|
|
||||||
bg.position.set(bg.boundary.halfSize.x, 76);
|
|
||||||
|
|
||||||
// Add the level 1 tilemap
|
|
||||||
this.add.tilemap("level1", new Vec2(2, 2));
|
|
||||||
this.viewport.setBounds(0, 0, 64*32, 20*32);
|
|
||||||
|
|
||||||
this.playerSpawn = new Vec2(5*32, 18*32);
|
|
||||||
|
|
||||||
// Do generic setup for a GameLevel
|
|
||||||
super.startScene();
|
|
||||||
|
|
||||||
this.addLevelEnd(new Vec2(58, 17), new Vec2(2, 2));
|
|
||||||
|
|
||||||
this.nextLevel = Level2;
|
|
||||||
|
|
||||||
// Add enemies of various types
|
|
||||||
for(let pos of [new Vec2(24, 18)]){
|
|
||||||
this.addEnemy("bunny", pos, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let pos of [new Vec2(51, 17)]){
|
|
||||||
this.addEnemy("hopper", pos, {jumpy: true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScene(deltaT: number): void {
|
|
||||||
super.updateScene(deltaT);
|
|
||||||
|
|
||||||
Debug.log("playerpos", this.player.position.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import Debug from "../../Wolfie2D/Debug/Debug";
|
|
||||||
import GameLevel from "./GameLevel";
|
|
||||||
|
|
||||||
export default class Level2 extends GameLevel {
|
|
||||||
loadScene(): void {
|
|
||||||
this.load.image("background", "hw4_assets/sprites/2bitbackground.png");
|
|
||||||
this.load.image("coin", "hw4_assets/sprites/coin.png");
|
|
||||||
this.load.tilemap("level2", "hw4_assets/tilemaps/level2.json");
|
|
||||||
this.load.spritesheet("player", "hw4_assets/spritesheets/platformPlayer.json");
|
|
||||||
this.load.spritesheet("hopper", "hw4_assets/spritesheets/hopper.json");
|
|
||||||
this.load.spritesheet("bunny", "hw4_assets/spritesheets/ghostBunny.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
startScene(): void {
|
|
||||||
console.log("Starting level2");
|
|
||||||
// Add a background layer and set the background image on it
|
|
||||||
this.addParallaxLayer("bg", new Vec2(0.25, 0), -100);
|
|
||||||
let bg = this.add.sprite("background", "bg");
|
|
||||||
bg.scale.set(2, 2);
|
|
||||||
bg.position.set(bg.boundary.halfSize.x, 96);
|
|
||||||
|
|
||||||
// Add the level 1 tilemap
|
|
||||||
this.add.tilemap("level2", new Vec2(2, 2));
|
|
||||||
this.viewport.setBounds(0, 0, 64*32, 20*32);
|
|
||||||
|
|
||||||
this.playerSpawn = new Vec2(5*32, 18*32);
|
|
||||||
|
|
||||||
// Do generic setup for a GameLevel
|
|
||||||
super.startScene();
|
|
||||||
|
|
||||||
this.addLevelEnd(new Vec2(58, 17), new Vec2(2, 2));
|
|
||||||
|
|
||||||
// Add enemies of various types
|
|
||||||
for(let pos of [new Vec2(24, 18)]){
|
|
||||||
this.addEnemy("bunny", pos, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let pos of [new Vec2(51, 17)]){
|
|
||||||
this.addEnemy("hopper", pos, {jumpy: true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScene(deltaT: number): void {
|
|
||||||
super.updateScene(deltaT);
|
|
||||||
|
|
||||||
Debug.log("playerpos", this.player.position.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
|
||||||
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|
||||||
import Button from "../../Wolfie2D/Nodes/UIElements/Button";
|
|
||||||
import { UIElementType } from "../../Wolfie2D/Nodes/UIElements/UIElementTypes";
|
|
||||||
import Scene from "../../Wolfie2D/Scene/Scene";
|
|
||||||
import Color from "../../Wolfie2D/Utils/Color";
|
|
||||||
import Level1 from "./Level1";
|
|
||||||
|
|
||||||
export default class MainMenu extends Scene {
|
|
||||||
|
|
||||||
animatedSprite: AnimatedSprite;
|
|
||||||
|
|
||||||
loadScene(): void {}
|
|
||||||
|
|
||||||
startScene(): void {
|
|
||||||
this.addUILayer("Main");
|
|
||||||
|
|
||||||
let size = this.viewport.getHalfSize();
|
|
||||||
this.viewport.setFocus(size);
|
|
||||||
|
|
||||||
let playBtn = <Button>this.add.uiElement(UIElementType.BUTTON, "Main", {position: new Vec2(size.x, size.y), text: "Play Game"});
|
|
||||||
playBtn.setBackgroundColor(Color.GREEN);
|
|
||||||
playBtn.setPadding(new Vec2(50, 10));
|
|
||||||
playBtn.font = "NoPixel";
|
|
||||||
|
|
||||||
// When the play button is clicked, go to the next scene
|
|
||||||
playBtn.onClick = () => {
|
|
||||||
/*
|
|
||||||
Init the next scene with physics collisions:
|
|
||||||
|
|
||||||
ground player enemy coin
|
|
||||||
ground No -- -- --
|
|
||||||
player Yes No -- --
|
|
||||||
enemy Yes No No --
|
|
||||||
coin No Yes No No
|
|
||||||
|
|
||||||
Each layer becomes a number. In this case, 4 bits matter for each
|
|
||||||
|
|
||||||
ground: self - 0001, collisions - 0110
|
|
||||||
player: self - 0010, collisions - 1001
|
|
||||||
enemy: self - 0100, collisions - 0001
|
|
||||||
coin: self - 1000, collisions - 0010
|
|
||||||
*/
|
|
||||||
|
|
||||||
let sceneOptions = {
|
|
||||||
physics: {
|
|
||||||
groupNames: ["ground", "player", "enemy", "coin"],
|
|
||||||
collisions:
|
|
||||||
[
|
|
||||||
[0, 1, 1, 0],
|
|
||||||
[1, 0, 0, 1],
|
|
||||||
[1, 0, 0, 0],
|
|
||||||
[0, 1, 0, 0]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.sceneManager.changeToScene(Level1, {}, sceneOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScene(): void {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
export enum HW4_Events {
|
|
||||||
PLAYER_MOVE = "PlayerMove",
|
|
||||||
PLAYER_JUMP = "PlayerJump",
|
|
||||||
PLAYER_HIT_COIN = "PlayerHitCoin",
|
|
||||||
PLAYER_HIT_COIN_BLOCK = "PlayerHitCoinBlock",
|
|
||||||
PLAYER_HIT_ENEMY = "PlayerHitEnemy",
|
|
||||||
ENEMY_DIED = "EnemyDied",
|
|
||||||
PLAYER_ENTERED_LEVEL_END = "PlayerEnteredLevelEnd",
|
|
||||||
LEVEL_START = "LevelStart",
|
|
||||||
LEVEL_END = "LevelEnd",
|
|
||||||
}
|
|
|
@ -64,6 +64,26 @@ export enum GameEventType {
|
||||||
*/
|
*/
|
||||||
STOP_SOUND = "stop_sound",
|
STOP_SOUND = "stop_sound",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Play Sound event. Has data: {key: string, loop: boolean, holdReference: boolean, channel: AudioChannelType }
|
||||||
|
*/
|
||||||
|
PLAY_SFX = "play_sfx",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Play Sound event. Has data: {key: string, loop: boolean, holdReference: boolean }
|
||||||
|
*/
|
||||||
|
PLAY_MUSIC = "play_music",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute audio channel event. Has data: {channel: AudioChannelType}
|
||||||
|
*/
|
||||||
|
MUTE_CHANNEL = "mute_channel",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmute audio channel event. Has data: {channel: AudioChannelType}
|
||||||
|
*/
|
||||||
|
UNMUTE_CHANNEL = "unmute_channel",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encompasses all event types. Used for receivers only.
|
* Encompasses all event types. Used for receivers only.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,8 @@ export default class Slider extends UIElement {
|
||||||
protected value: number;
|
protected value: number;
|
||||||
/** The color of the slider nib */
|
/** The color of the slider nib */
|
||||||
public nibColor: Color;
|
public nibColor: Color;
|
||||||
|
/** The size of the nib */
|
||||||
|
public nibSize: Vec2;
|
||||||
/** The color of the slider track */
|
/** The color of the slider track */
|
||||||
public sliderColor: Color;
|
public sliderColor: Color;
|
||||||
/** The reaction of this UIElement to a value change */
|
/** The reaction of this UIElement to a value change */
|
||||||
|
@ -17,14 +19,15 @@ export default class Slider extends UIElement {
|
||||||
/** The event propagated by this UIElement when value changes */
|
/** The event propagated by this UIElement when value changes */
|
||||||
public onValueChangeEventId: string;
|
public onValueChangeEventId: string;
|
||||||
|
|
||||||
constructor(position: Vec2){
|
constructor(position: Vec2, initValue: number){
|
||||||
super(position);
|
super(position);
|
||||||
|
|
||||||
this.value = 0;
|
this.value = initValue;
|
||||||
this.nibColor = Color.RED;
|
this.nibColor = Color.RED;
|
||||||
this.sliderColor = Color.BLACK;
|
this.sliderColor = Color.BLACK;
|
||||||
this.backgroundColor = Color.TRANSPARENT;
|
this.backgroundColor = Color.TRANSPARENT;
|
||||||
this.borderColor = Color.TRANSPARENT;
|
this.borderColor = Color.TRANSPARENT;
|
||||||
|
this.nibSize = new Vec2(10, 20);
|
||||||
|
|
||||||
// Set a default size
|
// Set a default size
|
||||||
this.size.set(200, 20);
|
this.size.set(200, 20);
|
||||||
|
|
|
@ -88,14 +88,12 @@ export default class UIElementRenderer {
|
||||||
sliderSize.x, sliderSize.y, slider.borderRadius);
|
sliderSize.x, sliderSize.y, slider.borderRadius);
|
||||||
|
|
||||||
// Calculate the nib size and position
|
// Calculate the nib size and position
|
||||||
let nibSize = new Vec2(10, slider.size.y);
|
let x = MathUtils.lerp(-slider.size.x/2, slider.size.x/2, slider.getValue());
|
||||||
let x = MathUtils.lerp(slider.position.x - slider.size.x/2, slider.position.x + slider.size.x/2, slider.getValue());
|
|
||||||
let nibPosition = new Vec2(x, slider.position.y);
|
|
||||||
|
|
||||||
// Draw the nib
|
// Draw the nib
|
||||||
this.ctx.fillStyle = slider.nibColor.toString();
|
this.ctx.fillStyle = slider.nibColor.toString();
|
||||||
this.ctx.fillRoundedRect(-nibSize.x/2, -nibSize.y/2,
|
this.ctx.fillRoundedRect(x-slider.nibSize.x/2, -slider.nibSize.y/2,
|
||||||
nibSize.x, nibSize.y, slider.borderRadius);
|
slider.nibSize.x, slider.nibSize.y, slider.borderRadius);
|
||||||
|
|
||||||
// Reset the alpha
|
// Reset the alpha
|
||||||
this.ctx.globalAlpha = previousAlpha;
|
this.ctx.globalAlpha = previousAlpha;
|
||||||
|
|
|
@ -180,7 +180,12 @@ export default class CanvasNodeFactory {
|
||||||
buildSlider(options: Record<string, any>): Slider {
|
buildSlider(options: Record<string, any>): Slider {
|
||||||
this.checkIfPropExists("Slider", options, "position", Vec2, "Vec2");
|
this.checkIfPropExists("Slider", options, "position", Vec2, "Vec2");
|
||||||
|
|
||||||
return new Slider(options.position);
|
let initValue = 0;
|
||||||
|
if(options.value !== undefined){
|
||||||
|
initValue = options.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Slider(options.position, initValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTextInput(options: Record<string, any>): TextInput {
|
buildTextInput(options: Record<string, any>): TextInput {
|
||||||
|
|
|
@ -19,11 +19,23 @@ export default class AudioManager {
|
||||||
|
|
||||||
private audioCtx: AudioContext;
|
private audioCtx: AudioContext;
|
||||||
|
|
||||||
|
private gainNodes: Array<GainNode>;
|
||||||
|
|
||||||
private constructor(){
|
private constructor(){
|
||||||
this.initAudio();
|
this.initAudio();
|
||||||
this.receiver = new Receiver();
|
this.receiver = new Receiver();
|
||||||
this.receiver.subscribe([GameEventType.PLAY_SOUND, GameEventType.STOP_SOUND]);
|
this.receiver.subscribe([
|
||||||
|
GameEventType.PLAY_SOUND,
|
||||||
|
GameEventType.STOP_SOUND,
|
||||||
|
GameEventType.PLAY_MUSIC,
|
||||||
|
GameEventType.PLAY_SFX,
|
||||||
|
GameEventType.MUTE_CHANNEL,
|
||||||
|
GameEventType.UNMUTE_CHANNEL
|
||||||
|
]);
|
||||||
this.currentSounds = new Map();
|
this.currentSounds = new Map();
|
||||||
|
|
||||||
|
this.gainNodes = new Array<GainNode>(MAX_AUDIO_CHANNELS);
|
||||||
|
this.initGainNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +62,12 @@ export default class AudioManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initGainNodes(): void {
|
||||||
|
for(let i = 0; i < MAX_AUDIO_CHANNELS; i++){
|
||||||
|
this.gainNodes[i] = this.audioCtx.createGain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current audio context
|
* Returns the current audio context
|
||||||
* @returns The AudioContext
|
* @returns The AudioContext
|
||||||
|
@ -73,7 +91,7 @@ export default class AudioManager {
|
||||||
* @param key The key of the loaded audio file to create a new sound for
|
* @param key The key of the loaded audio file to create a new sound for
|
||||||
* @returns The newly created AudioBuffer
|
* @returns The newly created AudioBuffer
|
||||||
*/
|
*/
|
||||||
protected createSound(key: string): AudioBufferSourceNode {
|
protected createSound(key: string, holdReference: boolean, channel: AudioChannelType, options: Map<any>): AudioBufferSourceNode {
|
||||||
// Get audio buffer
|
// Get audio buffer
|
||||||
let buffer = ResourceManager.getInstance().getAudio(key);
|
let buffer = ResourceManager.getInstance().getAudio(key);
|
||||||
|
|
||||||
|
@ -83,8 +101,22 @@ export default class AudioManager {
|
||||||
// Tell the source which sound to play
|
// Tell the source which sound to play
|
||||||
source.buffer = buffer;
|
source.buffer = buffer;
|
||||||
|
|
||||||
|
// Add any additional nodes
|
||||||
|
const nodes: Array<AudioNode> = [source];
|
||||||
|
|
||||||
|
// Do any additional nodes here?
|
||||||
|
// Of course, there aren't any supported yet...
|
||||||
|
|
||||||
|
// Add the gain node for this channel
|
||||||
|
nodes.push(this.gainNodes[channel]);
|
||||||
|
|
||||||
|
// Connect any nodes along the path
|
||||||
|
for(let i = 1; i < nodes.length; i++){
|
||||||
|
nodes[i-1].connect(nodes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Connect the source to the context's destination
|
// Connect the source to the context's destination
|
||||||
source.connect(this.audioCtx.destination);
|
nodes[nodes.length - 1].connect(this.audioCtx.destination);
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
@ -95,8 +127,8 @@ export default class AudioManager {
|
||||||
* @param loop A boolean for whether or not to loop the sound
|
* @param loop A boolean for whether or not to loop the sound
|
||||||
* @param holdReference A boolean for whether or not we want to hold on to a reference of the audio node. This is good for playing music on a loop that will eventually need to be stopped.
|
* @param holdReference A boolean for whether or not we want to hold on to a reference of the audio node. This is good for playing music on a loop that will eventually need to be stopped.
|
||||||
*/
|
*/
|
||||||
protected playSound(key: string, loop: boolean, holdReference: boolean): void {
|
protected playSound(key: string, loop: boolean, holdReference: boolean, channel: AudioChannelType, options: Map<any>): void {
|
||||||
let sound = this.createSound(key);
|
let sound = this.createSound(key, holdReference, channel, options);
|
||||||
|
|
||||||
if(loop){
|
if(loop){
|
||||||
sound.loop = true;
|
sound.loop = true;
|
||||||
|
@ -120,23 +152,93 @@ export default class AudioManager {
|
||||||
this.currentSounds.delete(key);
|
this.currentSounds.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected muteChannel(channel: AudioChannelType){
|
||||||
|
this.gainNodes[channel].gain.setValueAtTime(0, this.audioCtx.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected unmuteChannel(channel: AudioChannelType){
|
||||||
|
this.gainNodes[channel].gain.setValueAtTime(1, this.audioCtx.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the volume of a channel using the GainNode for that channel. For more
|
||||||
|
* information on GainNodes, see https://developer.mozilla.org/en-US/docs/Web/API/GainNode
|
||||||
|
* @param channel The audio channel to set the volume for
|
||||||
|
* @param volume The volume of the channel. 0 is muted. Values below zero will be set to zero.
|
||||||
|
*/
|
||||||
|
static setVolume(channel: AudioChannelType, volume: number){
|
||||||
|
if(volume < 0){
|
||||||
|
volume = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const am = AudioManager.getInstance();
|
||||||
|
am.gainNodes[channel].gain.setValueAtTime(volume, am.audioCtx.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GainNode for this channel.
|
||||||
|
* Learn more about GainNodes here https://developer.mozilla.org/en-US/docs/Web/API/GainNode
|
||||||
|
* DON'T USE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
|
||||||
|
* @param channel The channel
|
||||||
|
* @returns The GainNode for the specified channel
|
||||||
|
*/
|
||||||
|
getChannelGainNode(channel: AudioChannelType){
|
||||||
|
return this.gainNodes[channel];
|
||||||
|
}
|
||||||
|
|
||||||
update(deltaT: number): void {
|
update(deltaT: number): void {
|
||||||
// Play each audio clip requested
|
// Play each audio clip requested
|
||||||
// TODO - Add logic to merge sounds if there are multiple of the same key
|
// TODO - Add logic to merge sounds if there are multiple of the same key
|
||||||
while(this.receiver.hasNextEvent()){
|
while(this.receiver.hasNextEvent()){
|
||||||
let event = this.receiver.getNextEvent();
|
let event = this.receiver.getNextEvent();
|
||||||
if(event.type === GameEventType.PLAY_SOUND){
|
if(event.type === GameEventType.PLAY_SOUND || event.type === GameEventType.PLAY_MUSIC || event.type === GameEventType.PLAY_SFX){
|
||||||
let soundKey = event.data.get("key");
|
let soundKey = event.data.get("key");
|
||||||
let loop = event.data.get("loop");
|
let loop = event.data.get("loop");
|
||||||
let holdReference = event.data.get("holdReference");
|
let holdReference = event.data.get("holdReference");
|
||||||
this.playSound(soundKey, loop, holdReference);
|
|
||||||
|
let channel = AudioChannelType.DEFAULT;
|
||||||
|
|
||||||
|
if(event.type === GameEventType.PLAY_MUSIC){
|
||||||
|
channel = AudioChannelType.MUSIC;
|
||||||
|
} else if(GameEventType.PLAY_SFX){
|
||||||
|
channel = AudioChannelType.SFX;
|
||||||
|
} else if(event.data.has("channel")){
|
||||||
|
channel = event.data.get("channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.playSound(soundKey, loop, holdReference, channel, event.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event.type === GameEventType.STOP_SOUND){
|
if(event.type === GameEventType.STOP_SOUND){
|
||||||
let soundKey = event.data.get("key");
|
let soundKey = event.data.get("key");
|
||||||
this.stopSound(soundKey);
|
this.stopSound(soundKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(event.type === GameEventType.MUTE_CHANNEL){
|
||||||
|
this.muteChannel(event.data.get("channel"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.type === GameEventType.UNMUTE_CHANNEL){
|
||||||
|
this.unmuteChannel(event.data.get("channel"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum AudioChannelType {
|
||||||
|
DEFAULT = 0,
|
||||||
|
SFX = 1,
|
||||||
|
MUSIC = 2,
|
||||||
|
CUSTOM_1 = 3,
|
||||||
|
CUSTOM_2 = 4,
|
||||||
|
CUSTOM_3 = 5,
|
||||||
|
CUSTOM_4 = 6,
|
||||||
|
CUSTOM_5 = 7,
|
||||||
|
CUSTOM_6 = 8,
|
||||||
|
CUSTOM_7 = 9,
|
||||||
|
CUSTOM_8 = 10,
|
||||||
|
CUSTOM_9 = 11,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MAX_AUDIO_CHANNELS = 12;
|
71
src/demos/AudioDemo.ts
Normal file
71
src/demos/AudioDemo.ts
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import Vec2 from "../Wolfie2D/DataTypes/Vec2";
|
||||||
|
import { GameEventType } from "../Wolfie2D/Events/GameEventType";
|
||||||
|
import Input from "../Wolfie2D/Input/Input";
|
||||||
|
import Label from "../Wolfie2D/Nodes/UIElements/Label";
|
||||||
|
import Slider from "../Wolfie2D/Nodes/UIElements/Slider";
|
||||||
|
import { UIElementType } from "../Wolfie2D/Nodes/UIElements/UIElementTypes";
|
||||||
|
import Scene from "../Wolfie2D/Scene/Scene";
|
||||||
|
import AudioManager, { AudioChannelType } from "../Wolfie2D/Sound/AudioManager";
|
||||||
|
import Color from "../Wolfie2D/Utils/Color";
|
||||||
|
|
||||||
|
export default class Test extends Scene {
|
||||||
|
loadScene(){
|
||||||
|
this.load.audio("song", "demo_assets/sounds/title.mp3");
|
||||||
|
this.load.audio("sfx", "demo_assets/sounds/jump.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
startScene(){
|
||||||
|
this.emitter.fireEvent(GameEventType.PLAY_MUSIC, {key: "song", loop: true, holdReference: true});
|
||||||
|
|
||||||
|
this.addLayer("Main");
|
||||||
|
|
||||||
|
// Initialize value to 1 (music is at max)
|
||||||
|
let slider = <Slider>this.add.uiElement(UIElementType.SLIDER, "Main", {position: new Vec2(600, 600), value: 1});
|
||||||
|
|
||||||
|
// UI Stuff
|
||||||
|
slider.size = new Vec2(200, 50);
|
||||||
|
slider.nibSize = new Vec2(30, 30);
|
||||||
|
slider.nibColor = Color.WHITE;
|
||||||
|
slider.sliderColor = Color.WHITE;
|
||||||
|
|
||||||
|
slider.onValueChange = (value: number) => {
|
||||||
|
// Use a non-linear value->volume function, since sound is wack
|
||||||
|
AudioManager.setVolume(AudioChannelType.MUSIC, value*value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize value to 1 (music is at max)
|
||||||
|
let sfxslider = <Slider>this.add.uiElement(UIElementType.SLIDER, "Main", {position: new Vec2(600, 700), value: 1});
|
||||||
|
|
||||||
|
// UI Stuff
|
||||||
|
sfxslider.size = new Vec2(200, 50);
|
||||||
|
sfxslider.nibSize = new Vec2(30, 30);
|
||||||
|
sfxslider.nibColor = Color.WHITE;
|
||||||
|
sfxslider.sliderColor = Color.WHITE;
|
||||||
|
|
||||||
|
sfxslider.onValueChange = (value: number) => {
|
||||||
|
// Use a non-linear value->volume function, since sound is wack
|
||||||
|
AudioManager.setVolume(AudioChannelType.SFX, value*value);
|
||||||
|
}
|
||||||
|
|
||||||
|
(this.add.uiElement(UIElementType.LABEL, "Main", {position: new Vec2(600, 100), text: "1 - Play a sound"}) as Label).textColor = Color.WHITE;
|
||||||
|
(this.add.uiElement(UIElementType.LABEL, "Main", {position: new Vec2(600, 200), text: "2 - Mute music"}) as Label).textColor = Color.WHITE;
|
||||||
|
(this.add.uiElement(UIElementType.LABEL, "Main", {position: new Vec2(600, 300), text: "3 - Unmute music"}) as Label).textColor = Color.WHITE;
|
||||||
|
(this.add.uiElement(UIElementType.LABEL, "Main", {position: new Vec2(600, 400), text: "4 - Fade out music"}) as Label).textColor = Color.WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScene(deltaT: number){
|
||||||
|
if(Input.isKeyJustPressed("1")){
|
||||||
|
this.emitter.fireEvent(GameEventType.PLAY_SFX, {key: "sfx", loop: false, holdReference: false});
|
||||||
|
} else if(Input.isKeyJustPressed("2")){
|
||||||
|
this.emitter.fireEvent(GameEventType.MUTE_CHANNEL, {channel: AudioChannelType.MUSIC});
|
||||||
|
} else if(Input.isKeyJustPressed("3")){
|
||||||
|
this.emitter.fireEvent(GameEventType.UNMUTE_CHANNEL, {channel: AudioChannelType.MUSIC});
|
||||||
|
} else if(Input.isKeyJustPressed("4")){
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/AudioParam
|
||||||
|
const am = AudioManager.getInstance();
|
||||||
|
const ctx = am.getAudioContext();
|
||||||
|
const gainNode = am.getChannelGainNode(AudioChannelType.MUSIC);
|
||||||
|
gainNode.gain.setTargetAtTime(0, ctx.currentTime, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/main.ts
10
src/main.ts
|
@ -9,15 +9,7 @@ import default_scene from "./default_scene";
|
||||||
// Set up options for our game
|
// Set up options for our game
|
||||||
let options = {
|
let options = {
|
||||||
canvasSize: {x: 1200, y: 800}, // The size of the game
|
canvasSize: {x: 1200, y: 800}, // The size of the game
|
||||||
clearColor: {r: 34, g: 32, b: 52}, // The color the game clears to
|
clearColor: {r: 0, g: 0, b: 0}, // The color the game clears to
|
||||||
inputs: [
|
|
||||||
{name: "left", keys: ["a"]},
|
|
||||||
{name: "right", keys: ["d"]},
|
|
||||||
{name: "jump", keys: ["w", "space"]},
|
|
||||||
{name: "run", keys: ["shift"]}
|
|
||||||
],
|
|
||||||
useWebGL: false, // Tell the game we want to use webgl
|
|
||||||
showDebug: false // Whether to show debug messages. You can change this to true if you want
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a game with the options specified
|
// Create a game with the options specified
|
||||||
|
|
Loading…
Reference in New Issue
Block a user