From 6361a6c539ef39c2233d127e89a1a24c44d1e3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Baumg=C3=A4rtner?= Date: Tue, 30 Jul 2024 20:56:24 +0200 Subject: [PATCH] initial commit, walkable and idling character, first map with collision --- .gitignore | 7 ++ DirectionInput.js | 37 ++++++++ GameObject.js | 22 +++++ Overworld.js | 47 ++++++++++ OverworldMap.js | 123 +++++++++++++++++++++++++ Person.js | 62 +++++++++++++ Sprite.js | 102 ++++++++++++++++++++ images/characters/people/hero-idle.png | Bin 0 -> 3764 bytes images/characters/people/hero-run.png | Bin 0 -> 5356 bytes images/characters/people/hero.png | Bin 0 -> 15282 bytes images/characters/shadow.png | Bin 0 -> 1439 bytes images/maps/floor-test.jpg | Bin 0 -> 115468 bytes images/maps/map-room-entrance.png | Bin 0 -> 3311 bytes images/maps/room-builder.png | Bin 0 -> 11307 bytes index.html | 23 +++++ init.js | 8 ++ map-room-entrance.jpg | Bin 0 -> 115468 bytes style.css | 25 +++++ utils.js | 25 +++++ 19 files changed, 481 insertions(+) create mode 100644 .gitignore create mode 100644 DirectionInput.js create mode 100644 GameObject.js create mode 100644 Overworld.js create mode 100644 OverworldMap.js create mode 100644 Person.js create mode 100644 Sprite.js create mode 100644 images/characters/people/hero-idle.png create mode 100644 images/characters/people/hero-run.png create mode 100644 images/characters/people/hero.png create mode 100644 images/characters/shadow.png create mode 100644 images/maps/floor-test.jpg create mode 100644 images/maps/map-room-entrance.png create mode 100644 images/maps/room-builder.png create mode 100644 index.html create mode 100644 init.js create mode 100644 map-room-entrance.jpg create mode 100644 style.css create mode 100644 utils.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66982ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +Thumbs.db* + +*.afpub* +*.zip + +/tiles-paid +/modern-tiles_free diff --git a/DirectionInput.js b/DirectionInput.js new file mode 100644 index 0000000..fa2bf00 --- /dev/null +++ b/DirectionInput.js @@ -0,0 +1,37 @@ +class DirectionInput { + constructor() { + this.heldDirections = []; + + this.map = { + "ArrowUp": "up", + "KeyW": "up", + "ArrowDown": "down", + "KeyS": "down", + "ArrowLeft": "left", + "KeyA": "left", + "ArrowRight": "right", + "KeyD": "right", + } + } + + get direction() { + return this.heldDirections[0]; + } + + init() { + document.addEventListener("keydown", e => { + const dir = this.map[e.code]; + if (dir && this.heldDirections.indexOf(dir) === -1) { + this.heldDirections.unshift(dir); + } + }); + + document.addEventListener("keyup", e => { + const dir = this.map[e.code]; + const index = this.heldDirections.indexOf(dir); + if (index > -1) { + this.heldDirections.splice(index, 1); + } + }); + } +} \ No newline at end of file diff --git a/GameObject.js b/GameObject.js new file mode 100644 index 0000000..16cc04e --- /dev/null +++ b/GameObject.js @@ -0,0 +1,22 @@ +class GameObject { + constructor(config) { + this.isMounted = false; + this.x = config.x || 0; + this.y = config.y || 0; + this.direction = config.direction || "down"; + this.sprite = new Sprite({ + gameObject: this, + src: config.src || "/images/characters/people/hero.png", + + }); + } + + mount(map) { + this.isMounted = true; + map.addWall(this.x, this.y); + } + + update() { + + } +} \ No newline at end of file diff --git a/Overworld.js b/Overworld.js new file mode 100644 index 0000000..2a253d9 --- /dev/null +++ b/Overworld.js @@ -0,0 +1,47 @@ +class Overworld { + constructor(config) { + this.element = config.element; + this.canvas = this.element.querySelector(".game-canvas"); + this.ctx = this.canvas.getContext("2d"); + this.map = null; + } + + startGameLoop() { + const step = () => { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + const cameraPerson = this.map.gameObjects.hero; + + // update all objects + Object.values(this.map.gameObjects).forEach(object => { + object.update({ + arrow: this.directionInput.direction, + map: this.map, + }); + }) + + this.map.drawLowerImage(this.ctx, cameraPerson); + + Object.values(this.map.gameObjects).forEach(object => { + object.sprite.draw(this.ctx, cameraPerson); + }) + + this.map.drawUpperImage(this.ctx, cameraPerson); + + requestAnimationFrame(() => { + step(); + }) + } + step(); + } + + init() { + this.map = new OverworldMap(window.OverworldMaps.DemoRoom); + this.map.mountObjects(); + + this.directionInput = new DirectionInput(); + this.directionInput.init(); + + this.startGameLoop(); + } +} \ No newline at end of file diff --git a/OverworldMap.js b/OverworldMap.js new file mode 100644 index 0000000..7c1ccb3 --- /dev/null +++ b/OverworldMap.js @@ -0,0 +1,123 @@ +class OverworldMap { + constructor(config) { + this.gameObjects = config.gameObjects; + this.walls = config.walls || {}; + + this.lowerImage = new Image(); + this.lowerImage.src = config.lowerSrc; + + this.upperImage = new Image(); + this.upperImage.src = config.upperSrc; + } + + drawLowerImage(ctx, cameraPerson) { + ctx.drawImage(this.lowerImage, utils.withGrid(10.5) - cameraPerson.x, utils.withGrid(6) - cameraPerson.y); + } + + drawUpperImage(ctx, cameraPerson) { + ctx.drawImage(this.upperImage, utils.withGrid(10.5) - cameraPerson.x, utils.withGrid(6) - cameraPerson.y); + } + + isSpaceTaken(currentX, currentY, direction) { + const {x, y} = utils.nextPosition(currentX, currentY, direction); + return this.walls[`${x},${y}`] || false; + } + + mountObjects() { + Object.values(this.gameObjects).forEach(o => { + // todoL determine if this object should actually mount + + o.mount(this); + }) + } + + addWall(x, y) { + this.walls[`${x},${y}`] = true; + } + + removeWall(x, y) { + delete this.walls[`${x},${y}`]; + } + + moveWall(wasX, wasY, direction) { + this.removeWall(wasX, wasY); + const {x, y} = utils.nextPosition(wasX, wasY, direction); + this.addWall(x, y); + } +} + +window.OverworldMaps = { + DemoRoom: { + lowerSrc: "/images/maps/map-room-entrance.png", + upperSrc: "", + gameObjects: { + hero: new Person({ + isPlayerControlled: true, + x: utils.withGrid(8), + y: utils.withGrid(2), + }), + // npc1: new Person({ + // x: utils.withGrid(6), + // y: utils.withGrid(7), + // }) + }, + walls: { + // "16,16": true + [utils.asGridCoord(5,2)] : true, + [utils.asGridCoord(5,3)] : true, + [utils.asGridCoord(5,4)] : true, + [utils.asGridCoord(4,4)] : true, + [utils.asGridCoord(3,4)] : true, + [utils.asGridCoord(2,4)] : true, + [utils.asGridCoord(1,5)] : true, + [utils.asGridCoord(0,6)] : true, + [utils.asGridCoord(1,7)] : true, + [utils.asGridCoord(2,8)] : true, + [utils.asGridCoord(3,8)] : true, + [utils.asGridCoord(4,8)] : true, + [utils.asGridCoord(5,8)] : true, + [utils.asGridCoord(5,9)] : true, + [utils.asGridCoord(5,10)] : true, + [utils.asGridCoord(4,11)] : true, + [utils.asGridCoord(5,12)] : true, + [utils.asGridCoord(6,12)] : true, + [utils.asGridCoord(7,12)] : true, + [utils.asGridCoord(7,13)] : true, + [utils.asGridCoord(8,14)] : true, + [utils.asGridCoord(9,13)] : true, + [utils.asGridCoord(9,12)] : true, + [utils.asGridCoord(10,12)] : true, + [utils.asGridCoord(11,12)] : true, + [utils.asGridCoord(12,11)] : true, + [utils.asGridCoord(11,10)] : true, + [utils.asGridCoord(11,9)] : true, + [utils.asGridCoord(11,8)] : true, + [utils.asGridCoord(11,7)] : true, + [utils.asGridCoord(11,6)] : true, + [utils.asGridCoord(12,5)] : true, + [utils.asGridCoord(11,4)] : true, + [utils.asGridCoord(11,3)] : true, + [utils.asGridCoord(11,2)] : true, + [utils.asGridCoord(10,1)] : true, + [utils.asGridCoord(9,1)] : true, + [utils.asGridCoord(8,1)] : true, + [utils.asGridCoord(7,1)] : true, + [utils.asGridCoord(6,1)] : true, + } + }, + Kitchen: { + lowerSrc: "/images/maps/room-builder.png", + upperSrc: "/images/maps/room-builder.png", + gameObjects: { + hero: new GameObject({ + x: 2, + y: 3, + }), + npc1: new GameObject({ + x: 3, + y: 6, + src: "/images/characters/people/hero-run.png" + }) + } + } +} \ No newline at end of file diff --git a/Person.js b/Person.js new file mode 100644 index 0000000..b1b55a5 --- /dev/null +++ b/Person.js @@ -0,0 +1,62 @@ +class Person extends GameObject { + constructor(config) { + super(config); + this.movementProgressRemaining = 0; + + this.isPlayerControlled = config.isPlayerControlled || false; + + this.directionUpdate = { + "up": ["y", -1], + "down": ["y", 1], + "left": ["x", -1], + "right": ["x", 1], + } + } + + update(state) { + if (this.movementProgressRemaining > 0) { + this.updatePosition(); + } else { + + // more cases for starting to walk come here + + // case: keyboard ready and arrow pressed + if (this.isPlayerControlled && state.arrow) { + this.startBehavior(state, { + type: "walk", + direction: state.arrow + }) + } + this.updateSprite(state); + } + } + + startBehavior(state, behavior) { + // set character direction to behavior + this.direction = behavior.direction; + if (behavior.type === "walk") { + // stop if space is not free + if (state.map.isSpaceTaken(this.x, this.y, this.direction)) { + return; + } + + // ready to walk + state.map.moveWall(this.x, this.y, this.direction); + this.movementProgressRemaining = 16; + } + } + + updatePosition() { + const [property, change] = this.directionUpdate[this.direction]; + this[property] += change; + this.movementProgressRemaining -= 1; + } + + updateSprite() { + if (this.movementProgressRemaining > 0) { + this.sprite.setAnimation("walk-" + this.direction); + return; + } + this.sprite.setAnimation("idle-" + this.direction); + } +} \ No newline at end of file diff --git a/Sprite.js b/Sprite.js new file mode 100644 index 0000000..d5704fe --- /dev/null +++ b/Sprite.js @@ -0,0 +1,102 @@ +class Sprite { + constructor(config) { + // Setup image + this.image = new Image(); + this.image.src = config.src; + this.image.onload = () => { + this.isLoaded = true; + } + + // Shadow + this.shadow = new Image(); + this.useShadow = true; + if (this.useShadow) { + this.shadow.src = "/images/characters/shadow.png" + } + this.shadow.onload = () => { + this.isShadowLoaded = true; + } + + // Configure animation and initial state + this.animation = config.animation || { + "idle-up": [ + [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1] + ], + "idle-down": [ + [18, 1], [19, 1], [20, 1], [21, 1], [22, 1], [23, 1] + ], + "idle-left": [ + [12, 1], [13, 1], [14, 1], [15, 1], [16, 1], [17, 1] + ], + "idle-right": [ + [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1] + ], + "walk-up": [ + [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2] + ], + "walk-down": [ + [18, 2], [19, 2], [20, 2], [21, 2], [22, 2], [23, 2] + ], + "walk-left": [ + [12, 2], [13, 2], [14, 2], [15, 2], [16, 2], [17, 2] + ], + "walk-right": [ + [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2] + ], + } + this.currentAnimation = "idle-down"; // config.currentAnimation || "idle-down"; + this.currentAnimationFrame = 0; + + this.animationFrameLimit = config.animationFrameLimit || 6; + this.animationFrameProgress = this.animationFrameLimit; + + // Reference game object + this.gameObject = config.gameObject; + } + + get frame() { + return this.animation[this.currentAnimation][this.currentAnimationFrame] + } + + setAnimation(key) { + if (this.currentAnimation !== key) { + this.currentAnimation = key; + this.currentAnimationFrame = 0; + this.animationFrameProgress = this.animationFrameLimit; + } + } + + updateAnimationProgress() { + // downtick frame progress + if (this.animationFrameProgress > 0) { + this.animationFrameProgress -= 1; + return; + } + + // reset the counter + this.animationFrameProgress = this.animationFrameLimit; + this.currentAnimationFrame += 1; + + if (this.frame === undefined) { + this.currentAnimationFrame = 0; + } + } + + draw(ctx, cameraPerson) { + const x = this.gameObject.x + utils.withGrid(10.5) - cameraPerson.x; + const y = this.gameObject.y - 4 + utils.withGrid(6) - cameraPerson.y; + + this.isShadowLoaded && ctx.drawImage(this.shadow, x, y); + + const [frameX, frameY] = this.frame; + + this.isLoaded && ctx.drawImage(this.image, + frameX * 16, frameY * 32, + 16, 32, + x, y, + 16, 32 + ) + + this.updateAnimationProgress(); + } +} \ No newline at end of file diff --git a/images/characters/people/hero-idle.png b/images/characters/people/hero-idle.png new file mode 100644 index 0000000000000000000000000000000000000000..7c53b67c4e527044f52aaa31710a2fcaae454ff1 GIT binary patch literal 3764 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 HWF7K9YFvut literal 0 HcmV?d00001 diff --git a/images/characters/people/hero.png b/images/characters/people/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..d26ccd7e8fcc53d4edecef436202a570e11dd565 GIT binary patch literal 15282 zcma*Oc|4SF-#&g#QzUDVT|_Doh3s1?BoVS^FJzCh4>Q^<*|W=1M0OIg6S5mi*0F`L z@B1)jzUS2Ee(vXY|DHeY*GqA6&AFfF`*bokpwIB$F0zXfl zBm@7Sx?Q9RzQLYrDc^$fyVw^Xhzq)V`{qNB4=YJN_H5R^bG2zqs-G_3`8GeIWv}AK z&}x@gEfn)k5T5J4^!g{`oKox5OG?I^V~dPGZ`kpc<`11xJh$m~Gy!eN|a@Pl$sDJ&uekV#r`#F*-<@YlQ5q6iiUbi>) zU{pN~xURK5nXQgJ&)N9jR0?#*Z~nJmjRT5ioQ^M&k3mN96z>+JZEa;C)SAxg9DrB4V#h|?xk zjTb&8wl`YUCI~G&U)2@f+5J}CAa@w~>FqQi)WrOzMNKBrfqB8y3zwU*JD$sFcO6y~ z4(&_bUOWy8LUAjwdYXcET%sX+p~vn+r;uo;dM+uaoH3svtY5>{HXaAB+w#YM7p7+% zerj4BA~wjN#5q6bJY}Y!U0_WJ-n2L!-OuJxdj4cefnqTg7=|~uBR1u+O_4%Zs1HGX zdsaui^DLm)D@_VcFOnlOjlO-eTE|H>f|4LE#xq*qmPOh%JKGv~J3|}n5ihv{ZlxVZ z&CbiyPe0LCwkkn$MrOFAekc3rKTxX9PBq!)MDGQvLX@6=Dz#?K_EPlhZMxg_+Q*^# zR8#jS)R0}#lN1@}YvC^#>8K902d-OOy~xF^#$19PjOc~2I22UrtMwM6i^5UiwJLgS zn@pddlEyPSayv&Mnb6aK%~ld%IG){kKd<@LF{AwK?d$g)(b#Mc;W}cJnjh%6@juWQC;Ek{xwCq+{&hGa(xelL4lcixzNg(=C3l=bFUUoi3mYTlG02AFmp)$Ih2lE-sau6r${&B{ zB<|gd&f2{LX6VRt*wD}6ebckmXBX~M6j4^SQI^|gH?^fZTsChXk|ND+=e4dX=(zu=&}j@tdZeyOR0BOjm#X?Am5|X)=i# zI&F4KSZyJu)df<}=zIChWs(u~2#O2TeR38L8le>KQHXiaeEs((;+1H*d~K9VL}|57 zWi4w}v0r`#qtS=t_gjtlNIadijTc{0Rq>+DHu-E}fxriyanKu#A2*lhg^msesAAD@ z2A!ni3ZYhMx%t>wz{jWdd0uu9qNU=W43!!PSmN_5VlGg(;}*N`!=TZw%ThUuGsyZ> zP9Y`L4U2S!`c(M^=`xXobl#IMFW(M=%n)l!KaOzMR?(Nj0>-+&*vBldja8PtA7Js( zf4e2bUMEewGDScPZBLLMte0BdR|*~YAAdzt#mw!G4`Q1YJ|KTXf&v1qOO;8Q-;Mec zQpUP2gXfQPsZ{Pp! zOc+Sdy&ua}Ntf%ttx!f2VJviwZ33H}5!(P}v->G)>ZSms!fY+oud!U!zOJ@3|QRuSAq*)fPyb z^-UDbP^Kb7&M9RWOSr7r5Hpg9f(V5{I-7leyW3Mc8aw1PE}~1w`Vy za;%-`inUGW3lAz8W5$OXlGD;>qh-$~xIWdp8gCa(HI!X#uf#NUBTb=5Dd~weuS*p-j z*u=cd8-5YryofS*~Sre4Ib2 zKY5FuY}cfpU(b1b(Ka^O9p{&4UT63;+Asb~5*T_gq@b34d&LJPrZ^4Cl0ZXJGlFW4 zcZ)wL*6$~OrEW7$k8GYl+OBFxQ~eU~BKwdxj?M1+ z68iZ3O<&_L9H0xS}H%8^TP9EVc3C+QY_DiJp9zxJ1tjzi%{C{7EnL+${n( z!;isvL8K>RvV7QLNTIL@S|3GR@`V6DKz=i0VAD*ps+PD%Y9r#GAQcxO=L)8`^!XrXU& zIw4Z=_B*-vzltr6{thquI2!6DI4t;QpRuvb_sm+cJ2(y)H`Dl(=u>cM`l}8Jm#PbH z%e1BZV)bAxWL%6m{5awYX`w&6a(>nEsle-T-l5vk$VAS)Kcy&JPn%4JAnl-p#|{te z*u3=n`M0bcWH6h>V#)W(8!;%BHYrggL~~3$pFD;f)KN12Ormg@EH~ZR zI3dZzaHVbN$$d41sK;hPA$^U(Ja>djPCX;cQNQTiX!VrI{yF`LM3OM_zmI& zROXTac09*H=PldUSv+K0hWfo>asutDcH++Pv!-^DG{4#|?X^tY$d5J4UUu%JZ1a z?rn-xr57hQZgyp7_Hf2E)O;K&B;Pz8dH z{3KuK_J5SW=D$iCNonPuY>fk_P5WMDEx&Q0U_QhBBMtyz6iW(o=Zp!b?Wy5pBw+K@ z{`IJ?!J(xCt~bfqlTE-~nzX&axlA+0P&Mw>vl9G?-ql4tcJ^nF0q+q}t6ON07y6#0 z$psm4RPaHlvqxF)Cr*3D)Sgt4J8RAcM*)b16X6f8fms)DP8?P|L&^moZv9TjI$A%> z7SOeUR>!LyD!~#4J#HxzN;u+o6&~0zJ;g)`t#{Q1eV6AHJ7NlFU7v3d253j&=fPhr zBwZeBN`Vo#H|5(i)ib^qskF2`mYrO3-!joMg(WvBY|Tg3lC>{8Ss51}SdpX&2BMYt z@}|5=aMV!z?`WBijwkP#tsu>O!t(|G5d8quNI93d?iaQ(pB z#*v*=wH#Ar80$O$XMUBRGq!a)178KW((1+fPT6|{0pUe#zrkSp#4 zkjMFDDCHq{RHlek?WV`{#UFr;kh=)8A&hn8#XkCouWsI*#^>DyuyVgNO}$Uz5dIv( z?>7h``IHZw!EZNDs^3SN(ExZ0-fVAIQX+d}azV;L#H)k%TW*a?1HBI!1 zM9bp#zu<9?lPycIKy{)BZMY(&=XLelb}uajJ^Z}(3bE$f`1(4k?i@u!4*qQ!dEAZe zyf16H*$qu$yqTJNb&01ZazS{?bk~^PtlF&r-_x9aglv^vw7d$f4;0s$I8{DXLJv$_ z!HRP~f@AZD(`Q<&CA{87weMT)*urmA665?-C)WFmYlpuf$FYMlP*j?Jbz{iTl>-1Y zJq_e$)^`DO_a&Y`>52;7j$hE0LcNEVP41LFo~=F% z49WY|u+cA1uU@mGHd2>fmSJ6CRw!pENZ#Zu zO_K}x;+7_)cMqMc?yzQ!0~D4Laz9AK^hqi4u9JF!w`xWeoBxr^fc@J2gXJByOu5d! zN9tbQJ1Ehh6Q~-BvMSn6b!7N>Lh>F#=!NWmNn;c>6|U%+FLRXXS^eNcZ&^EK;7s0Z zm%i8~`VpRj3VCl@HHHKwoL)Yw$&?9Rxm6z7+X*l4?ayOdgb zdd{0*RTj|&^+n$lLP}48M-o02*{wE^AF$}B@74fso*1cRgdQ> z(AufMSFq~QYyZZlFS=xMnb+M~CW2rllzKtUimzxy{S?pLvije6W zRQmx!gs-`P<4?t|bR{jpFxz<3i{u5QdTMpxPpr>bxpo|12}%Jovdf&xXefD&{+o!e z+}s*C8PQ_L-%qiuNMEJ@W>Kd*J@=fzi>iSo@G@_wRp}ECOY}Ec-ZA7T%2azBN=QCy zcL7bT9f1HMqGI8>zg7fDuEYdR?!Ftgf{bX@8JE8%g$sdrX55s!uGc8eG zY0s`&9Q2L52M7mv^_zo0zQ zY-pQMWGS^n%|B9X@-xq!XxGa>YdA+kE{A`@`PLtK{zGW3WJ~BiE&+_&yPX0}xC*=e zvS@e`A*)s#q}yferi2ffIR3RSPXW>csIV%3*e2`uZ`j9--Q4}10_pCcMlp-?Fu(*&0VUK2EC*s~-t??$2YRddJf+<=sB!JkhpDn2(&-p5>7;B@bL?WHdOf zv-52q5175jguC8-K``5o=Oj6^jmf!oj6m9b(?_WAPucZh_SE4ea52`$4!7;t$^&YR zH}yVs)IW`9%^|bDQKKUphNs?Bl7fqV0!Y*N|3aE#uE~zP1hdA>FPWU$W*>5Xi{r(y81@d|vGBC+@B1z)9;#T9wW4f;QjLRM*|M0m z;RUl+FbsQQi)y=7_(ZTXBn==?s2k8c);b*Eak}5ht1xobPX(;^Se!dDyy|i8&oWz- zz_>e7uVT{3h%ezl+QVA07-mHehK2LykKxDJjEPyO-?YtQFD}kjKVaW(FE3p4BAUqy61*r5+ZaW} z>dc@kkA(G(aJ~=X{Y%lZ5IFyhWe5#@46{%VW-H`MQpf0XpR1m z$pW{=!NaF5&yc`rh*>lRWbAr%bFM2}>i8>Pys*~=?B)?5*4`X$nUAK>w%1oK8cw4dCeMppA;yu1(dlAnfK-8;UxYr4bHz0ND#8iGVgN z$~2eHu3>D-nNXW4xWI&~H0t*lJtpHAvDmc|3^=|4{IZ+U#@xgZznuY_mGf||S$7x{ z&u5S8T2}@s4x6`A@-CS^@EJY!(5F*EE_@ypB|nSba$3IMrm2B$Yh9hTmc--4cN4ly z4cxNeBSK|DY5O{+@2B|rU>D$xuTmN*wPT)4k^pmcJAA+nugR~aw7yomLp2^o%*8A@ zFd66D@-d?lnv>H}NZErsZ9Mn;H&|SzDI4XYnQ%6I9JvuJCm^!p{$wWO+A$kK$=*R+ODWbxXBrbKg^(Us zk3#-Is&~ml`u8bDn$))EO!rlLoALoC3EL=rFG%e1w`8uCd&|i&^x1>^bIJbZNna_) zNp)I50hL!wC4TLP?BbTyzcSt)-*;VEy+?M? zmVC-w|D*LrjNU!VK6vZ+NJr*EVVjDVVJaLg8ctzsKivfjJ`EXP8Kk9KgM_a? z%R61g=#`P>x>gng154o=FMxfY09>^8HYIBidF{v2G#C^g=m)Rs*uEer7d3U_6(MSY)-+)OW521F@Dwoo z3r7WFNY59CZ0XEg;n$u~SA&Cwe#4GW37J}dt>!Ddb$`EdMSY=a<{-Gt^eUX3D;6y) zxPqBGESOT7%Sxwdxki{06%1{&q=%C1AXJTwZO9}G$O1evtQej0FQ{#O5bD_%LVP}U zFQw}f?Fu)BLJ1HlPkh#@lKqx$m;r$Z|332ivgZchi(3Ajbda^FuO*We3KUq2xfg?I zx6YQ7DQcQ~9{VAAKS{-fyzyInqh3_~HxrvlL(6N4wI;zYHqaB1`JI=gx$;iSGz9y3 zSFc!T^a;!OFTpxsP#5I!SYPTbNIJWIbsRIe%`-f` z_C&L32jP&{Ys>BX%rW;3HF^SKZbeyct@2xCzA={lzkiJm*(Eg;!Upw8Vl)7ac}5L$kv>^oDe>?cK$5P zOryaUH@=);NZZ98p+-S(ezkgm>AHJltexxmtbC4G+FLE`07mY-ite?|J`q_S= zW`N~5SBW18u@5<878egwx~8TI*k;zYlQ|p7{tJ+wT&Ro8TUBATp__9+rD%p>%zAd#Xb@gwG<@~@ees8rMH!B?x;es{-gZe>n$UxAa{2~xC&SvMoS|h)GmtzS4q3vw|7h?QHw?k(vT?n z+}A)7!RT(n$5FR1*7pO8Bhy^s5_TBp*HYHfUaBW#_{8D&MRH|~eteKGPz>SN*irkyK^{BD_RMSV+p1r)i_qS~ z$xVb})r$9Z$@3*Xt)hLj$Mg?16P@-dXGhQ@TFltw*MTYHvK$5Ut#!sWN^5ra%!l!| zpOP=on>#drq0-&dJNHW9XGoX!{_xO~k=;WCQD+~)@v>bfq=urUuMlty9|BV%J~yZ$ z-hMs0Xq=|yFi2G!d`|NlM;$g>H}t?EFr^pvf&Kdl&~C@Z385oqulI zJ?IDI>ir9j_)GpyeCJHkO-~Ed2oEIk?>s~7pkKdtl6}nlNHU1H7Dfv_4Pf(_f<%Mz zj8?aR+BWK(#QxpV_L5;Mku*3jnw8h3hd7_@wmV-)}zP(r|ua zmfCR{Xzs$Sc>R!q{DvsIhZi+zU&b-Tx5+l_SKQ@$l{_vRVyYAtuq-O`{>PJdn-+qH z*t~eM^zSG6#b18h*Ou;_U*S%~_wyKwz0`9Q!c>T-mGRUJcqw5zFQSc_tVd+24>yi_ z!``%S1-|nG%YHch{n^~=T_75XMcwtejFFZO9melku~z~Cg)PUywz#znLGjL*qK5h=eRnJIk+h)9z17d@IL)R}8n zSn$*V?g++1oT9Icae*&u`mgnIlC^-n^bulw2Q6Krss6?u1yq_T+L3RZPF_v}Vf<-y z1~izfa%%@=BEBOu&}AcdaILd4kl|A+yXId(BStrkD8+&balt|E2&Ip!NS;%}5J?OA z<0c4@_*SO+Jn65_696zigI*RFDVvTsBN8}X9 z^MMp~`rV;AFcvIue8ijwmCtdQhP{R@%(+gPK_JuTX3KMk-T$|g^Kz7iWm&|o*sVcY zuCRKy)||ZV@S^&L z2RL{CCl8K^%E1j{9d`DsmQvjDYTa$`?kk$nJC+UwlPdH8?ugYFuq^7u`1_tkal7}Q z;20(X5M#u*)=(sDVef(=*^{};!S47MjbiR2o_*6>`N;8&{%dgIwwrhJslxRTS4$7C zr@nSSn&Ym?;^UG%WiywfsfWnPEJ~e%zo{mcsnW)yiRX2Tz)?=`BvDD6> zg8uIV7PqvT%Dh;AkN&Rnr#v(p+-}zmbP_9AsUVh2Iw(|4k+cj>!R1#V599OKSLt@h z#PG>ImR=!#BZ(DL9Hz1p%$rQD?LbD57#XFSqw!BVU-t0t+@BdIYm}}z15(;hG4XcK z##>sLhd(>8^Kr`H?;xSGk%mZb$U(31ckVhH*fW;xRc!xo$m4u6bLSUY zj{XXt92^Jt+YYQ9&P^5*4HC;(<)>M-S?QqHaw&I(Q>mBRu0$XL1 za4u6t+;~$;>|Yn-0s}e5d3$nWA6pvRE4UWiF3Fy4+}t7-h^{0&KRrgQ1}V*jo%yJ;Neo{WgRkS~>5p&Ja zF$XO8iLU*(#!dgEQsu(1RQYS)fwC`1?~%#95{vZHf!!8p|G+(>F0^C%!p@saBkLExmB_(Q=fX2vxvT=1+1| zL`41l>%=^LLT7Nn3Gej}2i!&)eJ=QyqD|-<%N^lhQ(?<^e1BS#*5*2U%LmP#TWH;(C(8~ev#i%k2-B_KbtD}7Toeuy6&ys z>=vX!=T%th3ETq5M#83iEj8|Rg;ASqlu^Dd^V=k?K7-|d%xH^jS@qRN5z0>_?aTh0 zj|d(QHac*i?}C6aQUC1!8!-5NM#ZElvpG}BFMwb~+{W*5~BCc^A;s036)bu-=?%8_$-22C#wm|(b zS5|n)dcbYvtvkZ(aGCgxHdOF$%uxJS%wYRh%<%bF%t+dB{g0U8jct#GWqpKkOac5@ zDntI-{m)_OEA|xIoN>O8LfmLZiU3?pM#)Ze8thaTs#83#UYt)L1&__#1Vl(mC}NaY z@%MO^=eRD{*Okba;(oLhT5#gei5*5F_QZV{9Z8{tXw-;47_-ETK_L$k(N@*r-Z_or zr@V|BO&%Y>5}E^S5$I?3)X2 z>hkNM;Oy~i9we0zT;TYqi-QJmg)v(JZ_>rGgKg&K<4B{rf^48c{XK%uBQ>>*7!#XT zs^!QO4*i*N=l=HcE$Po_Gl!58*{dQJD`HIRL4Qs)c?asVUjaiHObr1I4yM9%6<7>! z39jO>EdLoguAb_L3=S=r&Kh9)+Rih9rkR1bAxDZEHPQPl*82a%4IA74Gj87vKe3QCCt%-$zY99G-SyF~v!|`55|`l$|V$ zH{d=;J)*`uTH!p}3`GyAA5Od=ufw3kq-#VgvQ-QRbOvAEdp-?FIT!>CZ`}qu{xuY} z`wg*Z3gnTvlYQd8?J0+U;EpwZ9s7JfaX(~8NAFVE&4>N14nSu1=sf^KYCe~foUh!^}oNN38_6rNHVOx3C<4 zX3y#M69q@j_*cT>Hw-OX=k{~+_%K|D9S=&!HmVCSQnIbmf6wt%mO2nrPRQ&BPR&_b zZeA+?3h$jGdH50tA@e(>@WQ#K#;WOBlH<*EW6NfzJvJK9pHR@+a}MHVQih)(t&x;G$>+;W z$WfL71UG{{PF%VMsE5f}@psCV6JnkRD9?n(VS89o-nQrr^VPWF`;|`{;XSg<+MRfP z2Vy&bl_GNW=f36kNvn)Yu`sn}XNXcCFoQwA>r zH7ghmfgJ3F#~+^_q_AUt~x=%2Uw2u4zO)u*-uZ|5N6M^Rh7^*q?!Wa^{~vFflk*9k20mjg-7BsV4;C-KO3S5!*2|Dv zlw;I}J%beP4r>WH7e){uQmgcT{R)#i3H;ORnuVwHhj`4bEEVPA zR=R=5NCUo$lPb*2I9Wf%L2}YHMRU`vH-0F&K!ru8i_?*KiK75D zn`^eYi+QstdE>RZ0tbUZ+FeG!magy#F`lM6C@MM)hdM=4)V2+o`_DFf=@RK7l?!C| zY&%G4rWe)sQ7-k7Y)I*%r@O*%u3aol_(lTU`gU^N`PNq^k@E4-xywv^W#!$&)> ztHJX@ntlJ7Ip?AbO}#qFb2#tG@+_(O{J%oAL*uQNjy@wd2Kky zxpRe2>VT2qd=+aXQnYDNsa?&W`pRF2rR+@xDL!q5c-AjtUN=;)LhRYmj+|6vNBX9e zn0$>`;$m8WIbmUY4WSj0US^RB2`mi`{@A>usVi=X>2An2iI>m8*teq>#pppv!Zu+6 zFUY*owjOqEhb-|z7ar>a$Jx~U1)%bE1K*CR?^o4;+XK(D2iu6i4Ra40MkcS)`{;T% z$S?(#cp_X8xYjHGOBEbs3jfkzv=EIeuIMbq=Q?&SQhe&}k(Y|FPyMR}DiBwmADJ3k zeM0^?-M|zvbz$XS4)znVIjksA5|J-Ngqq z{rPDEgftQ9Z4)QyPdzGH9DGY5^^0X+tMrGk!NVDIn!Yc&7_=3f;UQtEXWVsL$ep}fBeKp z$&s!w$m(2d;L?)a<*TkOOJ6$aQKRKLF-(+|bgu?6p_%s@zBA<&-gj!8t3UJm?%?Cs z0~RDip=SzorKPcw2T2jW#cfXd4_;oTn-M{E8&ZW+J(QD(^OK^Ho|zji##-B2ISUz{ zKUN1c!J^>|%h?u7^9+S$Z8DbF@1%sIc=_N1tPmcQq$L8f*T_{1SURp>Tr=fcN45zq z{{fIf0Sci3P=VjPt{fO%2*3mn5g6$Eg}ZAHClntP8+gh7I*=EH0USihb)ENppqw6V zX#t$lJyn$Rca`5fvvD*!j(W#=ubrfPzyS1Bnt06ydNNHuJ}@BC)g*Mvu?ass2aXMA z$6Ia1Yvv`nl?>a{;G^rFw-4QEA8De$GZgIQeUQJ&a0RgKEiI`sK>!=PoqKi%&(<_S zaRj$nTIj!6?YafLRn2c2mXW>eySD``B zeD==EYG+neHd&CGa_`gGgo*cZ)yc-keV>0eIgVO&FBx#1M)7k8pC}RPmNRB$R7t5$ z{?Fw1KXT#!cr0byHhPih2_$)L2zLi-`_`YFYH2hZl=4G>&*}%JZqtAWtW8av-##z? zk41hz(9~k67j#*O zQS+~hhlE^AhV|zU07cF0L#NWi*NHiq15DSKPI42&NjX;x`k#AHmkSE;nQumJ=lxGj ziqILdhemv#s)jtCF>T)SdFyf|wR;E1XG7yx_C8l&%nc!C;0^_%DaqcgL3i6%>zGPG zC;YD$=bEJgxJ$KD{%ohW^6BT(c;MmQFmpcrQB+)?Z^G10hXfvO&RpV!knncvYL^2t z$gOe=LILab+XE0)6%ee=LB4>Em^4O`-g`Mx2e`t=zMhhKFj%iB6mDU@xCF^i3e+4#0nYokZXt296dUO@#^6nLg-Ee(X@?bL%###TAx# zJF$bjBI3!HEy|Ih2p+i9U(-m%Quw(qjQlVNTr1M5c?_;Al>=A2{7pLC9W9U=)omK1 zB_38f+QyH0#XK^Ti`wLPWR-y@1(Lr%fwq$0F{Jcl(U)87Z)f`JN$yvUNJlo0=>Qf{ zt;ew6ZUf|hS}{l4yYNoek^nOKYbC*8W|bs>8DUDh@^g=IPUh*4Xln?H)>yr3s9BEh z>Scf?2?&rmoZTV1a&y~xhpnKqe7DV6fQ=W3qVI2Hl?7g$&&^f@WEXHhIP`1@5W$J? z;&dF>Cd2Pvt!n{kwCzwj>;3zAN}X@&ia6#0rdPj0B#B3o5lCqmWXH(+Q>Gm zOai!_R1frcU~ZUM6Y31foR6LW*M~^r;lX)>Qm;~?M+_(EDKGCbM7o9pjs)C0kSLlF zYZj_7i1|E0PF0LeE5yb6cM-k8JN8G3$c+Nu9kJj(6^=eEj zNAO1h@Q43+d+i-)wLrl|?`>Qjo+Zl8zGtL zaA|HtFz|Bo@dH&2Xk-iIw^ZTB(rr>n73{{wxGLv+k+$EHpHrj16($O-ii&fNr5s^z z^^O*6B6QyZsZ-M3?R>PuH>g#F zU(sCm7z?8m${1I6Ot)5Y>EXT4_hIW!&rz(sbk8?0-q!MBnIU4C|MgV2iMCcfwU&hwsg`lYRn`N;JM$8qz8 ze5MTlm*AjtbMSkk|LZfy&0Z#zDytSZ6`h(f&7gZY=9xC&9G6=4Y)x-rhW2oSSStVH z{RbWqL*;iCi(=7E<0i=;IC%SDtD+yY^rXSBu0&Fv0tQUXG~}6W%T+v;59})N?TZB- z1r*j&`D(F*($v9dF}4^J`IQJtIYwP6XL18&xT$=TFjkktsUVx>!6r3)7rP#AVriD8!(s69Jv% z?N)j=7RuPA9Y@F6eQdFXpcddwNjq3$I0HxJWl_Ep6_=t?q9Tim7+0j_+oCLrLvoQC zq~7}%SrQdV2C_2FhW0Qtru`3pSa8K>he1JWo*B_dCr#Vbf#4vAco6IeDx}jTht^3O zFt@z1jtbdyLP{nQQ8^|BT>ssa67g`mnjt2(T<9^CmlA)0yJKKn9)W@HZ5SihbrAB26L0IINmD4AT+_B>66$}!c_FBfH1ZMKrfWRa)B)+ z4A&G~hKmkc&_WKZv7e9M{e~5I-p=p39CzW0e`dI6&#!?nUdXIf@_oH_ZT4mD>XXB} zVk9>s*N&v)%uCET31{EYeB6df`X!@D&)Jtt?&D`ygjGiIbZwvgp)ALojZ3j_dYy#?)>NX z2=59zkvzlB(GKBoI3)T(!Y))}8_Nks$k`d`AcQ2*IGhR+$5Pl<G(|?L>MiDkO2EFdWq`!{H7VwX44Jl(rL3vG$T6Agif1< zEW@~*NRkbQ9TkRwM*4;Z$ZSC@FOa!{9YqRaFXu#JKF+Qr zYc8Knnxj8Q-;j*$&1VJE-EHhX?u-3pPX5@)RjXF%ubQRLa*| zks;haDE@i#Xor2;iN*X}IWL+YHriqq(|{eu4rfP1MPg-*M1An7CC<*Di~nw0!oxq8 zj*PO6!M?^=XD!k*j>k4|XGe0Q`AoKL40c3K(ZP6hYd$+Lifx0v&B>yxNY8Mt9&NTK zb`=?#(q|dYG^80Cekke8WpRSzey`-{^@f$Ce=drhP*z}6;D0UrxvS`+q959VT}gl3 zkS{w}bHliNtW8+EXOT%?@*Sqz z(p>(>3(JGO@?$EDGygYMV`d<_NU%K8ht!912LG}@_D2*aDvbTH0?V+d&sB-eB|R)K zV!1gvR*%IF4vY?qBF_&G=?9aUW`+j@BS=bGG~LgI2tfM$>v_8Fg>A@ByBM z-7@;Sy1UppF0{pla9GWrVa)JIf+0fT*iD+~9@59xk0jBJB#<(ih>hh80-2FKXAe8i z(K>(k3=12nV8c5}tjK&Oj~|7l9kBGmRZ%=qItxoHGD8Ac zSh@sD>+-P%V(C^w9hiFJ2`wRWS{-V0o z&?3ae_GMz9JQRoch=Z1+5EO-UvD|2^b~g4q7|Um4KVc|N)c@Fi*y~HbMh4HKjb`Cw ztq>BwFBHDQ&auP}god{Zh3^W4!r^_`!1o?PbrE0o=jJ11@*2zE{w0sH7oiCo5IWxY zB`;_vLMJvMq};{}I;u2V-OUmj@7%^F?UlHH4&>eCRW5n`k>Kyn~SEYV1_~ zfKcwY2u;VzPgpAK!1@S#I`EfXqDuZ!1)`mWbx1)HHRA%ra0&>ofD==|37gR5(Z-3| z|LG-;CrDr$DDnu8$BQAn7`E@|HXL4zAWj^opn)bTDv@bcZdfT5(MGJqr=1ZZh-2j> zrLb+&vBTg9IC0UzKa?1)K|zCv#wn7GCekc5-2#Q}NLCDowMR?=EkK>hbk|$w2Ob?9 zkRIg8-$*t|@(M{v4M^$oxUN9c19k;U#@Rk&9+)vvrXL(S1GDs!LJ-PbFrT*{gi zxtx^SXH-?5^(^}~(tb~;Brfz$1LRCZ1 zbz;9o^*0ZcA`IJhHQ(0hERK?OxErojajB|Re(`bH-Az`~9fR5~lH6*WLTMUtNoJ{u z3d!JHLvQypvA*{89^rkAO>S2X9NSmI%%Lva?yH_f{a!=xA`LuU9C$iL1(ZJDnH5V9UKQfvVts2EJwWX0MvY zV5X{1d2;SGBhA30c}MimyIOv8m&R3)oXNdbV5V`lg_x>+!7+ldzcVDUcCyTo!iote zLgk!K9Me&^r{~??QjqSGO|xXhxH{Go&R)VdmDEoOxDfEvdhxXLnWvg&UazxeNInqv zDtK#@thLd_#wNwff)GR4Ji%X%UlJF3u-IlL)%FG>MTU8+Df@KBz(IDgmfv95ieleV zO@W|(sAbBQ%yUW#B)4?kRK^SWL-sg1ZOzR}-kZ9c zCG(Wb6^K+Xq;Qu=GG8<2V!_X4-{&ecWlwh0q3CT}O!R(f-+VG>*Pa#Es}AM{?@w1z zm3T-A)^Sqw%+O&;X@-QKrlhJVs8kxNPMNlExkTYmW%Gr=n((Lcx;tw&E=e^GHafPY zX2u>dqOq#uGg@ynL8)*3^a1(gQ@44KXsxaq>iSui$%u?dV#{_Eq2e}tLbY^v}%vc4;_-8DzIzb8lc z(47J&qG!EXnUY{2@pfNQ{Hi%H1pdZ`X^JRhorm>on}` zDm&0Q{n<11Ao;rT;klXVE&cEJn7z9C*h!}H*v+7#=nrZYS z&Q4B@@M{e{;?&~|KcAhUt>v9FqA67ml?CEcf5^~pd3Q~Xac-;0{K@7;QbAY8mj+!N zj#sRrE}VF=z=x|m{<-YhAq!b43tQDzj`}(tC9X^Tty5E0ZO>{9@a5yf!Xq z^m3_lzH^)2q>;4vEtjgkqw80C+>^bRbG(9XDV3YOoI9w+ol$dq(~(>%v*75^{OI6s zb8@me3O2S%JB4K(t=&xoF&*iDRpUZwb zI3tL$ODo&z@O?w|d&=+n6P1aHTjrMBppSGqylR*?SaqOEGx6KUlZPACv>Vm-*32_a z>)^NO9XgulO2~Y(pLWqioNVpF(j8|{QQK3UnCPIEq*Ien$vC!d31NKM(Sd5ua_Mz~ zvb~AB4^>2Ow#FYCyw8}Y)%Y^%)zt;Lx@G6eW_rgx;&v~(@3As`!g3npyfvqPP0tT= z^z>$&u$C!N%xRm!30hX}ekif1HS>IGkh0=xW1CZ2FDzEhoTS@1wDe6Db*mY@XzR?^ z-R@1Ehqo+^u*3o>uwt9M3yt?qywLPbcAGA-s!pcq;-0b}I*0-U4 zejX8m$*wc>s@-oio$@a7$2pZ!w<$LnYQG6fiE+7~_`qA&x4!>mpSIJa*l4Foi=SO9 zO3?|(^OA0ity{%ozGy%J47~RJLWgJXk~FVMzPQnx*OZQ5vCID#Sze(mKcTbt@!arB zl;dY_#90uX+P7cQ?o>>XGv9uAirRL5%tbto#3z(>y*;LLYdB1vUUsv&#l2$2h)P)k zKH_ZEZ4FuJ+M99Oy?ZCL+`MWw!m2KxR8r~tB%`)qUYzr}qvqeW%v6^R&`e2>`mzXki$_vkjjuz! z%HQ54MSC4c%PjKoct6MUJ>kc-%nB=IrFF$G-P-0)+i@T-?tKf}ThGn!$W_gCRxvMk zZw*;(n(0kfby@$!n^Vf+IDfCa%wqrX7AGfSpI`PGasB-{W=#3I!nSH^+k$wp6rZZ) z5)Ds|7U=qR-O}~-KV+3dDNT;^oGJGZ_hbFGT1i}zwq#*^n&zSBgl%S;wN5Ili6&A9 z1J~U%YDhI|dAI(^t{+e6X12d`{24hKgj(wsCc0B*zp<)g@hw|Av?U2i7l`GXdRogD zzdmfyQ|_WlWgI>*6k0kY_5IuPJ{t^mgvj|(VfC5?S}ta*zsvS>mnQEOu)Bv;=uEysLuUnE!{3PDS`qkG<(+5D$PRSrzva?!ah#W(QSI z*XdZOSHI%-nLY!l*7$9~7k09SyT?<5&V4scChx|Es^yzJtJn!=qf$7;q`zQoyBvO97Vx zE(Kf)j8b5f0;81wd@%7(7^R&1Guna|W2z+ffl2~Y5+Ei5F%gJ~KywG0JJ8&LG!>+& zAWa1YHz>G4!3_#-Sm^NeEp(7G`!jM6yD_B&hhRP)=Hp>L9_Hgg;sp{fka&T_3nX43 z@dDK_sD?o`460#J4TEaqH2&)BQwIHk(gw=wuS`eub zA~iy!Mu^l1ks2XVBLx5b>%o74xx%HafmQObN*-3p!zy`3F5aPCl`EwwL9i=dIIh{g zJGZ`jWai3hRADZ%?AX@^O2yVK-o7_4-@aW)x^dL|EMzTqgS4cu? zKuVX#Kh2u}a|M_yz+3_53NTk34MMGT3lrTbv)@?NvG|rP9omwFqzlCIO+BsUi(enM zfFLLk1OP_WboaL#!UJ;!m@B|s0pjKCcs<)<_a)ZfVl$96=1IHZn0+#B`nH| zd-95!?Q_gF^r~6fuvEvz2)%;d$BsVT;lNx0<_a)ZfVl$96=1Faa|M_yz+4fSfW`|n zUSn&#fVl$Gzrb7p<_a)ZfVl$96=1Faa|M_yz+9P~pHA}fn^veyj`bY0ame;W_5luw zulw)lY|1I?Vc8SGOu$UQOu$SWx(W^_(CmWtSJ^rei!CyZ1sx3z_4Nv6H*r-NZ>RI( z!A!nJGXdrbFjs)N0?ZX)t^jidm@B|s0pXmg1`eT29-LDr>Da^b6im7>0!!)RQ_p zz)ZkQz)ZkQlz&d~piHu76TXvo>OHK>NL9!I<_a)ZfVl$96=1Faa|M_yz+3_53NTlI zxdO};V6MP?{MhsHz+3_53NTlIxss3?kkaLGU4iW7ic<&Xij<}V0hlYmTmj|^yI9L_ zFlgq0P(Rc%WlQEcB?==K@6fKw1v8PJ*q{n#0%ihcvLw|w*yz}nni+eH(3I(}U?yNDU?$;xj7@G=4jkK8!pxyA-0rKMMdVo;RM%DM z7~1)OnVilTI0$9}X7ZJo2{2cHxdO};V6Fgj1(++qTmk0F4f;r@!>fjQgH;ErG!wsl zJbAcLO}kNTZ_PZ@v<`lY-XUPF0CNSHE5KX<<_a)ZfVl$96=1G#IAd$PfVl$96=1Fa za|M_yz+3_53NTlIxdO};fJp#M0$>sVllUE&1VpC!`$eXKsF{DeAv`cwfVl$96=1Fa za|M_yz+3_53NTlIxdO};V6Fgj1(+*i&&LCE1(++qT=`SXmAh*~uNNjK8&qmE2a=oj zyOl~RTBkdVR0)yMzMDFV?`|55Oxv@f=lz!5yAKDwUZqv8yYkRmuN=8FKGSvlu|grb zvW;_MC@aRsJxTA4PhXd!{Dk+FU5w=qveqaN!TdWCHKZ5E6~o$iSMN)W+OgSvuuxgfch!d z(C{;*u05u$Z;pD&@|#LCWi+dk7fDjz_)MbONnRS~F(J)wHqX`e^?sAf6ra{Db2RXq zSGG*Mz2Na|KepB0cu_n0vtK9JI{$FjDE`!rTRA3ohIKBDYd&dIBH?#kh@Q9{?Rd|a zN1kDk^G-LWe~YBVhR+mbwh1c zwkO$`Jlghb+A9@3T7k$RCwWw-5__p%-9uHzE)Coi}6k%(wj+0700 zq^C!lS1MVnRq3#jFZAZ`NS0cgBc9@xOsmgoeCVB~rl_!%Gk%uTq&eg?2aA1beEZki zeodQ{>w4gR?z;Z>)V2N@9+5G!-yD4Onw>sJh#1xNRRSRx_1cwezNfxLxgxJuyv-hA@82xDuxMy^8=>r9i* zy}%>sd}C^r8C)|ofPC5kb0PHICQJfUYy|XXPw$$o90mH zF0Z{wEn}ED!n7^+obgMs|N8|}{)-=Z-urR=3Z=Z}&6Q*S_9k>~)yC{=`414Ts8K>O@4;Z@qOducE5C_Nljz z@tl@43;OMCLPTF%{L=%sHU$RZL>u$O23Ly(FHdZov3K*n)KvAZokBFhc3?@`_C{XE z4U(_HO6e2IVV9XJlz1NWag;FQ9k64-Jin8Z zpZuUJCMr5Hrq8nU_?sf@k|!SR*FB9c5sMvk(=SSykao5O_+%?<>P}fWe@@8tddtbT zw?8z@V7hC!ZjjbEPg&<9M7yqYvZdEP6*Z(`@vUE#=FSZ`*Yn)P+vlPGV7acU%A@9d z^%eF)v}gWJ?tpgh<|6!(-l~oUZPK(~mo#KuZE~}-8{dCPh&JsTs%*XxSQGwKUUz5B z#y?ozt3MVjVqQ#sYsYH$g4W2=zL2uto46{TrgAi-Gk@zdhn2e=s!A0@t;FRYW-h2$ zcRA$f#f|d^MeXRCIhMEB3*O>W2nz5P;4Q#g6i3NA+zr>NxK!0DzxcQ;cnk0rU&a>T WEj|Y<0&fA{0=&ils<)UcZ2KP|v*z3Y literal 0 HcmV?d00001 diff --git a/images/maps/map-room-entrance.png b/images/maps/map-room-entrance.png new file mode 100644 index 0000000000000000000000000000000000000000..6ce4c89dd6e90202b39de97fac2685d09b768fda GIT binary patch literal 3311 zcmbtWdpy(o8(*?wiZGW%D3_(!VTE#A%>B|(Ne)Vfu+s?90pXc*_p3n1qp7-aIjCQfz4pD-D zK%njRb|^RC`v(ZL2_&`!7`4tVu>b)dWMzd8ceAxrv$wV~)IV%!sB5674+6o`FQxZ5 zS{{WaSv*B|Pd5chtGhljh`u^lmgpvbTmsP zYAubz3|n7tz%r`}QN&NZyeXq_NyPaVN>2NN$XK!0gopBfUGa7-^3O3#&BvY&YLh-0 zaS3}?$Ih7_-Rjq|wb8SBu_^wMzS0}H-;EQrp(lDE$0TUjfD@VAM3byvjCEr6nHF|| z6IGqf+$Km}$ujHr9)dTU|K1?hEOSD+(oeIpG;wnBTbcVV2cG$qW8UN5iEHhZGp1N*%C5(n$hCgy}d*$v-MFlghy|1!I z)+w<=^pd@$GcNE!%FYg3)py*&G{ha2dmAhdKPQJZxVy3-tH_6%c??9S7U8zmVE3P9 zfNG+OIM&-SpNfBxZS0``6}QP*J&=-gYq zqU{Y(6Y)?x&v4+YE%w^+A?TYyiwLd8N0kykh07Bf2|ee}9@f}8;> zah`6=74@n+f(@B}aubBI#)Gy(M2*pEFYwl)@8n2I4Sjy_W)UHLAhed_a-u-|W%O8%fGEz4oZLvJ(QTy<|cT?5aoriyI z6E*&8o5tb<&v8NPfG)eC+!Ei89eZ9hmQZRvws;(tc8WonNN+TggJ>8Y&Z{sw8?+%T z&JN+DWqW&Pn<oJwjc|f>m?)g}GV!a0vX}!tL@D zi--&&m3nQ2}vlKrnrJ zwS6nOBUF`ufs65lMaxH%7~tr| z86;V}$SIHMd{VzwpixR8Ru~?_n=|kceEJ z2%@L5RPz#OwnVBclgy`i(3{4eOY?Ar&t?6G5JQZv^4=?563{u63U8$; z;P8VS4MtBtpnE{nR`-n@bM#STx$EHA4s4N1rhR8lJ~u<5!ePVQYeWv#=3OGrqfL! zyfF5Of7(v!p>N@cog5hBDX-i%XZCaYJefWUb{ki{5i^2A%&k_AYP*%>!}d~6(D7D!!(nrl`M}ahqXDEE%7k^3*{n6lD2~LvD$my+ak{FC63^Y606JuPC zSfp1GnQFd~EtnCqw#W{97MQK)o}pbJ8-<_A-dRlv{owDwW++S!je6|4%+xo0D`iD1 zNgJMGeqNR#7HAUe7JAQB04b&RS9d8$11E8BfrpQ?PvManoDBOh$2(KO4oI_kq>pYF zMveAsQ#3IlW|oxOj070|J#+Bo8GhTt#2cSNZOw&N&T(SpK*>~1YPI0#yF%lb@hAJy z*q#TBbCY~6c-nUW5^}>qFk58E6{t~aKI`-%SR_oo=KDnDM)3h8pkIhuQ{MBL6Ki_u zoL;L-2&uuGF-ZMv?;kn>4q034wbGXoE&pHL&$do*>*cQwZBPNUq6=7eZg*8PNhvAR zZ=(qzSvv*&6f+J(2ZVWP{g%zz1^(WIu4;d`nvfA%Fv3ggWrcuZ1mq?}csiyx>3QP% z%gB=JY+MdoIN3L4(crumLh|TB7m7Z!$cWtC$yvH`QA}HY4&{%<9fD*X7CIgNFH@up zBgI4GHN3~1OfWWhnaeBFV{T0VAF%~Qff%Q=Ua9A8a0*jfw;69{U-u> zEnkUZ;-t%KVV`FiA9F{_Sv2#S7F%QqF83NIpoKbqTSPOI^ERcl?o!AFuS4O4#y?2} z)>m#ZQapmEfEKV24S^2LYy|4;5AQA1ci< zVv_ne%TyZdaG=ruH2Y(}tgD*#!s^9N3=56|TyUxCwPeZ;@XVozXXK@`b$hFPTR8~GapQ&6OU3koeaal9 zIaEwSU#eaatRobFVEJEAws;6tognpHC+2={YjBdtSqKL?hc0Z@mtt4}^QLK1;8x4t z&AK*%r(43wQ&Yr_UHj$z#+u9De#}4XhNHjo3~5*7<$G@W_k$D!%A&7NWgrgLHP`PI OOxjz!plU47T>B5wV|us% literal 0 HcmV?d00001 diff --git a/images/maps/room-builder.png b/images/maps/room-builder.png new file mode 100644 index 0000000000000000000000000000000000000000..026bca5e775d1be759ba1f2d95e64b57c3a0b0a7 GIT binary patch literal 11307 zcmbt)cT`hNw|;06YC;i^me8a(>Ag#rrc|j?L=;eIq4(aEA}C0gE?psj^e$2a5ed=} zgg_{va}U1X_ulXQ-TTK~>$g^Nk~L?}%$eDHKhG``qkl)8jF_Gn1Okz1YN#55KsZp~ z>khsKw76fe>j6JF&kfa;K~R(vQ|fTq=MI?Zl-kRuH%bWx;!(b_MF*SBiqHj*^hZ- zKI=1N7S(3f5PcAZ->^vONc;q4P6d&$$K&IMgj>y3q7<6lHV?N><>vynKVq?^hHu&e zw$Z4)_0tLT*=MPC-VmF`a_e*P<`%z^JK9Wg%@XLL#>O`wP?)SUcALrPc*Qb{_Ix)9 zyS_TmZMUU^MQ_W$^=#$aI5XTE)Vq{Nx427&1E1R3?QR&%Ut7ZZ{L@TPY3Z1ORgFFm=~VM|TwX{S za|BQO#4S-Vu}3^^<@F6)_Njv1Vz@fqoUxzN`Lh{UD7O1Z&ee&-;o!bx+^14+-pD0l zz}TgT3pRqqXU)y~LH4&1;itbgHU^|?-*mECNBg}1x)mxS<7iKksKH9m#60Kw*Ig`( zR~W4sKMa<#<1YltmMGp<5Vf3)D1tl@mEj-&jmn+I<0n(HfaPS1fLp(NYO1_kGfHfK9p~Xjl)fFH5`eH^R`sBp0Vi0d{iDs%5F&Et#ox`#Fw22 zIEKPJBtGz49BRVpZN2#ZOF|pxLk^h)7c~SRyrV&ri?a0=!-T5QJyg+$_UrM=#4q#x zZ)1NlZNL2nu2clsEG;FyBDZ9O;{?B2sqw=m+Vwr>`qq$;&d;#?QQo*`drk±TV^ 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 + + + + + + witchday + + +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/init.js b/init.js new file mode 100644 index 0000000..bb91f0e --- /dev/null +++ b/init.js @@ -0,0 +1,8 @@ +(function () { + + const overworld = new Overworld({ + element: document.querySelector(".game-container") + }); + overworld.init(); + +})(); \ No newline at end of file diff --git a/map-room-entrance.jpg b/map-room-entrance.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91e0f256df99aee2dd8ed26b04ceb551fc48e5f1 GIT binary patch literal 115468 zcmeI52~<-@+s7v%$gU7UkwrsD1d%l=LIh=Bg2;}5T9zb85J(J*fQo<`MF9l?rB(zH zWL3cp>%uCET31{EYeB6df`X!@D&)Jtt?&D`ygjGiIbZwvgp)ALojZ3j_dYy#?)>NX z2=59zkvzlB(GKBoI3)T(!Y))}8_Nks$k`d`AcQ2*IGhR+$5Pl<G(|?L>MiDkO2EFdWq`!{H7VwX44Jl(rL3vG$T6Agif1< zEW@~*NRkbQ9TkRwM*4;Z$ZSC@FOa!{9YqRaFXu#JKF+Qr zYc8Knnxj8Q-;j*$&1VJE-EHhX?u-3pPX5@)RjXF%ubQRLa*| zks;haDE@i#Xor2;iN*X}IWL+YHriqq(|{eu4rfP1MPg-*M1An7CC<*Di~nw0!oxq8 zj*PO6!M?^=XD!k*j>k4|XGe0Q`AoKL40c3K(ZP6hYd$+Lifx0v&B>yxNY8Mt9&NTK zb`=?#(q|dYG^80Cekke8WpRSzey`-{^@f$Ce=drhP*z}6;D0UrxvS`+q959VT}gl3 zkS{w}bHliNtW8+EXOT%?@*Sqz z(p>(>3(JGO@?$EDGygYMV`d<_NU%K8ht!912LG}@_D2*aDvbTH0?V+d&sB-eB|R)K zV!1gvR*%IF4vY?qBF_&G=?9aUW`+j@BS=bGG~LgI2tfM$>v_8Fg>A@ByBM z-7@;Sy1UppF0{pla9GWrVa)JIf+0fT*iD+~9@59xk0jBJB#<(ih>hh80-2FKXAe8i z(K>(k3=12nV8c5}tjK&Oj~|7l9kBGmRZ%=qItxoHGD8Ac zSh@sD>+-P%V(C^w9hiFJ2`wRWS{-V0o z&?3ae_GMz9JQRoch=Z1+5EO-UvD|2^b~g4q7|Um4KVc|N)c@Fi*y~HbMh4HKjb`Cw ztq>BwFBHDQ&auP}god{Zh3^W4!r^_`!1o?PbrE0o=jJ11@*2zE{w0sH7oiCo5IWxY zB`;_vLMJvMq};{}I;u2V-OUmj@7%^F?UlHH4&>eCRW5n`k>Kyn~SEYV1_~ zfKcwY2u;VzPgpAK!1@S#I`EfXqDuZ!1)`mWbx1)HHRA%ra0&>ofD==|37gR5(Z-3| z|LG-;CrDr$DDnu8$BQAn7`E@|HXL4zAWj^opn)bTDv@bcZdfT5(MGJqr=1ZZh-2j> zrLb+&vBTg9IC0UzKa?1)K|zCv#wn7GCekc5-2#Q}NLCDowMR?=EkK>hbk|$w2Ob?9 zkRIg8-$*t|@(M{v4M^$oxUN9
c19k;U#@Rk&9+)vvrXL(S1GDs!LJ-PbFrT*{gi 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 WEj|Y<0&fA{0=&ils<)UcZ2KP|v*z3Y literal 0 HcmV?d00001 diff --git a/style.css b/style.css new file mode 100644 index 0000000..9ca09f1 --- /dev/null +++ b/style.css @@ -0,0 +1,25 @@ +* { + box-sizing: border-box; +} + +body { + margin: 0; + padding: 0; + overflow: hidden; + background: #333; +} + +.game-container { + position: relative; + width: 352px; + height: 198px; + margin: 0 auto; + margin-top: 20px; + outline: 1px solid #fff; + + transform: scale(2) translateY(30%); +} + +.game-container canvas { + image-rendering: pixelated; +} \ No newline at end of file diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..24568b1 --- /dev/null +++ b/utils.js @@ -0,0 +1,25 @@ +const utils = { + withGrid(n) { + return n * 16; + }, + asGridCoord(x, y) { + return `${x*16},${y*16}` + }, + nextPosition(initialX, initialY, direction) { + let x = initialX; + let y = initialY; + const size = 16; + + if (direction === "left") { + x -= size; + } else if (direction === "right") { + x += size; + } else if (direction === "up") { + y -= size; + } else if (direction === "down") { + y += size; + } + + return {x, y}; + } +} \ No newline at end of file