diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b785842 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4714a90 --- /dev/null +++ b/LICENSE @@ -0,0 +1,47 @@ +Copyright (c) 2013, 2014, 2015, 2016 Jake Gordon and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +# Javascript Tiny-Platformer + +A very minimal javascript platform game + +- [play the game](http://codeincomplete.com/projects/tiny-platformer/index.html) +- read the [original article](http://codeincomplete.com/posts/2013/5/27/tiny_platformer/) +- read a [follow up article](http://codeincomplete.com/posts/2013/6/2/tiny_platformer_revisited/) about adding monsters and treasure +- view the [source](https://github.com/jakesgordon/javascript-tiny-platformer) + +Just a sinple example of how to have a tiny rectangle run around some rectangle platforms, +collecting rectangular gold and avoiding rectangular monsters. + +# SUPPORTED BROWSERS + +Should work in any modern browser with canvas support + +# DEVELOPMENT + +The game is 100% client side javascript, html and css. It should run when served up by any web server. + +# License + +[MIT](http://en.wikipedia.org/wiki/MIT_License) license. + +--- diff --git a/README.md b/README.md new file mode 100644 index 0000000..bccc9c5 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# Readme + +Simple JS platformer to modify and extend. + +## Welche VS Code Extensions sollten installiert sein + +- Better Comments +- Color Highlight +- Atom One Dark Theme +- Material Icon Theme + +## Grundideen + +- Camera Setup kann ich erstmal auslassen. Dann mache ich stattdessen single rooms (vgl. Lykia). +- Overworld und Levels? +- Character selection? +- Inventory System mit durchsuchbaren Kisten, Content bleibt erhalten. +- Auflösung von Gameboy, GBC, Game Gear ist 160 × 144 pixel. +- Sprite Animation kann ich genauso machen wie bei Pico-8 (, )! +- Setting ist ein Space Adventure. Mit einem Raumschiff kann man viele verschiedene Umgebungen erreichen (Dschungel, Techno, Unterwasser, Höhlen,...) +- Commander Keen trifft Metroidvania (mit ein bisschen Subnautica?) + +## Todo + +- [x] Refactor code. Alles sortieren (Helper, Utils, Functions, Main Function, Objects usw.) +- [x] Robuste collision checks und collision maps bauen +- [x] Irgendeine Art Dev Function bauen, die mir übersichtliche console logs ausgibt. +- [x] "Doors" System entwickeln. +- [x] Die Camera funktioniert in Level2 noch nicht mit Begrenzung nach Rechts und Unten. Liegt das am Level selbst? +- [x] Pause Function +- [x] Sprite Animation () +- [x] Maps umrüsten auf 16x16 px tiles. Ist in den Variablen schon vorbereitet, muss nur die Maps noch mal aus Tiled exportieren + - [x] Aus Tiled werden die Custom Properties nicht richtig exportiert + - [x] "type" muss ich ändern in "class" in der setup Funktion + - [x] Die properties werden als Array exportiert. Da brauche ich in der setup Funktion noch eine Function um die zu Konviertieren. +- [x] Globales Objekt bauen mit einem einzigen Wert ("life = 3" z.B.), den ich immer Anzeige und der über die Level hinaus bestehen bleibt. +- [ ] Gravity Variable für verschiedene Umgebungen (Land, Wasser, Space) +- [ ] Verschiedene Biomes + - [ ] Ice World + - [ ] Desert World + - [ ] Lava World + - [ ] Underwater + - [ ] Forest World + - [ ] Techno World +- [ ] Fix Scaling bei verschiedenen Level-Größen (protrait ist broken) + +### Welche Assets nutze ich + +- "Grotto Escape Pack" by Ansimuz +- "8-Bit Cave Loop" by Wolfgang + +## Welche Tools nutze ich + +- Beepbox für Musik +- Tiled für Sprites und Maps + +### Tiled + +Map Setup: + +- Orthogonal +- CSV +- Left Down (! das ist wichtig) + +Layer in folgender Reihenfolge: + +- foreground +- Object Layer 1 +- tileLayer +- background + +Export als ".tmj" + +## Feature Roadmap + +- [x] zweite Map + - [x] Variablen für alle Props, die die Map betreffen (MAP.tw/.th, Scaling, HUD-Scaling, TileAtlas) +- [x] Alphabet TileMap (oder font!) +- [x] Map Layers (CollisionLayer, Background, Foreground, Object-Layer) inkl. Anleitung für Tiled +- [x] Map Transitions (mit einem Doors Object) +- [x] Map Layers +- [x] Global Player Object +- [x] Shooting +- [x] Swimming +- [x] Ammo +- [ ] mehr Weapons +- [ ] animated Tiles +- [ ] Destructibles (haben eigenes "destructibles = {}" Objekt wie monsters oder treasure und haben hitpoints, eigener Layer oder gehören die zu Objects?) +- [ ] Upgrades/Powerups +- [ ] Ladders/Poles +- [ ] mehr Enemy Types (flying, wallcrawler, shooting) +- [ ] Game Start/Game Over Screen +- [ ] Inventory System +- [ ] CameraBox +- [ ] Sprites + - [ ] Player + - [ ] Enemies + - [ ] Items + - [ ] Map + +## Possible Story + +Biff Bolton, sidekick to intergalactic space adventurer Ace Hunter, is stranded on a strange planet after several parts of his ship fail and he has to make an emergency landing. To repair his ship he must explore the planet and delve deep into its mysterious caves and catacombs. diff --git a/audio/Blip_Select.wav b/audio/Blip_Select.wav new file mode 100644 index 0000000..50acc69 Binary files /dev/null and b/audio/Blip_Select.wav differ diff --git a/audio/Default.wav b/audio/Default.wav new file mode 100644 index 0000000..a912dc8 Binary files /dev/null and b/audio/Default.wav differ diff --git a/audio/Explosion.wav b/audio/Explosion.wav new file mode 100644 index 0000000..e3985c6 Binary files /dev/null and b/audio/Explosion.wav differ diff --git a/audio/Explosion2.wav b/audio/Explosion2.wav new file mode 100644 index 0000000..4683fa7 Binary files /dev/null and b/audio/Explosion2.wav differ diff --git a/audio/Jump.wav b/audio/Jump.wav new file mode 100644 index 0000000..6569781 Binary files /dev/null and b/audio/Jump.wav differ diff --git a/audio/LA_Chest_Open.wav b/audio/LA_Chest_Open.wav new file mode 100644 index 0000000..5b95e71 Binary files /dev/null and b/audio/LA_Chest_Open.wav differ diff --git a/audio/LA_Ground_Crumble.wav b/audio/LA_Ground_Crumble.wav new file mode 100644 index 0000000..2a06e94 Binary files /dev/null and b/audio/LA_Ground_Crumble.wav differ diff --git a/audio/LA_LowHealth.wav b/audio/LA_LowHealth.wav new file mode 100644 index 0000000..89721a7 Binary files /dev/null and b/audio/LA_LowHealth.wav differ diff --git a/audio/LA_Rock_Push.wav b/audio/LA_Rock_Push.wav new file mode 100644 index 0000000..91a01c8 Binary files /dev/null and b/audio/LA_Rock_Push.wav differ diff --git a/audio/Laser1.wav b/audio/Laser1.wav new file mode 100644 index 0000000..9db73af Binary files /dev/null and b/audio/Laser1.wav differ diff --git a/audio/Laser2.wav b/audio/Laser2.wav new file mode 100644 index 0000000..5e637a4 Binary files /dev/null and b/audio/Laser2.wav differ diff --git a/audio/Oracle_Chest.wav b/audio/Oracle_Chest.wav new file mode 100644 index 0000000..e881321 Binary files /dev/null and b/audio/Oracle_Chest.wav differ diff --git a/audio/Oracle_Rock_Shatter.wav b/audio/Oracle_Rock_Shatter.wav new file mode 100644 index 0000000..7596b82 Binary files /dev/null and b/audio/Oracle_Rock_Shatter.wav differ diff --git a/audio/Oracle_Stairs.wav b/audio/Oracle_Stairs.wav new file mode 100644 index 0000000..2834862 Binary files /dev/null and b/audio/Oracle_Stairs.wav differ diff --git a/audio/Pickup_Coin.wav b/audio/Pickup_Coin.wav new file mode 100644 index 0000000..6abbf25 Binary files /dev/null and b/audio/Pickup_Coin.wav differ diff --git a/audio/Powerup.wav b/audio/Powerup.wav new file mode 100644 index 0000000..5f603ce Binary files /dev/null and b/audio/Powerup.wav differ diff --git a/audio/Randomize.wav b/audio/Randomize.wav new file mode 100644 index 0000000..f71de5e Binary files /dev/null and b/audio/Randomize.wav differ diff --git a/audio/Randomize2.wav b/audio/Randomize2.wav new file mode 100644 index 0000000..922c920 Binary files /dev/null and b/audio/Randomize2.wav differ diff --git a/audio/Randomize3.wav b/audio/Randomize3.wav new file mode 100644 index 0000000..977cf73 Binary files /dev/null and b/audio/Randomize3.wav differ diff --git a/audio/Randomize4.wav b/audio/Randomize4.wav new file mode 100644 index 0000000..b2fce13 Binary files /dev/null and b/audio/Randomize4.wav differ diff --git a/audio/SML2_Swim.ogg b/audio/SML2_Swim.ogg new file mode 100644 index 0000000..127b747 Binary files /dev/null and b/audio/SML2_Swim.ogg differ diff --git a/audio/click.wav b/audio/click.wav new file mode 100644 index 0000000..6e14165 Binary files /dev/null and b/audio/click.wav differ diff --git a/audio/jump2.wav b/audio/jump2.wav new file mode 100644 index 0000000..ab0e2fa Binary files /dev/null and b/audio/jump2.wav differ diff --git a/audio/laser.wav b/audio/laser.wav new file mode 100644 index 0000000..22dcc35 Binary files /dev/null and b/audio/laser.wav differ diff --git a/audio/music/8BitCave.wav b/audio/music/8BitCave.wav new file mode 100644 index 0000000..5409161 Binary files /dev/null and b/audio/music/8BitCave.wav differ diff --git a/audio/pickup.wav b/audio/pickup.wav new file mode 100644 index 0000000..76847ba Binary files /dev/null and b/audio/pickup.wav differ diff --git a/audio/smb_1-up.wav b/audio/smb_1-up.wav new file mode 100644 index 0000000..1449c27 Binary files /dev/null and b/audio/smb_1-up.wav differ diff --git a/audio/smb_kick.wav b/audio/smb_kick.wav new file mode 100644 index 0000000..14cc827 Binary files /dev/null and b/audio/smb_kick.wav differ diff --git a/audio/smb_powerup.wav b/audio/smb_powerup.wav new file mode 100644 index 0000000..d085783 Binary files /dev/null and b/audio/smb_powerup.wav differ diff --git a/audio/smb_stomp.wav b/audio/smb_stomp.wav new file mode 100644 index 0000000..00ac6c9 Binary files /dev/null and b/audio/smb_stomp.wav differ diff --git a/beepbox/BeepBox-Song.json b/beepbox/BeepBox-Song.json new file mode 100644 index 0000000..81f802d --- /dev/null +++ b/beepbox/BeepBox-Song.json @@ -0,0 +1,683 @@ +{ + "format": "BeepBox", + "version": 9, + "scale": "easy :)", + "key": "C", + "introBars": 0, + "loopBars": 4, + "beatsPerBar": 8, + "ticksPerBeat": 4, + "beatsPerMinute": 150, + "layeredInstruments": false, + "patternInstruments": false, + "channels": [ + { + "type": "pitch", + "instruments": [ + { + "type": "FM", + "volume": 80, + "eqFilter": [], + "preset": 325, + "effects": [ + "chord type", + "note filter", + "reverb" + ], + "chord": "strum", + "noteFilter": [ + { + "type": "low-pass", + "cutoffHz": 19027.31, + "linearGain": 0.3536 + } + ], + "reverb": 33, + "fadeInSeconds": 0, + "fadeOutTicks": -3, + "algorithm": "1←2←3←4", + "feedbackType": "3⟲", + "feedbackAmplitude": 4, + "operators": [ + { + "frequency": "3×", + "amplitude": 13 + }, + { + "frequency": "1×", + "amplitude": 7 + }, + { + "frequency": "13×", + "amplitude": 3 + }, + { + "frequency": "1×", + "amplitude": 11 + } + ], + "envelopes": [ + { + "target": "noteFilterAllFreqs", + "envelope": "twang 1" + } + ] + } + ], + "patterns": [ + { + "notes": [ + { + "pitches": [ + 57 + ], + "points": [ + { + "tick": 4, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 6, + "pitchBend": 0, + "volume": 100 + } + ] + } + ] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + } + ], + "sequence": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "octaveScrollBar": 3 + }, + { + "type": "pitch", + "instruments": [ + { + "type": "FM", + "volume": 80, + "eqFilter": [], + "preset": 649, + "effects": [ + "transition type", + "vibrato", + "reverb" + ], + "transition": "slide", + "vibrato": "delayed", + "reverb": 33, + "fadeInSeconds": 0.0263, + "fadeOutTicks": -3, + "algorithm": "1←(2 3 4)", + "feedbackType": "1⟲", + "feedbackAmplitude": 2, + "operators": [ + { + "frequency": "2×", + "amplitude": 15 + }, + { + "frequency": "1×", + "amplitude": 7 + }, + { + "frequency": "~1×", + "amplitude": 7 + }, + { + "frequency": "1×", + "amplitude": 0 + } + ], + "envelopes": [ + { + "target": "operatorAmplitude", + "envelope": "punch", + "index": 1 + }, + { + "target": "feedbackAmplitude", + "envelope": "twang 3" + } + ] + } + ], + "patterns": [ + { + "notes": [ + { + "pitches": [ + 38 + ], + "points": [ + { + "tick": 4, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 6, + "pitchBend": 0, + "volume": 100 + } + ] + } + ] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + } + ], + "sequence": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "octaveScrollBar": 2 + }, + { + "type": "pitch", + "instruments": [ + { + "type": "FM", + "volume": 80, + "eqFilter": [], + "preset": 322, + "effects": [ + "chord type", + "note filter", + "reverb" + ], + "chord": "strum", + "noteFilter": [ + { + "type": "low-pass", + "cutoffHz": 13454.34, + "linearGain": 0.25 + } + ], + "reverb": 33, + "fadeInSeconds": 0, + "fadeOutTicks": 48, + "algorithm": "1←(2 3←4)", + "feedbackType": "3⟲", + "feedbackAmplitude": 4, + "operators": [ + { + "frequency": "1×", + "amplitude": 15 + }, + { + "frequency": "1×", + "amplitude": 5 + }, + { + "frequency": "11×", + "amplitude": 1 + }, + { + "frequency": "1×", + "amplitude": 9 + } + ], + "envelopes": [ + { + "target": "noteFilterAllFreqs", + "envelope": "twang 1" + }, + { + "target": "operatorAmplitude", + "envelope": "twang 3", + "index": 2 + }, + { + "target": "feedbackAmplitude", + "envelope": "twang 1" + } + ] + } + ], + "patterns": [ + { + "notes": [ + { + "pitches": [ + 19 + ], + "points": [ + { + "tick": 4, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 6, + "pitchBend": 0, + "volume": 100 + } + ] + }, + { + "pitches": [ + 19 + ], + "points": [ + { + "tick": 8, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 10, + "pitchBend": 0, + "volume": 100 + } + ] + }, + { + "pitches": [ + 28 + ], + "points": [ + { + "tick": 12, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 14, + "pitchBend": 0, + "volume": 100 + } + ] + }, + { + "pitches": [ + 19 + ], + "points": [ + { + "tick": 20, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 22, + "pitchBend": 0, + "volume": 100 + } + ] + }, + { + "pitches": [ + 19 + ], + "points": [ + { + "tick": 24, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 26, + "pitchBend": 0, + "volume": 100 + } + ] + }, + { + "pitches": [ + 28 + ], + "points": [ + { + "tick": 28, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 30, + "pitchBend": 0, + "volume": 100 + } + ] + } + ] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + } + ], + "sequence": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "octaveScrollBar": 1 + }, + { + "type": "drum", + "instruments": [ + { + "type": "noise", + "volume": 80, + "eqFilter": [ + { + "type": "low-pass", + "cutoffHz": 16000, + "linearGain": 0.3536 + } + ], + "preset": 69, + "effects": [ + "chord type" + ], + "chord": "arpeggio", + "fadeInSeconds": 0, + "fadeOutTicks": -3, + "wave": "retro", + "envelopes": [] + } + ], + "patterns": [ + { + "notes": [ + { + "pitches": [ + 9 + ], + "points": [ + { + "tick": 0, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 2, + "pitchBend": 0, + "volume": 0 + } + ], + "continuesLastPattern": false + }, + { + "pitches": [ + 6 + ], + "points": [ + { + "tick": 4, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 6, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 6 + ], + "points": [ + { + "tick": 6, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 8, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 9 + ], + "points": [ + { + "tick": 8, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 10, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 2 + ], + "points": [ + { + "tick": 10, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 12, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 2 + ], + "points": [ + { + "tick": 12, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 14, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 9 + ], + "points": [ + { + "tick": 16, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 18, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 2 + ], + "points": [ + { + "tick": 20, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 23, + "pitchBend": 0, + "volume": 0 + } + ] + }, + { + "pitches": [ + 9 + ], + "points": [ + { + "tick": 24, + "pitchBend": 0, + "volume": 100 + }, + { + "tick": 26, + "pitchBend": 0, + "volume": 0 + } + ] + } + ] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + }, + { + "notes": [] + } + ], + "sequence": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ] +} \ No newline at end of file diff --git a/fonts/C64_Pro-STYLE.eot b/fonts/C64_Pro-STYLE.eot new file mode 100644 index 0000000..3124016 Binary files /dev/null and b/fonts/C64_Pro-STYLE.eot differ diff --git a/fonts/C64_Pro-STYLE.otf b/fonts/C64_Pro-STYLE.otf new file mode 100644 index 0000000..f1e4dfe Binary files /dev/null and b/fonts/C64_Pro-STYLE.otf differ diff --git a/fonts/C64_Pro-STYLE.ttf b/fonts/C64_Pro-STYLE.ttf new file mode 100644 index 0000000..a6c30a6 Binary files /dev/null and b/fonts/C64_Pro-STYLE.ttf differ diff --git a/fonts/C64_Pro-STYLE.woff b/fonts/C64_Pro-STYLE.woff new file mode 100644 index 0000000..c711dd8 Binary files /dev/null and b/fonts/C64_Pro-STYLE.woff differ diff --git a/fonts/C64_Pro-STYLE.woff2 b/fonts/C64_Pro-STYLE.woff2 new file mode 100644 index 0000000..1d0a8d6 Binary files /dev/null and b/fonts/C64_Pro-STYLE.woff2 differ diff --git a/fonts/C64_Pro_Mono-STYLE.eot b/fonts/C64_Pro_Mono-STYLE.eot new file mode 100644 index 0000000..b671904 Binary files /dev/null and b/fonts/C64_Pro_Mono-STYLE.eot differ diff --git a/fonts/C64_Pro_Mono-STYLE.otf b/fonts/C64_Pro_Mono-STYLE.otf new file mode 100644 index 0000000..b96258c Binary files /dev/null and b/fonts/C64_Pro_Mono-STYLE.otf differ diff --git a/fonts/C64_Pro_Mono-STYLE.ttf b/fonts/C64_Pro_Mono-STYLE.ttf new file mode 100644 index 0000000..02ff5fc Binary files /dev/null and b/fonts/C64_Pro_Mono-STYLE.ttf differ diff --git a/fonts/C64_Pro_Mono-STYLE.woff b/fonts/C64_Pro_Mono-STYLE.woff new file mode 100644 index 0000000..60347be Binary files /dev/null and b/fonts/C64_Pro_Mono-STYLE.woff differ diff --git a/fonts/C64_Pro_Mono-STYLE.woff2 b/fonts/C64_Pro_Mono-STYLE.woff2 new file mode 100644 index 0000000..a1b72c5 Binary files /dev/null and b/fonts/C64_Pro_Mono-STYLE.woff2 differ diff --git a/fpsmeter.min.js b/fpsmeter.min.js new file mode 100644 index 0000000..481da37 --- /dev/null +++ b/fpsmeter.min.js @@ -0,0 +1,15 @@ +/*! FPSMeter 0.3.1 - 9th May 2013 | https://github.com/Darsain/fpsmeter */ +(function(m,j){function s(a,e){for(var g in e)try{a.style[g]=e[g]}catch(j){}return a}function H(a){return null==a?String(a):"object"===typeof a||"function"===typeof a?Object.prototype.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase()||"object":typeof a}function R(a,e){if("array"!==H(e))return-1;if(e.indexOf)return e.indexOf(a);for(var g=0,j=e.length;gd.interval?(x=M(k),m()):(x=setTimeout(k,d.interval),P=M(m))}function G(a){a=a||window.event;a.preventDefault?(a.preventDefault(),a.stopPropagation()):(a.returnValue= +!1,a.cancelBubble=!0);b.toggle()}function U(){d.toggleOn&&S(f.container,d.toggleOn,G,1);a.removeChild(f.container)}function V(){f.container&&U();h=D.theme[d.theme];y=h.compiledHeatmaps||[];if(!y.length&&h.heatmaps.length){for(p=0;p=m?m*(1+j):m+j-m*j;0===l?g="#000":(t=2*m-l,k=(l-t)/l,g*=6,n=Math.floor(g), +v=g-n,v*=l*k,0===n||6===n?(n=l,k=t+v,l=t):1===n?(n=l-v,k=l,l=t):2===n?(n=t,k=l,l=t+v):3===n?(n=t,k=l-v):4===n?(n=t+v,k=t):(n=l,k=t,l-=v),g="#"+N(n)+N(k)+N(l));b[e]=g}}h.compiledHeatmaps=y}f.container=s(document.createElement("div"),h.container);f.count=f.container.appendChild(s(document.createElement("div"),h.count));f.legend=f.container.appendChild(s(document.createElement("div"),h.legend));f.graph=d.graph?f.container.appendChild(s(document.createElement("div"),h.graph)):0;w.length=0;for(var q in f)f[q]&& +h[q].heatOn&&w.push({name:q,el:f[q]});u.length=0;if(f.graph){f.graph.style.width=d.history*h.column.width+(d.history-1)*h.column.spacing+"px";for(c=0;c + + + + + Javascript Platformer + + + + +
+ +
+ Sorry, this example cannot be run because your browser does not + support the <canvas> element +
+
+ +
+ LEFT/RIGHT to move, SPACE to jump, collect gold and jump + on monsters. +
+ +
+
+
+ +
+
+ + +
+
+ +
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/js/camera.js b/js/camera.js new file mode 100644 index 0000000..4693365 --- /dev/null +++ b/js/camera.js @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------- +// 3.2 Simple CAMERA +//------------------------------------------------------------------------- + +function renderCamera() { + // ! Ich muss diese Funktion gegen eine mit CameraBox austauschen. Diese kann ich aber für TopDown/Overworld Level benutzen. + + const cameraWidth = mapWidth * TILE + const cameraHeight = mapHeight * TILE + + const camera = { + get x() { + if (player.x < scaledCanvas.width) return 0 + if (player.x > cameraWidth - scaledCanvas.width) + return -(cameraWidth - scaledCanvas.width * 2) + else return -(player.x - scaledCanvas.width) + }, + get y() { + if (player.y < scaledCanvas.height) return 0 + if (player.y > cameraHeight - scaledCanvas.height) + return -(cameraHeight - scaledCanvas.height * 2) + else return -(player.y - scaledCanvas.height) + }, + } + + ctx.translate(camera.x, camera.y) +} + +//------------------------------------------------------------------------- +// Box CAMERA +//------------------------------------------------------------------------- + +let cameraWithBox = { + position: { + x: 0, + y: 0, + }, +} + +function renderCameraWithBox() { + //console.log('log renderCameraWithBox position.x: ', cameraWithBox.position.x) + ctx.translate(cameraWithBox.position.x, cameraWithBox.position.y) +} + +const cameraBox = { + // ! Die Werte stimme nur ungefähr, geben mir aber eine grobe CameraBox zurück. + get x() { + return -(canvas.width / 2 / 2 - 100 - player.x) + }, + get y() { + return -(canvas.height / 2 / 2 - 150 - player.y) + }, + width: canvas.width / 2 - 200, + height: canvas.height / 2 - 300, +} + +// ! "camera" muss ich dann in der renderCamera() in der render Funktion anpassen. +// ? Woher kommt this.velocity ? + +function shouldPanCameraToTheLeft({ canvas, camera }) { + const cameraboxRightSide = cameraBox.x + cameraBox.width + const scaledDownCanvasWidth = canvas.width / 2 + + // console.log('log cameraboxRightSide: ', cameraboxRightSide) + //console.log('log cameraboxRightSide >= 2048: ', cameraboxRightSide >= 2048) + // ! Woher kommt der Wert hier? + if (cameraboxRightSide >= 2048) return + + //console.log('log player.x: ', player.x) + + //console.log('log scaledDownCanvasWidth: ', scaledDownCanvasWidth) + + /* console.log( + 'log shouldPanCameraToTheLeft: ', + cameraboxRightSide >= scaledDownCanvasWidth + ) */ + + if ( + cameraboxRightSide >= + scaledDownCanvasWidth + Math.abs(cameraWithBox.position.x) + ) { + cameraWithBox.position.x -= player.x - canvas.width / 2 / 2 + } +} + +function shouldPanCameraToTheRight({ canvas, cameraprop }) { + //console.log('log shouldPanCameraToTheRight') + //console.log('log entity x update: ', (player.x + step * player.dx).toFixed(2)) + //console.log('log cameraBox.x <= 0: ', cameraBox.x <= 0) + if (cameraBox.x <= 0) return + + if (cameraBox.x <= Math.abs(cameraWithBox.position.x)) { + cameraWithBox.position.x = cameraWithBox.position.x-- + } +} + +function shouldPanCameraDown({ canvas, camera }) { + //console.log('log shouldPanCameraDown') + /* if (cameraBox.position.y + this.velocity.y <= 0) return + + if (cameraBox.position.y <= Math.abs(camera.position.y)) { + camera.position.y -= this.velocity.y + } */ +} + +function shouldPanCameraUp({ canvas, camera }) { + // console.log('log shouldPanCameraUp') + /* if (cameraBox.position.y + cameraBox.height + this.velocity.y >= 432) return + + const scaledCanvasHeight = canvas.height / 4 + + if ( + cameraBox.position.y + cameraBox.height >= + Math.abs(camera.position.y) + scaledCanvasHeight + ) { + camera.position.y -= this.velocity.y + } */ +} diff --git a/js/input.js b/js/input.js new file mode 100644 index 0000000..c6976fd --- /dev/null +++ b/js/input.js @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------- +// 3.1 INPUT +//------------------------------------------------------------------------- + +function onkey(ev, key, down) { + switch (key) { + case KEY.LEFT: + player.left = down + shouldPanCameraToTheRight({ canvas, cameraWithBox }) + ev.preventDefault() + return false + case KEY.RIGHT: + player.right = down + shouldPanCameraToTheLeft({ canvas, cameraWithBox }) + ev.preventDefault() + return false + case KEY.X: + player.jump = down + // console.log('log Key X') + shouldPanCameraDown({ canvas, cameraWithBox }) + ev.preventDefault() + return false + case KEY.Y: + console.log('log shoot') + // player.shooting = down + shoot(player) + ev.preventDefault() + return false + case KEY.UP: + console.log('log Key Up') + player.up = down + shouldPanCameraDown({ canvas, cameraWithBox }) + ev.preventDefault() + return false + case KEY.DOWN: + console.log('log Key Down') + player.down = down + ev.preventDefault() + return false + case KEY.ENTER: + console.log('log Key Enter') + player.interact = down + ev.preventDefault() + return false + case KEY.SPACE: + console.log('log Key Space') + ev.preventDefault() + return false + } +} diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..a0eee71 --- /dev/null +++ b/js/main.js @@ -0,0 +1,97 @@ +function main() { + //------------------------------------------------------------------------- + // 6. THE GAME LOOP + //------------------------------------------------------------------------- + + var counter = 0, + dt = 0, + now, + last = timestamp(), + fpsmeter = new FPSMeter({ + decimals: 0, + graph: true, + theme: 'dark', + left: '5px', + }) + + function frame() { + fpsmeter.tickStart() + now = timestamp() + dt = dt + Math.min(1, (now - last) / 1000) + while (dt > step) { + dt = dt - step + + // * Update wird pausiert bei Toggle 'p'. + if (!paused) { + update(step) + } + } + + render(ctx, counter, dt, currentLevel) + + last = now + counter++ + fpsmeter.tick() + requestAnimationFrame(frame, canvas) + } + + document.addEventListener( + 'keydown', + function (ev) { + return onkey(ev, ev.key, true) + }, + false + ) + document.addEventListener( + 'keyup', + function (ev) { + return onkey(ev, ev.key, false) + }, + false + ) + + // * EventListener für Pause-Taste + window.addEventListener('keydown', function (e) { + var key = e.key + if (key === 'p') { + // p key + togglePause() + } + }) + // * EventListener für DevInfos Toggle + window.addEventListener('keydown', function (e) { + var key = e.key + if (key === 'o') { + // p key + toggleDevInfos() + } + }) + + // ! Vielleicht kann ich statt des setup() an dieser Stelle auch eine gameStart() Funktion erstellen, die beim erstmaligen Start alles erledigt. Später wird dann ja immer die _initLevel() aufgerufen. + setup(currentLevel.levelData) // ! Was brauche ich hier, damit das variabel alle Level laden kann? + + console.log('log monsters ', monsters) + + frame() +} + +// * window onload function +;(function () { + //------------------------------------------------------------------------- + // POLYFILLS + //------------------------------------------------------------------------- + + if (!window.requestAnimationFrame) { + // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + window.requestAnimationFrame = + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback, element) { + window.setTimeout(callback, 1000 / 60) + } + } + + main() +})() diff --git a/js/render.js b/js/render.js new file mode 100644 index 0000000..2ff1a17 --- /dev/null +++ b/js/render.js @@ -0,0 +1,375 @@ +//------------------------------------------------------------------------- +// 4. RENDERING +//------------------------------------------------------------------------- + +function render(ctx, frame, dt, thiscurrentLevel) { + // ? Kann ich mich eigentlich mit scale und translate noch weiter an Pico-8 orientieren und in den variables sowas wie scale = ctx.scale oder so erstellen? + // * Disable Image Smoothing + ctx.mozImageSmoothingEnabled = false + ctx.webkitImageSmoothingEnabled = false + ctx.msImageSmoothingEnabled = false + ctx.imageSmoothingEnabled = false + + ctx.save() + ctx.scale( + Math.round(thiscurrentLevel.scalingFactor / 2), + Math.round(thiscurrentLevel.scalingFactor / 2) + ) + + ctx.clearRect(0, 0, width, height) + renderCamera() + //renderCameraWithBox() + renderBackground(ctx, thiscurrentLevel.backgroundAtlas, bgCells) + renderMap(ctx, thiscurrentLevel.levelAtlas, cells) + renderPlayer(ctx, playerAtlas, dt, frame) + renderBullets(ctx, itemsAtlas, dt, frame) + renderMonsters(ctx, enemyAtlas, dt, frame) + renderTreasure(ctx, itemsAtlas, dt, frame) + renderPickups(ctx, itemsAtlas, dt, frame) + renderForeground(ctx, thiscurrentLevel.foregroundAtlas, fgCells) + renderLiquids(ctx, thiscurrentLevel.foregroundAtlas, fgCells) + + // * Draw CameraBox + //renderCameraBox() + ctx.restore() + renderPause() + renderHud(ctx, meterAtlas, dt, frame) + renderHudSprites() + //fadeScreen(frame, dt) + renderDevInfos() +} + +// Map Limit Variables + +// * Das hier ist die allgemeine Funktion um Tiles aus dem TileAtlas auf den Canvas zu malen. +function drawTile(levelAtlas, cell, dx, dy, opacity) { + levelAtlas.sourceY = + Math.floor(cell / levelAtlas.atlasCol) * levelAtlas.tileSize + levelAtlas.sourceX = (cell % levelAtlas.atlasCol) * levelAtlas.tileSize + // ? Wofür stehen die Werte sWidth, sHeight, dWidth, dHeight + + ctx.globalAlpha = opacity + // ! Kann ich die ganzen festen Zahlen als Variablen aus der Map holen? + ctx.drawImage( + levelAtlas.tileAtlas, + levelAtlas.sourceX, + levelAtlas.sourceY, + 16, + 16, + dx * 16, + dy * 16, + 16, + 16 + ) +} + +function renderBackground(ctx, levelAtlas) { + var x, y, cell + for (y = 0; y < mapHeight; y++) { + for (x = 0; x < mapWidth; x++) { + cell = bgTcell(x, y, mapWidth) + if (cell) { + drawTile(levelAtlas, cell - levelAtlas.offset, x, y) + } + } + } +} + +function renderForeground(ctx, levelAtlas) { + var x, y, cell + for (y = 0; y < mapHeight; y++) { + for (x = 0; x < mapWidth; x++) { + cell = fgTcell(x, y, mapWidth) + if (cell) { + drawTile(levelAtlas, cell - levelAtlas.offset, x, y) + } + } + } +} + +function renderLiquids(ctx, levelAtlas) { + var x, y, cell + for (y = 0; y < mapHeight; y++) { + for (x = 0; x < mapWidth; x++) { + cell = lqTcell(x, y, mapWidth) + if (cell) { + drawTile(levelAtlas, cell - levelAtlas.offset, x, y, 0.5) + } + } + } +} + +function renderMap(ctx, levelAtlas) { + var x, y, cell + for (y = 0; y < mapHeight; y++) { + for (x = 0; x < mapWidth; x++) { + cell = tcell(x, y, mapWidth) + if (cell) { + drawTile(levelAtlas, cell - levelAtlas.offset, x, y) + } + } + } +} + +// * Sprite Animation +function drawSprite(entity, spriteAtlas, dt, frame) { + /* entity.start.x === 48 && + entity.start.y === 656 && + console.log('log frame ', entity.sprites.idle) + */ + + let sprites = entity.sprites + + let isJumping = entity.jumping || entity.falling + + let isRunning = + (entity.right === true && !isJumping) || + (entity.left === true && !isJumping) + + let isShooting = entity.shooting || false + + let sprite = + !!sprites.run && isRunning + ? sprites.run + : !!sprites.jump && isJumping + ? sprites.jump + : !!sprites.shoot && isShooting + ? sprites.shoot + : sprites.idle + + const x = entity.bullet ? entity.x : entity.x + entity.dx * dt + const y = entity.bullet + ? entity.y - entity.height * 2 + : entity.y + entity.dy * dt + const flipped = entity.flipped + const width = entity.bullet ? entity.width * 4 : entity.width + const height = entity.bullet ? entity.height * 4 : entity.height + + let spriteTile = sprite.tiles[sprite.currentFrame] + + /* entity.pickups && + console.log( + 'log drawSprite currentFrame ', + sprite.tiles[sprite.currentFrame] + ) */ + + // make an image position using the + // current row and colum + spriteAtlas.sourceY = + Math.floor(spriteTile / spriteAtlas.atlasCol) * spriteAtlas.tileSize + spriteAtlas.sourceX = + (spriteTile % spriteAtlas.atlasCol) * spriteAtlas.tileSize + + ctx.save() + // * Flip Sprite + ctx.scale(flipped ? -1 : 1, 1) + let dx = flipped ? -x - width : x + + ctx.drawImage( + spriteAtlas.tileAtlas, + spriteAtlas.sourceX, + spriteAtlas.sourceY, + 16, // * source Höhe + 16, // * source Breite + dx, + y, + width, // * player Höhe + height // * player Breite + ) + + ctx.restore() + updateFrames(frame, sprite) + + // entity.treasure && console.log('log drawSprite ', entity) +} + +function updateFrames(frame, sprite) { + /* entity.start.x === 48 && + entity.start.y === 656 && + console.log('log frame ', entity) */ + + if (frame % sprite.framebuffer === 0) { + if (sprite.currentFrame + 1 < sprite.tiles.length) sprite.currentFrame++ + else if (sprite.loop) sprite.currentFrame = 0 + } +} +// * Render Player +function renderPlayer(ctx, spriteAtlas, dt, frame) { + if (player.vul === false) { + ctx.globalAlpha = 0.25 + tweenTreasure(frame * 3, 60) + } + drawSprite(player, spriteAtlas, dt, frame) + ctx.globalAlpha = 1 +} + +function renderHud(ctx, spriteAtlas, dt, frame) { + var n, max + const hudScaling = scalingFactor / 2 + + const hitpoints = globalObject.hitpoints + const killed = globalObject.killed + const collected = globalObject.collected + + ctx.fillStyle = COLOR.GOLD + for (n = 0, max = collected; n < max; n++) + ctx.fillRect( + t2p(1 + n) * hudScaling, + t2p(1) * hudScaling, + (TILE / 2) * hudScaling, + (TILE / 2) * hudScaling + ) + + ctx.fillStyle = COLOR.SLATE + for (n = 0, max = killed; n < max; n++) + ctx.fillRect( + t2p(1 + n) * hudScaling, + t2p(2) * hudScaling, + (TILE / 2) * hudScaling, + (TILE / 2) * hudScaling + ) + + // ! provisorische Hitpoint-Anzeige + ctx.fillStyle = 'red' + if (hitpoints === 1) { + ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60) + } + for (n = 0, max = hitpoints; n < max; n++) + ctx.fillRect( + t2p(1 + n) * hudScaling, + t2p(3) * hudScaling, + (TILE / 2) * hudScaling, + (TILE / 2) * hudScaling + ) + // ! Der Atlas funktioniert so nicht weil die Tiles nicht quadratisch sind. + // drawSprite(t, spriteAtlas, dt, frame) + ctx.globalAlpha = 1 +} + +function fadeScreen(frame, dt) { + ctx.fillStyle = 'black' + ctx.globalAlpha = 0 + let duration = 100 + + pulse = frame % duration + + if (pulse < duration) { + opacity = pulse / duration + } else { + opacity = 0 + } + + ctx.fillRect(0, 0, width, height) + ctx.globalAlpha = opacity + + //setInterval(show(), 800) + // console.log('log opacity ', opacity) + // console.log('log fade frame ', frame) + // console.log('log fade pulse ', pulse) +} + +// * Render Pause Function +function renderPause() { + if (paused) { + ctx.save() + ctx.scale(scalingFactor / 2, scalingFactor / 2) + + ctx.font = '12px C64 TrueType' + ctx.fillStyle = 'white' + ctx.textAlign = 'center' + ctx.fillText('- pause -', scaledCanvas.width, scaledCanvas.height) + ctx.restore() + } +} + +function renderCameraBox() { + ctx.fillStyle = 'rgba(0, 0, 255, 0.2)' + ctx.fillRect(cameraBox.x, cameraBox.y, cameraBox.width, cameraBox.height) +} + +function renderMonsters(ctx, spriteAtlas, dt, frame) { + ctx.fillStyle = COLOR.SLATE + var n, max, monster + for (n = 0, max = monsters.length; n < max; n++) { + monster = monsters[n] + + if (monster.sprites === undefined && !monster.dead) + ctx.fillRect( + monster.x + monster.dx * dt, + monster.y + monster.dy * dt, + TILE, + TILE + ) + if (monster.sprites !== undefined && !monster.dead) { + drawSprite(monster, spriteAtlas, dt, frame) + } + } +} + +function renderPickups(ctx, spriteAtlas, dt, frame) { + //ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60) + var n, max, p + for (n = 0, max = pickups.length; n < max; n++) { + p = pickups[n] + + //console.log('log p.sprites.currentsprite ', p.sprites.currentFrame) + + if (p.sprites !== undefined && !p.collected) { + drawSprite(p, spriteAtlas, dt, frame) + } + } + //ctx.globalAlpha = 1 +} + +function renderTreasure(ctx, spriteAtlas, dt, frame) { + ctx.fillStyle = COLOR.GOLD + ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60) + var n, max, t + for (n = 0, max = treasure.length; n < max; n++) { + t = treasure[n] + //if (!t.collected) ctx.fillRect(t.x, t.y + TILE / 3, TILE, (TILE * 2) / 3) + + if (t.sprites !== undefined && !t.collected) { + // console.log('log treasure entity ', t) + drawSprite(t, spriteAtlas, dt, frame) + } + } + ctx.globalAlpha = 1 +} + +function tweenTreasure(frame, duration) { + const half = duration / 2 + pulse = frame % duration + return pulse < half ? pulse / half : 1 - (pulse - half) / half +} + +function renderBullets(ctx, spriteAtlas, dt, frame) { + ctx.fillStyle = COLOR.GOLD + + var n, max, bullet + + for (n = 0, max = bullets.length; n < max; n++) { + bullet = bullets[n] + + switch (bullet.ammoType) { + case 'simpleGun': + bullet.sprites = simpleBullet.sprites + break + case 'advancedGun': + bullet.sprites = simpleBullet.sprites + break + } + + //console.log('log bullet ', bullet.sprites) + //console.log('log bullet spriteAtlas ', spriteAtlas) + + if (bullet !== undefined) { + if (bullet.sprites === undefined) { + ctx.fillRect(bullet.x, bullet.y, ammoType.width, ammoType.height) + } + if (bullet.sprites !== undefined) { + console.log('log bullet entity ', bullet) + drawSprite(bullet, spriteAtlas, dt, frame) + } + } + } +} diff --git a/js/setup.js b/js/setup.js new file mode 100644 index 0000000..be8050f --- /dev/null +++ b/js/setup.js @@ -0,0 +1,150 @@ +//------------------------------------------------------------------------- +// 5. LOAD THE MAP +//------------------------------------------------------------------------- + +// ! Wenn ich die Setup-Funktion zum Levelwechsel aufrufe, dann werden die Variablen nicht upgedated! + +// * Die setup Funktion finde ich gut, weil sie alle Infos aus einer map mit mehreren Layern erhalten kann. +function setup(map) { + var background = map.layers[0]?.data, + data = map.layers[1].data, + objects = map.layers[2].objects, + foreground = map.layers[3]?.data, + liquidTiles = map.layers[4]?.data || null, + n, + obj, + entity + + for (n = 0; n < objects.length; n++) { + obj = objects[n] + + const entityType = obj.type || obj.class + const entityName = obj.name + const entityClass = obj.class + + const entityProperties = Array.isArray(obj.properties) + ? Object.fromEntries( + !!obj.properties && + obj.properties?.map((obj) => [obj.name, obj.value]) + ) + : !!obj.properties + ? obj.properties + : {} + + // * Hier werden alle actors/entities in die entsprechenden Ojekte gepushed. + entity = setupEntity(obj, entityType, entityProperties, entityName) + + switch (entityType) { + case 'player': + player = entity + break + case 'monster': + monsters.push(entity) + break + case 'slimeMonster': + monsters.push(entity) + break + case 'treasure': + treasure.push(entity) + break + + case 'ammo': + pickups.push(entity) + break + case 'health': + pickups.push(entity) + break + case 'extralife': + pickups.push(entity) + break + + case 'water': + liquids.push(entity) + break + case 'door': + doors.push(entity) + break + } + } + + cells = data + bgCells = background + fgCells = foreground + lqCells = liquidTiles +} + +// * Diese Funktion entspricht grob meiner actor init Funktion. +// ? Muss ich noch eine Sprite Animation Funktion erstellen, die ihre Daten aus dem Entity Object für alle Entities (player, monster, etc.) erhält? +function setupEntity(obj, entityType, entityProperties, entityName) { + let entityTemplate = + entityName == 'monster' + ? bounderMonster + : entityName == 'player' + ? playerObject + : entityName == 'slimeMonster' + ? slimeMonster + : entityName == 'treasure' + ? coinTreasure + : entityName == 'ammo' + ? ammo + : entityName == 'health' + ? health + : entityName == 'extralife' + ? extralife + : entityName == 'door' + ? null + : null + + let entitySprites = entityTemplate?.sprites + + const entityMaxHitpoints = + entityType == 'player' ? playerObject.maxHitpoints : 1 + + const entityCurrentHitpoints = + entityType == 'player' + ? playerObject.currentHitpoints + : !!entityTemplate?.currentHitpoints + ? entityTemplate?.currentHitpoints + : 1 + + console.log('log entity ', entity) + + var entity = {} + entity.x = obj.x + entity.y = obj.y + entity.dx = 0 + entity.dy = 0 + entity.gravity = METER * (entityProperties.gravity || GRAVITY) + entity.maxdx = METER * (entityProperties.maxdx || MAXDX) + entity.maxdy = METER * (entityProperties.maxdy || MAXDY) + entity.impulse = METER * (entityProperties.impulse || IMPULSE) + entity.accel = entity.maxdx / (entityProperties.accel || ACCEL) + entity.friction = entity.maxdx / (entityProperties.friction || FRICTION) + entity.monster = entityType == 'monster' + entity.slimeMonster = entityType == 'slimeMonster' + entity.player = entityType == 'player' + entity.treasure = entityType == 'treasure' + entity.ammo = entityType == 'ammo' + entity.health = entityType == 'health' + entity.extralife = entityType == 'extralife' + entity.water = entityType == 'water' + entity.door = entityType == 'door' + entity.leadsTo = entityProperties.leadsTo + entity.left = entityProperties.left + entity.right = entityProperties.right + entity.up = entityProperties.up || false + entity.down = entityProperties.down || false + entity.start = { x: obj.x, y: obj.y } + entity.killed = 0 + entity.collected = false + entity.sprites = entitySprites + entity.flipped = false + entity.width = obj.width + entity.height = obj.height + entity.maxHitpoints = entityMaxHitpoints + entity.currentHitpoints = entityCurrentHitpoints + entity.hurt = false + entity.vul = true + + return entity +} diff --git a/js/update.js b/js/update.js new file mode 100644 index 0000000..8d01e61 --- /dev/null +++ b/js/update.js @@ -0,0 +1,411 @@ +//------------------------------------------------------------------------- +// 3. UPDATE LOOP +//------------------------------------------------------------------------- + +function update(dt) { + updatePlayer(dt) + updateBullets(dt) + updateMonsters(dt) + checkTreasure() + checkPickups() + checkLiquids() + // updateDoors(dt) + checkDoors() + + // ! Vielleicht eigene update Funktion für Musik schreiben + // theme.level1.play() +} + +function updatePlayer(dt) { + updateEntity(player, dt) +} + +function updateMonsters(dt) { + var n, max + for (n = 0, max = monsters.length; n < max; n++) + updateMonster(monsters[n], dt) +} + +function updateMonster(monster, dt) { + monster.slimeMonster && console.log('log monster ', monster) + if (!monster.dead) { + updateEntity(monster, dt) + if ( + overlap(player.x, player.y, TILE, TILE, monster.x, monster.y, TILE, TILE) + ) { + if (player.dy > 0 && monster.y - player.y > TILE / 2) killMonster(monster) + else if (player.vul) { + reduceHitpoints(player, 1) + } + } + } +} + +function shoot(player) { + //globalObject.ammo > 0 ? sfx.shoot.play() : sfx.click.play() + if (player.shooting) return + player.shooting = true + const bulletX = player.x + const bulletY = player.y + const direction = player.flipped + const weaponType = player?.currentWeapon || 'simpleGun' + + if (globalObject.ammo > 0) { + sfx.shoot.play() + globalObject.ammo-- + bullets.push({ + bullet: true, + width: 4, + height: 4, + flipped: player.flipped, + originX: bulletX, + originY: bulletY, + x: bulletX, + y: bulletY + player.height / 2, + directionLeft: direction, + ammoType: weaponType, + damage: 1, + }) + } else { + sfx.click.play() + } + setTimeout(() => { + player.shooting = false + }, 200) +} + +function updateBullets(dt) { + var n, max + for (n = 0, max = bullets.length; n < max; n++) updateBullet(bullets[n], dt) +} + +function updateBullet(bullet, dt) { + if (!!bullet) { + if (bullet.directionLeft) { + bullet.x = bullet.x - ammoType.velocity + } else { + bullet.x = bullet.x + ammoType.velocity + } + var n, max, monster, thisBullet + for (n = 0, max = monsters.length; n < max; n++) { + monster = monsters[n] + thisBullet = bullet + if (!monster.dead) { + if ( + overlap( + thisBullet.x, + thisBullet.y, + ammoType.width, + ammoType.height, + monster.x, + monster.y, + TILE, + TILE + ) + ) + reduceHitpoints(monster, bullet.damage), + sfx.explode.play(), + destroyBullet(bullet) + } + } + if ( + (!bullet.directionLeft && + bullet.x > bullet.originX + ammoType.distance) || + (bullet.directionLeft && bullet.x < bullet.originX - ammoType.distance) + ) { + destroyBullet(bullet) + } + } +} + +function destroyBullet(bullet) { + const index = bullets.indexOf(bullet) + if (index > -1) { + bullets.splice(index, 1) + } +} + +function checkTreasure() { + var n, max, t + for (n = 0, max = treasure.length; n < max; n++) { + t = treasure[n] + if ( + !t.collected && + overlap(player.x, player.y, TILE, TILE, t.x, t.y, TILE, TILE) + ) + collectTreasure(t) + } +} + +function checkPickups() { + var n, max, p + for (n = 0, max = pickups.length; n < max; n++) { + p = pickups[n] + if ( + !p.collected && + overlap(player.x, player.y, TILE, TILE, p.x, p.y, TILE, TILE) + ) + collectPickup(p) + } +} + +function collectPickup(p) { + // console.log('log pickup ', p) + + if (p.extralife) { + addExtraLife(p) + } + if (p.ammo) { + addAmmo(p) + } + if (p.health) { + addHitPoints(p) + } +} + +function addExtraLife(p) { + globalObject.lifes++ + p.collected = true + sfx.smb_powerup.play() +} + +function addHitPoints(p) { + if (globalObject.hitpoints < globalObject.maxHitpoints) { + globalObject.hitpoints++ + p.collected = true + sfx.stomp.play() + } +} + +function addAmmo(p) { + if (globalObject.ammo < globalObject.maxAmmo) { + globalObject.ammo++ + p.collected = true + sfx.kick.play() + } +} + +function checkLiquids() { + var n, max, l + for (n = 0, max = liquids.length; n < max; n++) { + l = liquids[n] + if (overlap(player.x, player.y, TILE, TILE, l.x, l.y, l.width, l.height)) { + !player.swimming && sfx.splash.play() + player.dy = player.dy / 1.15 + if (!player.swimming) player.jumping = false + player.swimming = true + } else { + player.swimming = false + } + } +} + +function checkDoors() { + // ! Hier habe ich rudimentär einen Levelwechsel eingebaut. + // ! Was noch fehlt ist, dass ein globales Player-Objekt beibehalten wird. + var n, max, t + for (n = 0, max = doors.length; n < max; n++) { + t = doors[n] + if ( + overlap( + player.x, + player.y, + TILE * 2, + TILE * 2, + t.x, + t.y, + TILE * 2, + TILE * 2 + ) + ) + player.interact && useDoor(t) + } +} + +function useDoor(t) { + let leadsTo + switch (t.leadsTo) { + case 'level1': + leadsTo = levelObject.level1 + break + case 'level2': + leadsTo = levelObject.level2 + break + case 'level3': + leadsTo = levelObject.level3 + break + } + sfx.openDoor.play() + levelTransition(leadsTo) +} + +function levelTransition(level) { + setTimeout(() => { + _initLevel(level) + }, 800) +} + +function killMonster(monster) { + globalObject.killed++ + monster.dead = true + sfx.killMonster.play() +} + +// * Take Damage Function +function reduceHitpoints(entity, damage) { + if ( + entity.player ? globalObject.hitpoints > 1 : entity.currentHitpoints > 1 + ) { + entity.player + ? (globalObject.hitpoints -= damage) + : (entity.currentHitpoints -= damage) + entity.vul = false + entity.hurt = true + sfx.takeDamage.play() + setTimeout(() => { + entity.vul = true + entity.hurt = false + }, 1500) + } else killEntity(entity) +} + +function killEntity(entity) { + console.log('killEntity: ', entity) + if (entity.player === true) { + killPlayer(entity) + } + if (entity.monster === true) { + killMonster(entity) + } +} + +function killPlayer(player) { + sfx.die.play() + player.x = player.start.x + player.y = player.start.y + player.dx = player.dy = 0 + globalObject.hitpoints = player.maxHitpoints + globalObject.lifes-- + console.log('log globalObject: ', globalObject.lifes) +} + +function collectTreasure(t) { + globalObject.collected++ + t.collected = true + sfx.pickup.play() +} + +function updateEntity(entity, dt) { + var wasleft = entity.dx < 0, + wasright = entity.dx > 0, + falling = entity.falling, + swimming = entity.swimming || false, + friction = + entity.friction * (falling && !swimming ? 0.5 : swimming ? 0.1 : 1), + impulse = entity.impulse, + swimImpulse = entity.impulse / 3, + accel = entity.accel * (falling && !swimming ? 0.5 : swimming ? 0.1 : 1), + gravity = swimming ? METER * 8 : METER * GRAVITY + + entity.ddx = 0 + entity.ddy = gravity // ! Hier wir gravity angewandt + + // * Hier wird die Entity bewegt. + if (entity.left) (entity.ddx = entity.ddx - accel), (entity.flipped = true) + else if (wasleft) entity.ddx = entity.ddx + friction + + if (entity.right) (entity.ddx = entity.ddx + accel), (entity.flipped = false) + else if (wasright) entity.ddx = entity.ddx - friction + + if (entity.jump) { + if (!entity.jumping && !falling && !swimming) { + jump(entity) + } else if (!entity.jumping && swimming) { + swim(entity) + } + } + + function jump(entity) { + sfx.jump.play() + entity.ddy = entity.ddy - impulse // an instant big force impulse + entity.jumping = true + } + + function swim(entity) { + sfx.swim.play() + entity.ddy = entity.down + ? entity.ddy + swimImpulse + : entity.up + ? entity.ddy - swimImpulse * 2 + : entity.ddy - swimImpulse + entity.jumping = true + setTimeout(() => { + entity.jumping = false + }, 400) + } + + // ! "dt" ist hier identisch mit "step", was in der index.js in die update() gegeben wird. Konstant bei ca. 0.01666 + //console.log('log entity.x + dt * entity.dx: ', player.x + dt * player.dx) + + entity.x = entity.x + dt * entity.dx + entity.y = entity.y + dt * entity.dy + entity.dx = bound(entity.dx + dt * entity.ddx, -entity.maxdx, entity.maxdx) + entity.dy = bound(entity.dy + dt * entity.ddy, -entity.maxdy, entity.maxdy) + + if ((wasleft && entity.dx > 0) || (wasright && entity.dx < 0)) { + entity.dx = 0 // clamp at zero to prevent friction from making us jiggle side to side + } + + var tx = p2t(entity.x), + ty = p2t(entity.y), + nx = entity.x % TILE, + ny = entity.y % TILE, + cell = tcell(tx, ty, mapWidth), //! Was ist das hier? + cellright = tcell(tx + 1, ty, mapWidth), + celldown = tcell(tx, ty + 1, mapWidth), + celldiag = tcell(tx + 1, ty + 1, mapWidth) + + // ? Ist das hier der Collision Check? + + if (entity.dy > 0) { + if ((celldown && !cell) || (celldiag && !cellright && nx)) { + entity.y = t2p(ty) + entity.dy = 0 + entity.falling = false + entity.jumping = false + ny = 0 + } + } else if (entity.dy < 0) { + if ((cell && !celldown) || (cellright && !celldiag && nx)) { + entity.y = t2p(ty + 1) + entity.dy = 0 + cell = celldown + cellright = celldiag + ny = 0 + } + } + + if (entity.dx > 0) { + if ((cellright && !cell) || (celldiag && !celldown && ny)) { + entity.x = t2p(tx) + entity.dx = 0 + } + } else if (entity.dx < 0) { + if ((cell && !cellright) || (celldown && !celldiag && ny)) { + entity.x = t2p(tx + 1) + entity.dx = 0 + } + } + + if (entity.monster || entity.slimeMonster) { + if (entity.left && (cell || !celldown)) { + entity.left = false + entity.right = true + } else if (entity.right && (cellright || !celldiag)) { + entity.right = false + entity.left = true + } + } + + entity.falling = !(celldown || (nx && celldiag)) +} diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 0000000..94b96c2 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,165 @@ +//------------------------------------------------------------------------- +// 1. UTILITIES +//------------------------------------------------------------------------- + +function timestamp() { + return window.performance && window.performance.now + ? window.performance.now() + : new Date().getTime() +} + +function bound(x, min, max) { + return Math.max(min, Math.min(max, x)) +} + +/* function get(url, onsuccess) { + var request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (request.readyState == 4 && request.status == 200) onsuccess(request); + }; + request.open("GET", url, true); + request.send(); + } */ + +function overlap(x1, y1, w1, h1, x2, y2, w2, h2) { + return !( + x1 + w1 - 1 < x2 || + x2 + w2 - 1 < x1 || + y1 + h1 - 1 < y2 || + y2 + h2 - 1 < y1 + ) +} + +// * SFX function +function sound(src, volume) { + this.sound = document.createElement('audio') + this.sound.src = src + this.sound.setAttribute('preload', 'auto') + this.sound.setAttribute('controls', 'none') + this.sound.style.display = 'none' + document.body.appendChild(this.sound) + this.sound.volume = volume + this.play = function () { + this.sound.play() + } + this.stop = function () { + this.sound.pause() + } +} + +// * Music function +function music(src, volume) { + this.music = document.createElement('audio') + this.music.src = src + this.music.setAttribute('preload', 'auto') + this.music.setAttribute('controls', 'none') + this.music.setAttribute('loop', 'loop') + this.music.style.display = 'none' + document.body.appendChild(this.music) + this.music.volume = volume + this.play = function () { + this.music.play() + } + this.stop = function () { + this.music.pause() + } +} + +// * Pause function +function togglePause() { + console.log('log togglePause', paused) + if (!paused) { + paused = true + } else if (paused) { + paused = false + } +} + +function toggleDevInfos() { + if (!showDevInfo) { + showDevInfo = true + } else if (showDevInfo) { + showDevInfo = false + } +} + +function renderHudSprites() { + const hudObject = { + player_hitpoints: player.currentHitpoints, + player_collected: player.collected, + player_lifes: globalObject.lifes, + player_ammo: globalObject.ammo, + } + + function hitpoints() { + ctx.save() + ctx.scale(scalingFactor / 4, scalingFactor / 4) + ctx.textAlign = 'left' + ctx.font = '12px C64 TrueType' + + ctx.fillStyle = 'white' + ctx.fillText(`lifes: ${hudObject.player_lifes}`, 50, 50) + ctx.fillText(`ammo: ${hudObject.player_ammo}`, 200, 50) + ctx.restore() + } + hitpoints() +} + +// * Renderfunktion für DevInfos +function renderDevInfos() { + ctx.save() + ctx.scale(scalingFactor / 6, scalingFactor / 6) + if (showDevInfo) { + const backgroundColor = 'rgba(18, 64, 90, 0.15)' + const color = 'white' + const lineHeight = 18 + + const devObject = { + player_accel: player.accel, + player_ddx: player.ddx, + player_ddy: player.ddy, + player_dx: player.dx, + player_dy: player.dy, + player_interact: player.interact, + player_falling: player.falling, + player_friction: player.friction, + player_gravity: player.gravity, + player_impulse: player.impulse, + player_jumping: player.jumping, + player_swimming: player.swimming, + player_shooting: player.shooting, + player_left: player.left, + player_maxdx: player.maxdx, + player_maxdy: player.maxdy, + player_right: player.right, + player_x: player.x, + player_y: player.y, + player_vul: player.vul, + player_hurt: player.hurt, + player_flipped: player.flipped, + canvas_width: canvas.height, + cameraWithBox_x: cameraWithBox.position.x, + } + + const canvas_width = canvas.width + const canvas_height = canvas.height + + function text() { + ctx.textAlign = 'left' + ctx.font = '12px C64 TrueType' + for (const [index, [key, value]] of Object.entries( + Object.entries(devObject) + )) { + const newIndex = Number(index) + 1 + const newValue = typeof value === 'number' ? value.toFixed(2) : value + ctx.fillStyle = backgroundColor + ctx.fillRect(15, lineHeight * newIndex - 15, 500, lineHeight) + ctx.fillStyle = color + ctx.fillText(`${key}: ${newValue}`, 15, lineHeight * newIndex) + } + } + + text() + } + ctx.restore() +} diff --git a/js/variables.js b/js/variables.js new file mode 100644 index 0000000..030c677 --- /dev/null +++ b/js/variables.js @@ -0,0 +1,363 @@ +//------------------------------------------------------------------------- +// 2. GAME CONSTANTS AND VARIABLES +//------------------------------------------------------------------------- + +// ! Globales Test-Objekt +let globalObject = { + lifes: 3, + hitpoints: 3, + maxHitpoints: 5, + collected: null, + killed: null, + ammo: 10, + maxAmmo: 10, +} + +// * Import tiles and level map // + +const tileAtlas1 = new Image() +tileAtlas1.src = './img/tiles.png' + +const tileAtlas2 = new Image() +tileAtlas2.src = './img/Grotto-escape-2-files/PNG/environment-tiles.png' + +const tileAtlasBg = new Image() +tileAtlasBg.src = './img/Grotto-escape-2-files/PNG/environment-background.png' + +let tileSize = 16 +let tileOutputSize = 2 // can set to 1 for 32px or higher + +const level1Atlas = { + tileAtlas: tileAtlas1, + offset: 1, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 8, + atlasRow: 5, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +const level2Atlas = { + tileAtlas: tileAtlas2, + offset: 1, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 42, + atlasRow: 16, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +const backgroundAtlas = { + tileAtlas: tileAtlasBg, + offset: 673, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 28, + atlasRow: 10, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +// * end of Import tiles and level map // + +// * Test Sprite Imports + +const playerSpriteAtlas = new Image() +playerSpriteAtlas.src = './img/player.png' + +const playerAtlas = { + tileAtlas: playerSpriteAtlas, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 4, + atlasRow: 2, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +const enemySpriteAtlas = new Image() +enemySpriteAtlas.src = './img/enemies.png' + +const enemyAtlas = { + tileAtlas: enemySpriteAtlas, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 4, + atlasRow: 3, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +const itemsSpriteAtlas = new Image() +itemsSpriteAtlas.src = './img/items.png' + +const itemsAtlas = { + tileAtlas: itemsSpriteAtlas, + tileSize: 16, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 4, + atlasRow: 4, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +const meterSpriteAtlas = new Image() +meterSpriteAtlas.src = './img/meter.png' + +const meterAtlas = { + tileAtlas: meterSpriteAtlas, + tileSize: 7, + tileOutputSize: 2, + updatedTileSize: tileSize * tileOutputSize, + atlasCol: 4, + atlasRow: 6, + mapIndex: 0, + sourceX: 0, + sourceY: 0, +} + +// * End Test Sprite Imports + +// * Das currentLevel Objekt sollte durch irgendeine Funktion befüllt werden, wenn ein Level gewechselt wird. + +let levelObject = { + level1: { + scalingFactor: 8, + levelData: level1, + levelAtlas: level2Atlas, + backgroundAtlas: backgroundAtlas, + foregroundAtlas: level2Atlas, + playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt. + }, + level2: { + scalingFactor: 4, + levelData: level2, + levelAtlas: level2Atlas, + backgroundAtlas: backgroundAtlas, + foregroundAtlas: level2Atlas, + playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt. + }, + level3: { + scalingFactor: 8, + levelData: level3, + levelAtlas: level2Atlas, + backgroundAtlas: backgroundAtlas, + foregroundAtlas: level2Atlas, + playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt. + }, +} + +let currentLevel = levelObject.level1 // ! hier kann ich noch eine function draus machen, die das currentLevel immer auf dem aktuellen Stand hält. Vorläufig erstmal mit einem Button-Press + +let mapWidth = currentLevel.levelData.width +let mapHeight = currentLevel.levelData.height + +let MAP = { tw: mapWidth, th: mapHeight } +let TILE = 16 +let METER = TILE + +let GRAVITY = 60 + +let MAXDX = 15, // * default max horizontal speed (15 tiles per second) + MAXDY = 60, // * default max vertical speed (60 tiles per second) + ACCEL = 1 / 2, // * default take 1/2 second to reach maxdx (horizontal acceleration) + FRICTION = 1 / 6, // * default take 1/6 second to stop from maxdx (horizontal friction) + IMPULSE = 1500, // * default player jump impulse + COLOR = { + BLACK: '#000000', + YELLOW: '#ECD078', + BRICK: '#D95B43', + PINK: '#C02942', + PURPLE: '#542437', + GREY: '#333', + SLATE: '#53777A', + GOLD: 'gold', + }, + COLORS = [COLOR.YELLOW, COLOR.BRICK, COLOR.PINK, COLOR.PURPLE, COLOR.GREY], + KEY = { + SPACE: ' ', + LEFT: 'ArrowLeft', + UP: 'ArrowUp', + RIGHT: 'ArrowRight', + DOWN: 'ArrowDown', + PAUSE: 'p', + ENTER: 'Enter', + X: 'x', + Y: 'y', + L: 'l', + } + +const ammoType = { + width: 4, + height: 4, + distance: 100, + velocity: 3, +} + +let fps = 60, + step = 1 / fps, + canvas = document.getElementById('canvas'), + ctx = canvas.getContext('2d'), + player = {}, + monsters = [], + pickups = [], + treasure = [], + doors = [], // ! Hier sammel ich alle Door Objekte. + liquids = [], // ! Alle Bereich, die mit Wasser gefüllt sind. + bullets = [], + cells = [], // ! vielleicht kann ich hieraus aber auch einfach ein Objekt machen, das Arrays für collCells, bgCells und fgCells beinhaltet + bgCells = [], // * Die sind für die background cells. + fgCells = [], // * Die sind für die foreground cells. + lqCells = [], + paused = false, + showDevInfo = false + +canvas.width = mapWidth * TILE +canvas.height = mapHeight * TILE + +let width = (canvas.width = mapWidth * TILE) // * Das ist clever, weil ich so der Canvas immer von der Map Size abhängig ist. Zusammen mit ctx.scale und ctx.translate bekomme ich so auch eine Camera hin! +let height = (canvas.height = mapHeight * TILE) + +let scalingFactor = currentLevel.scalingFactor // * 8 fühlt sich ungefähr nach 8bit Grafik an. + +let scaledCanvas = { + width: canvas.width / scalingFactor, + height: canvas.height / scalingFactor, +} + +let t2p = function (t) { + return t * TILE + }, + p2t = function (p) { + return Math.floor(p / TILE) + }, + cell = function (x, y) { + return tcell(p2t(x), p2t(y), mapWidth) + }, + tcell = function (tx, ty, mapWidth) { + // ! Hier brauche ich entweder eine allgemeinere Funktion oder noch weiter für bgCells ud fgCells. + return cells[tx + ty * mapWidth] + }, + bgTcell = function (tx, ty, mapWidth) { + return bgCells[tx + ty * mapWidth] + }, + fgTcell = function (tx, ty, mapWidth) { + return fgCells[tx + ty * mapWidth] + }, + lqTcell = function (tx, ty, mapWidth) { + return !!lqCells && lqCells[tx + ty * mapWidth] + } + +// * Init Level Funtion +function _initLevel(newLevel) { + monsters = [] + treasure = [] + pickups = [] + doors = [] + liquids = [] + cells = [] + currentLevel = newLevel + player.collected = 0 + + mapWidth = currentLevel.levelData.width + mapHeight = currentLevel.levelData.height + + canvas.width = mapWidth * TILE + canvas.height = mapHeight * TILE + + scalingFactor = currentLevel.scalingFactor + + scaledCanvas = { + width: canvas.width / scalingFactor, + height: canvas.height / scalingFactor, + } + + setup(newLevel.levelData) +} + +// * Const Sfx from audio files // +// ! Achtung: utils müssen in index.html vor den variables geladen werden. + +let sfxVolume = 0.2 +let musicVolume = 0.5 + +let sfx = { + jump: new sound('./audio/Jump.wav', sfxVolume), + pickup: new sound('./audio/Pickup_Coin.wav', sfxVolume), + lowHealth: new sound('./audio/LA_LowHealth.wav', sfxVolume), + die: new sound('./audio/Explosion.wav', sfxVolume), + takeDamage: new sound('./audio/Randomize3.wav', sfxVolume), + killMonster: new sound('./audio/Randomize.wav', sfxVolume), + powerup: new sound('./audio/Powerup.wav', sfxVolume), + openDoor: new sound('./audio/LA_Chest_Open.wav', sfxVolume), + shoot: new sound('./audio/Laser2.wav', sfxVolume), + explode: new sound('./audio/Explosion.wav', sfxVolume), + splash: new sound('./audio/Oracle_Rock_Shatter.wav', sfxVolume), + swim: new sound('./audio/SML2_Swim.ogg', sfxVolume), + click: new sound('./audio/click.wav', sfxVolume), + + stomp: new sound('./audio/smb_stomp.wav', sfxVolume), + kick: new sound('./audio/smb_kick.wav', sfxVolume), + extraLife: new sound('./audio/smb_1-up.wav', sfxVolume), + smb_powerup: new sound('./audio/smb_powerup.wav', sfxVolume), +} + +let theme = { + level1: new music('./audio/music/8BitCave.wav', musicVolume), +} + +let globalPlayer = { + collected: 0, + killed: 0, + maxHitpoints: 5, + currentHitpoints: 3, + vul: true, + hurt: false, + interact: false, + shooting: false, + swimming: false, + sprites: { + idle: { + tiles: [5], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + run: { + tiles: [0, 1, 2, 1], + framerate: 5, + framebuffer: 10, + loop: true, + currentFrame: 0, + }, + jump: { + tiles: [4], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + shoot: { + tiles: [3], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} diff --git a/levels/level1.js b/levels/level1.js new file mode 100644 index 0000000..ed97b55 --- /dev/null +++ b/levels/level1.js @@ -0,0 +1,1133 @@ +const level1 = { + compressionlevel: -1, + height: 48, + infinite: false, + layers: [ + { + data: [ + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 894, 895, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 922, 923, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 894, 895, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 775, 776, + 777, 778, 779, 673, 673, 673, 922, 923, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 762, 763, 764, 765, 766, + 767, 768, 769, 770, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 803, 804, 805, 806, 807, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 790, 791, 792, 793, 794, 795, 796, 797, 798, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 831, 832, 833, 834, 835, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 818, 819, 820, + 821, 822, 823, 824, 825, 826, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 859, 860, 861, 862, 863, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 846, 847, 848, 849, 850, 851, 852, 853, 854, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 887, 888, 889, 890, 891, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 874, + 875, 876, 877, 878, 879, 880, 881, 882, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 915, 916, 917, 918, + 919, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 902, 903, 904, 905, 906, 907, 908, + 909, 910, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, + ], + height: 48, + id: 4, + name: 'background', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 64, + x: 0, + y: 0, + }, + { + data: [ + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, + 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 516, 516, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, + 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 0, 0, + 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, + 214, 214, 214, 214, 214, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 0, 0, 0, 0, 0, 0, 0, 172, + 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, + 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 89, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 214, 214, 214, 214, 214, 214, 214, 214, 214, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, + 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 516, + 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, + 214, 214, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, + 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, 594, 516, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, + 172, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 516, 516, 516, 516, 516, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, + 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 516, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, + 594, 594, 594, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 516, 594, 594, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 516, 0, 0, 0, 0, 0, + 0, 0, 516, 516, 516, 516, 516, 594, 594, 594, 516, 516, 516, 516, 516, + 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, + 516, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 516, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 172, 172, 172, 172, 0, 0, 0, 516, 594, 594, 516, 0, 0, 0, 0, + 0, 0, 0, 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, + 594, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 516, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, 516, 516, 516, 516, + 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 516, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + ], + height: 48, + id: 1, + name: 'tileLayer', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 64, + x: 0, + y: 0, + }, + { + draworder: 'topdown', + id: 2, + name: 'Object Layer 1', + objects: [ + { + class: 'monster', + height: 16.0022, + id: 2, + name: 'monster', + properties: [ + { + name: 'maxdx', + type: 'string', + value: '10', + }, + { + name: 'right', + type: 'string', + value: 'true', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 31.7055, + y: 95.0211, + }, + { + class: 'monster', + height: 16.0022, + id: 3, + name: 'monster', + properties: [ + { + name: 'left', + type: 'string', + value: 'true', + }, + { + name: 'maxdx', + type: 'string', + value: '4', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 559.778, + y: 207.037, + }, + { + class: 'monster', + height: 16.0022, + id: 4, + name: 'monster', + properties: [ + { + name: 'left', + type: 'string', + value: 'true', + }, + { + name: 'maxdx', + type: 'string', + value: '4', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 815.813, + y: 415.065, + }, + { + class: 'monster', + height: 16.0022, + id: 5, + name: 'monster', + properties: [ + { + name: 'maxdx', + type: 'string', + value: '6', + }, + { + name: 'right', + type: 'string', + value: 'true', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 527.773, + y: 655.098, + }, + { + class: 'monster', + height: 16.0022, + id: 6, + name: 'monster', + properties: [ + { + name: 'left', + type: 'string', + value: 'true', + }, + { + name: 'maxdx', + type: 'string', + value: '4', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 319.745, + y: 495.076, + }, + { + class: 'treasure', + height: 16.0022, + id: 7, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 95.7142, + y: 431.067, + }, + { + class: 'treasure', + height: 16.0022, + id: 8, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 47.7077, + y: 655.098, + }, + { + class: 'treasure', + height: 16.0022, + id: 9, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 927.828, + y: 191.034, + }, + { + class: 'treasure', + height: 16.0022, + id: 10, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 351.749, + y: 207.037, + }, + { + class: 'treasure', + height: 16.0022, + id: 11, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 991.837, + y: 95.0211, + }, + { + class: 'treasure', + height: 16.0022, + id: 12, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 303.743, + y: 575.087, + }, + { + class: 'monster', + height: 16.0022, + id: 13, + name: 'slimeMonster', + properties: [ + { + name: 'maxdx', + type: 'string', + value: '1', + }, + { + name: 'right', + type: 'string', + value: 'true', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 607.784, + y: 367.058, + }, + { + class: 'monster', + height: 16.0022, + id: 14, + name: 'monster', + properties: [ + { + name: 'maxdx', + type: 'string', + value: '2', + }, + { + name: 'right', + type: 'string', + value: 'true', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 927.828, + y: 671.1, + }, + { + class: 'monster', + height: 16.0022, + id: 15, + name: 'monster', + properties: [ + { + name: 'left', + type: 'string', + value: 'true', + }, + { + name: 'maxdx', + type: 'string', + value: '4', + }, + ], + rotation: 0, + visible: true, + width: 16.0022, + x: 511.771, + y: 95.0211, + }, + { + class: 'treasure', + height: 16.0022, + id: 16, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 15.7033, + y: 95.0211, + }, + { + class: 'treasure', + height: 16.0022, + id: 17, + name: 'treasure', + rotation: 0, + visible: true, + width: 16.0022, + x: 991.837, + y: 671.1, + }, + { + class: 'door', + height: 34, + id: 18, + name: 'exit', + properties: [ + { + name: 'leadsTo', + type: 'string', + value: 'level2', + }, + ], + rotation: 0, + visible: true, + width: 30, + x: 240.359, + y: 334.171, + }, + { + class: 'player', + height: 16, + id: 19, + name: 'player', + rotation: 0, + visible: true, + width: 16, + x: 47.7058, + y: 239.099, + }, + { + class: 'water', + height: 82, + id: 21, + name: 'water', + rotation: 0, + visible: true, + width: 118, + x: 44.9091, + y: 592.364, + }, + { + class: 'door', + height: 32, + id: 22, + name: 'exit', + properties: [ + { + name: 'leadsTo', + type: 'string', + value: 'level3', + }, + ], + rotation: 0, + visible: true, + width: 32, + x: 192.25, + y: 560, + }, + { + class: 'ammo', + height: 16, + id: 23, + name: 'ammo', + rotation: 0, + visible: true, + width: 16, + x: 464, + y: 415.75, + }, + { + class: 'health', + height: 16, + id: 24, + name: 'health', + rotation: 0, + visible: true, + width: 16, + x: 863.984, + y: 191.917, + }, + { + class: 'health', + height: 16, + id: 25, + name: 'health', + rotation: 0, + visible: true, + width: 16, + x: 639.75, + y: 367.75, + }, + { + class: 'health', + height: 16, + id: 26, + name: 'health', + rotation: 0, + visible: true, + width: 16, + x: 208.017, + y: 351.483, + }, + { + class: 'ammo', + height: 16, + id: 27, + name: 'ammo', + rotation: 0, + visible: true, + width: 16, + x: 144.028, + y: 351.645, + }, + { + class: 'extralife', + height: 16, + id: 28, + name: 'extralife', + rotation: 0, + visible: true, + width: 16, + x: 287.932, + y: 351.307, + }, + { + class: 'health', + height: 16, + id: 29, + name: 'health', + rotation: 0, + visible: true, + width: 16, + x: 176, + y: 351.375, + }, + ], + opacity: 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 117, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 120, 0, 246, 120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 483, 0, + 0, 485, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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: 48, + id: 3, + name: 'foreground', + opacity: 1, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, + 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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: 48, + id: 5, + name: 'liquids', + opacity: 0.5, + type: 'tilelayer', + visible: true, + width: 64, + x: 0, + y: 0, + }, + ], + nextlayerid: 6, + nextobjectid: 30, + orientation: 'orthogonal', + renderorder: 'left-down', + tiledversion: '1.9.2', + tileheight: 16, + tilesets: [ + { + firstgid: 1, + source: 'grotto.tsx', + }, + { + firstgid: 673, + source: 'Background.tsx', + }, + ], + tilewidth: 16, + type: 'map', + version: '1.9', + width: 64, +} diff --git a/levels/level2.js b/levels/level2.js new file mode 100644 index 0000000..dfcd613 --- /dev/null +++ b/levels/level2.js @@ -0,0 +1,278 @@ +const level2 = { + compressionlevel: -1, + height: 24, + infinite: false, + layers: [ + { + data: [ + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 894, 895, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 922, 923, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 762, 763, 764, 765, 766, 767, 768, 769, 770, 775, 776, + 777, 778, 779, 762, 763, 764, 765, 766, 767, 768, 769, 770, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 790, 791, 792, 793, 794, 795, 796, + 797, 798, 803, 804, 805, 806, 807, 790, 791, 792, 793, 794, 795, 796, + 797, 798, 673, 673, 673, 673, 673, 673, 673, 673, 673, 818, 819, 820, + 821, 822, 823, 824, 825, 826, 831, 832, 833, 834, 835, 818, 819, 820, + 821, 822, 823, 824, 825, 826, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 846, 847, 848, 849, 850, 851, 852, 853, 854, 859, 860, 861, 862, + 863, 846, 847, 848, 849, 850, 851, 852, 853, 854, 673, 673, 673, 673, + 673, 894, 895, 673, 673, 874, 875, 876, 877, 878, 879, 880, 881, 882, + 887, 888, 889, 890, 891, 874, 875, 876, 877, 878, 879, 880, 881, 882, + 673, 673, 673, 673, 673, 922, 923, 673, 673, 902, 903, 904, 905, 906, + 907, 908, 909, 910, 915, 916, 917, 918, 919, 902, 903, 904, 905, 906, + 907, 908, 909, 910, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + ], + height: 24, + id: 2, + name: 'background', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + { + data: [ + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 436, 437, 307, 308, 0, 0, 0, 307, 308, 0, 0, 307, 308, 0, 0, + 436, 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 478, 479, + 349, 350, 0, 0, 0, 349, 350, 0, 0, 349, 350, 0, 0, 478, 479, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 151, 147, 149, 151, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 276, 315, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, + 516, 153, 0, 0, 0, 204, 204, 76, 204, 204, 76, 204, 204, 204, 516, 516, + 0, 0, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 404, 406, 516, 516, + 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 445, 446, 448, 516, 516, 88, 89, 0, 0, 0, 516, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, + ], + height: 24, + id: 1, + name: 'tileLayer', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + { + draworder: 'topdown', + id: 4, + name: 'Object Layer 1', + objects: [ + { + class: 'player', + height: 16, + id: 2, + name: 'player', + rotation: 0, + visible: true, + width: 16, + x: 48, + y: 64, + }, + { + class: 'treasure', + height: 16, + id: 3, + name: 'treasure', + rotation: 0, + visible: true, + width: 16, + x: 352, + y: 64, + }, + { + class: 'door', + height: 32, + id: 4, + name: 'exit', + properties: [ + { + name: 'leadsTo', + type: 'string', + value: 'level1', + }, + ], + rotation: 0, + visible: true, + width: 32, + x: 16.3333, + y: 335.667, + }, + { + class: 'treasure', + height: 16, + id: 6, + name: 'treasure', + rotation: 0, + visible: true, + width: 16, + x: 320, + y: 304, + }, + { + class: 'monster', + height: 16, + id: 8, + name: 'monster', + properties: [ + { + name: 'left', + type: 'string', + value: 'true', + }, + { + name: 'maxdx', + type: 'string', + value: '4', + }, + ], + rotation: 0, + visible: true, + width: 16, + x: 256, + y: 207.333, + }, + ], + opacity: 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, 315, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 318, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 81, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, + 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 0, 485, 0, 328, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, + 412, 0, 0, 0, 0, 0, 0, 0, 246, 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 454, 0, 485, 0, 0, 0, 105, 0, 0, 0, 454, + 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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: 24, + id: 3, + name: 'foreground', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + ], + nextlayerid: 6, + nextobjectid: 9, + orientation: 'orthogonal', + renderorder: 'left-down', + tiledversion: '1.9.2', + tileheight: 16, + tilesets: [ + { + firstgid: 1, + source: 'grotto.tsx', + }, + { + firstgid: 673, + source: 'Background.tsx', + }, + ], + tilewidth: 16, + type: 'map', + version: '1.9', + width: 32, +} diff --git a/levels/level3.js b/levels/level3.js new file mode 100644 index 0000000..0c24f37 --- /dev/null +++ b/levels/level3.js @@ -0,0 +1,562 @@ +const level3 = { + compressionlevel: -1, + height: 64, + infinite: false, + layers: [ + { + data: [ + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 894, 895, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 922, 923, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, + ], + height: 64, + id: 4, + name: 'background', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + { + data: [ + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 46, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 516, 516, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 539, 540, 541, + 542, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 581, 582, 583, 584, 0, 0, 0, 0, 0, 0, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, + 0, 539, 540, 541, 542, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 581, 582, 583, 584, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 539, 540, 541, + 542, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 581, 582, 583, 584, 0, 0, 0, 0, 0, 0, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, + 0, 539, 540, 541, 542, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 581, 582, 583, 584, 516, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 594, 594, 594, 594, 594, 594, 594, + 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, 594, 594, 594, + 594, 516, 539, 540, 541, 542, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, 594, 594, + 594, 594, 516, 581, 582, 583, 584, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, 594, + 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 539, 540, 541, 542, 516, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, 594, + 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 581, 582, 583, 584, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, 594, + 594, 594, 594, 594, 594, 516, 539, 540, 541, 542, 0, 0, 0, 0, 0, 0, 516, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, 594, + 594, 594, 594, 594, 594, 594, 516, 581, 582, 583, 584, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 594, + 594, 594, 594, 594, 594, 594, 594, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 516, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, + ], + height: 64, + id: 1, + name: 'tileLayer', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + { + draworder: 'topdown', + id: 2, + name: 'Object Layer 1', + objects: [ + { + class: 'water', + height: 527.023754075454, + id: 1, + name: 'water', + rotation: 0, + visible: true, + width: 178.854215183978, + x: 150.237540754541, + y: 490.060549604099, + }, + { + class: 'door', + height: 32, + id: 2, + name: 'exit', + properties: [ + { + name: 'leadsTo', + type: 'string', + value: 'level1', + }, + ], + rotation: 0, + visible: true, + width: 32, + x: 15.75, + y: 448, + }, + { + class: 'player', + height: 16, + id: 3, + name: 'player', + rotation: 0, + visible: true, + width: 16, + x: 159.666666666667, + y: 384.333333333333, + }, + ], + opacity: 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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: 64, + id: 3, + name: 'foreground', + opacity: 1, + type: 'tilelayer', + visible: true, + width: 32, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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: 64, + id: 5, + name: 'liquids', + opacity: 0.5, + type: 'tilelayer', + visible: true, + width: 32, + x: 0, + y: 0, + }, + ], + nextlayerid: 6, + nextobjectid: 4, + orientation: 'orthogonal', + renderorder: 'left-down', + tiledversion: '1.9.2', + tileheight: 16, + tilesets: [ + { + firstgid: 1, + source: 'grotto.tsx', + }, + { + firstgid: 673, + source: 'Background.tsx', + }, + ], + tilewidth: 16, + type: 'map', + version: '1.9', + width: 32, +} diff --git a/levels/levelObjects.js b/levels/levelObjects.js new file mode 100644 index 0000000..6d92e63 --- /dev/null +++ b/levels/levelObjects.js @@ -0,0 +1,138 @@ +let playerObject = { + maxHitpoints: 5, + currentHitpoints: 3, + vul: true, + hurt: false, + sprites: { + idle: { + tiles: [5], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + run: { + tiles: [0, 1, 2, 1], + framerate: 5, + framebuffer: 10, + loop: true, + currentFrame: 0, + }, + jump: { + tiles: [4], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + shoot: { + tiles: [3], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let bounderMonster = { + class: 'monster', + currentHitpoints: 2, + sprites: { + idle: { + tiles: [3], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + run: { + tiles: [4, 5, 6], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let slimeMonster = { + class: 'monster', + currentHitpoints: 1, + sprites: { + idle: { + tiles: [0], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + run: { + tiles: [0, 1, 2], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let coinTreasure = { + sprites: { + idle: { + tiles: [4, 5, 6, 7], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let simpleBullet = { + sprites: { + idle: { + tiles: [8, 9, 10], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let ammo = { + sprites: { + idle: { + tiles: [11], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let extralife = { + sprites: { + idle: { + tiles: [13], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} + +let health = { + sprites: { + idle: { + tiles: [0, 1, 2], + framerate: 5, + framebuffer: 8, + loop: true, + currentFrame: 0, + }, + }, +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..3e0bb3c --- /dev/null +++ b/style.css @@ -0,0 +1,143 @@ +:root { + --shell-color: #272929; + --button-color: #010105; + --text-color: #42683e; + --start-button-color: #597ea7; +} + + +@font-face { + font-family: "C64 TrueType"; + src: url('fonts/C64_Pro_Mono-STYLE.eot'); + src: url('fonts/C64_Pro_Mono-STYLE.eot') format('embedded-opentype'), + url('fonts/C64_Pro_Mono-STYLE.woff2') format('woff2'), + url('fonts/C64_Pro_Mono-STYLE.woff') format('woff'), + url('fonts/C64_Pro_Mono-STYLE.ttf') format('truetype'); +} + +body { + background: var(--shell-color); +} + +.controls-wrapper { + display: none; +} + +.dpad-wrapper { + background-color: darkgray; + border-radius: 50%; + height: 180px; + width: 180px; + display: flex; + flex-direction: column; + padding: 20px; + justify-content: center; +} +.dpad-top-bottom { + margin-left: auto; + margin-right: auto; +} +.dpad-middle { + display: flex; + justify-content: space-between; + width: 100%; + margin-left: auto; + margin-right: auto; +} +.dpad-button { + background-color: #4caf50; + border: none; + color: white; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + cursor: pointer; + width: 50px; + height: 50px; + margin: 4px; +} + +.button { + background-color: var(--button-color); + border: none; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin: 4px 2px; + cursor: pointer; + width: 80px; + height: 80px; + border-radius: 50%; + margin: auto; +} +.buttons-wrapper { + background-color: var(--shell-color); + border-radius: 60px; + height: 100px; + width: 240px; + display: flex; + padding: 10px; +} + +#platformer { + margin: 1em auto; + position: relative; + width: 512px; + height: 384px; +} +#canvas { + display: inline-block; + width: 100%; + height: 100%; + background: black; +} +#instructions { + font-style: italic; + color: #999; + font-size: 9pt; + margin-left: 1em; + margin-top: 0.5em; +} +#instructions b { + color: #ddd; +} +@media screen and (min-width: 0px) and (min-height: 0px) { + #platformer { + width: 512px; + height: 384px; + font-size: 7pt; + } +} /* block = 16 */ + +@media screen and (min-width: 840px) and (min-height: 530px) { + #platformer { + width: 640px; + height: 480px; + font-size: 9pt; + } +} /* block = 20 */ +@media screen and (min-width: 968px) and (min-height: 626px) { + #platformer { + width: 768px; + height: 576px; + font-size: 11pt; + } +} /* block = 24 */ +@media screen and (min-width: 1096px) and (min-height: 722px) { + #platformer { + width: 896px; + height: 672px; + font-size: 13pt; + } +} /* block = 28 */ +@media screen and (min-width: 1224px) and (min-height: 818px) { + #platformer { + width: 1024px; + height: 768px; + font-size: 15pt; + } +} /* block = 32 */