diff --git a/.gitignore b/.gitignore index 07b29ed..8eddfef 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ dist/* !dist/builtin/ # Include the hw1 assets -!dist/hw1_assets/ +!dist/hw4_assets/ ### IF YOU ARE MAKING A PROJECT, YOU MAY WANT TO UNCOMMENT THIS LINE ### # !dist/assets/ diff --git a/dist/hw4_assets/fonts/NoPixel.ttf b/dist/hw4_assets/fonts/NoPixel.ttf new file mode 100644 index 0000000..c97b7b2 Binary files /dev/null and b/dist/hw4_assets/fonts/NoPixel.ttf differ diff --git a/dist/hw4_assets/sounds/jump-3.wav b/dist/hw4_assets/sounds/jump-3.wav new file mode 100644 index 0000000..80df671 Binary files /dev/null and b/dist/hw4_assets/sounds/jump-3.wav differ diff --git a/dist/hw4_assets/sprites/2bitbackground.png b/dist/hw4_assets/sprites/2bitbackground.png new file mode 100644 index 0000000..2f221a9 Binary files /dev/null and b/dist/hw4_assets/sprites/2bitbackground.png differ diff --git a/dist/hw4_assets/sprites/coin.png b/dist/hw4_assets/sprites/coin.png new file mode 100644 index 0000000..1d9f45a Binary files /dev/null and b/dist/hw4_assets/sprites/coin.png differ diff --git a/dist/hw4_assets/spritesheets/ghostBunny.json b/dist/hw4_assets/spritesheets/ghostBunny.json new file mode 100644 index 0000000..5f8a9bf --- /dev/null +++ b/dist/hw4_assets/spritesheets/ghostBunny.json @@ -0,0 +1,22 @@ +{ + "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}] + } + ] +} \ No newline at end of file diff --git a/dist/hw4_assets/spritesheets/ghostBunny.png b/dist/hw4_assets/spritesheets/ghostBunny.png new file mode 100644 index 0000000..eb8cc40 Binary files /dev/null and b/dist/hw4_assets/spritesheets/ghostBunny.png differ diff --git a/dist/hw4_assets/spritesheets/hopper.json b/dist/hw4_assets/spritesheets/hopper.json new file mode 100644 index 0000000..6306175 --- /dev/null +++ b/dist/hw4_assets/spritesheets/hopper.json @@ -0,0 +1,26 @@ +{ + "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} ] + } + ] +} \ No newline at end of file diff --git a/dist/hw4_assets/spritesheets/hopper.png b/dist/hw4_assets/spritesheets/hopper.png new file mode 100644 index 0000000..fb1a6cd Binary files /dev/null and b/dist/hw4_assets/spritesheets/hopper.png differ diff --git a/dist/hw4_assets/spritesheets/platformPlayer.json b/dist/hw4_assets/spritesheets/platformPlayer.json new file mode 100644 index 0000000..f67d69a --- /dev/null +++ b/dist/hw4_assets/spritesheets/platformPlayer.json @@ -0,0 +1,27 @@ +{ + "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}] + } + ] +} \ No newline at end of file diff --git a/dist/hw4_assets/spritesheets/platformPlayer.png b/dist/hw4_assets/spritesheets/platformPlayer.png new file mode 100644 index 0000000..b62b001 Binary files /dev/null and b/dist/hw4_assets/spritesheets/platformPlayer.png differ diff --git a/dist/hw4_assets/tilemaps/level1.json b/dist/hw4_assets/tilemaps/level1.json new file mode 100644 index 0000000..dca2ac3 --- /dev/null +++ b/dist/hw4_assets/tilemaps/level1.json @@ -0,0 +1,558 @@ +{ "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 +} \ No newline at end of file diff --git a/dist/hw4_assets/tilemaps/level2.json b/dist/hw4_assets/tilemaps/level2.json new file mode 100644 index 0000000..15d1234 --- /dev/null +++ b/dist/hw4_assets/tilemaps/level2.json @@ -0,0 +1,901 @@ +{ "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 +} \ No newline at end of file diff --git a/dist/hw4_assets/tilemaps/platformer.png b/dist/hw4_assets/tilemaps/platformer.png new file mode 100644 index 0000000..4dbbc01 Binary files /dev/null and b/dist/hw4_assets/tilemaps/platformer.png differ diff --git a/src/Homework4/Enemies/EnemyController.ts b/src/Homework4/Enemies/EnemyController.ts new file mode 100644 index 0000000..a51b0e5 --- /dev/null +++ b/src/Homework4/Enemies/EnemyController.ts @@ -0,0 +1,71 @@ +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){ + 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); + } +} \ No newline at end of file diff --git a/src/Homework4/Enemies/EnemyState.ts b/src/Homework4/Enemies/EnemyState.ts new file mode 100644 index 0000000..0161214 --- /dev/null +++ b/src/Homework4/Enemies/EnemyState.ts @@ -0,0 +1,31 @@ +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; + (this.owner).invertX = !(this.owner).invertX; + } + } +} \ No newline at end of file diff --git a/src/Homework4/Enemies/Idle.ts b/src/Homework4/Enemies/Idle.ts new file mode 100644 index 0000000..bccff3b --- /dev/null +++ b/src/Homework4/Enemies/Idle.ts @@ -0,0 +1,37 @@ +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; + (this.owner).animation.play("IDLE", true); + } + + onExit(): Record { + (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)); + } +} \ No newline at end of file diff --git a/src/Homework4/Enemies/Jump.ts b/src/Homework4/Enemies/Jump.ts new file mode 100644 index 0000000..1e50b3a --- /dev/null +++ b/src/Homework4/Enemies/Jump.ts @@ -0,0 +1,34 @@ +import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite"; +import { EnemyStates } from "./EnemyController"; +import EnemyState from "./EnemyState"; + +export default class Jump extends EnemyState { + + onEnter(): void { + (this.owner).animation.play("JUMP", true); + (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 { + (this.owner).animation.stop(); + (this.owner).tweens.stop("jump"); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Enemies/OnGround.ts b/src/Homework4/Enemies/OnGround.ts new file mode 100644 index 0000000..14ec299 --- /dev/null +++ b/src/Homework4/Enemies/OnGround.ts @@ -0,0 +1,26 @@ +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 { + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Enemies/Walk.ts b/src/Homework4/Enemies/Walk.ts new file mode 100644 index 0000000..4d12ecb --- /dev/null +++ b/src/Homework4/Enemies/Walk.ts @@ -0,0 +1,37 @@ +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); + (this.owner).invertX = true; + } + + (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 { + (this.owner).animation.stop(); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerController.ts b/src/Homework4/Player/PlayerController.ts new file mode 100644 index 0000000..2deccca --- /dev/null +++ b/src/Homework4/Player/PlayerController.ts @@ -0,0 +1,89 @@ +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){ + 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"); + } + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/Fall.ts b/src/Homework4/Player/PlayerStates/Fall.ts new file mode 100644 index 0000000..8d8c5d9 --- /dev/null +++ b/src/Homework4/Player/PlayerStates/Fall.ts @@ -0,0 +1,18 @@ +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): void { + this.owner.animation.play("FALL", true); + } + + handleInput(event: GameEvent): void {} + + onExit(): Record { + this.owner.animation.stop(); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/Idle.ts b/src/Homework4/Player/PlayerStates/Idle.ts new file mode 100644 index 0000000..22f6a21 --- /dev/null +++ b/src/Homework4/Player/PlayerStates/Idle.ts @@ -0,0 +1,36 @@ +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): 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 { + this.owner.animation.stop(); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/InAir.ts b/src/Homework4/Player/PlayerStates/InAir.ts new file mode 100644 index 0000000..d13d71f --- /dev/null +++ b/src/Homework4/Player/PlayerStates/InAir.ts @@ -0,0 +1,19 @@ +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); + } + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/Jump.ts b/src/Homework4/Player/PlayerStates/Jump.ts new file mode 100644 index 0000000..3e56b9f --- /dev/null +++ b/src/Homework4/Player/PlayerStates/Jump.ts @@ -0,0 +1,108 @@ +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): 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 { + 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"); + } + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/OnGround.ts b/src/Homework4/Player/PlayerStates/OnGround.ts new file mode 100644 index 0000000..b60533e --- /dev/null +++ b/src/Homework4/Player/PlayerStates/OnGround.ts @@ -0,0 +1,38 @@ +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): 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){ + (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 { + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/PlayerState.ts b/src/Homework4/Player/PlayerStates/PlayerState.ts new file mode 100644 index 0000000..1183ecd --- /dev/null +++ b/src/Homework4/Player/PlayerStates/PlayerState.ts @@ -0,0 +1,30 @@ +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; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/Run.ts b/src/Homework4/Player/PlayerStates/Run.ts new file mode 100644 index 0000000..5fef920 --- /dev/null +++ b/src/Homework4/Player/PlayerStates/Run.ts @@ -0,0 +1,38 @@ +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): 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 { + this.owner.animation.stop(); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Player/PlayerStates/Walk.ts b/src/Homework4/Player/PlayerStates/Walk.ts new file mode 100644 index 0000000..9e4db0f --- /dev/null +++ b/src/Homework4/Player/PlayerStates/Walk.ts @@ -0,0 +1,38 @@ +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): 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 { + this.owner.animation.stop(); + return {}; + } +} \ No newline at end of file diff --git a/src/Homework4/Scenes/GameLevel.ts b/src/Homework4/Scenes/GameLevel.ts new file mode 100644 index 0000000..cbc8a3b --- /dev/null +++ b/src/Homework4/Scenes/GameLevel.ts @@ -0,0 +1,362 @@ +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(node, other); + } else { + // Other is player, node is enemy + this.handlePlayerEnemyCollision(other,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 =