From 428f1a2f742a671f1c9efc39c2284b7fd6c0b504 Mon Sep 17 00:00:00 2001 From: Justin Oros Date: Thu, 14 May 2026 13:16:21 -0700 Subject: [PATCH] =?UTF-8?q?Replace=20hat=20emoji=20with=20player.png=20spr?= =?UTF-8?q?ite=20sheet=20=E2=80=94=20directional=20walk=20animations=20fro?= =?UTF-8?q?m=2024-frame=20sheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game.js | 12 +++++++----- index.html | 2 +- player.png | Bin 0 -> 6325 bytes style.css | 31 ++++++++++++++++++++----------- 4 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 player.png diff --git a/game.js b/game.js index 33e46d0..f50e752 100644 --- a/game.js +++ b/game.js @@ -346,8 +346,10 @@ class Game { const p = document.getElementById('map-player'); if (p) { p.className = 'map-player idle'; - /* keep facing the last direction moved */ - p.style.transform = this.state.lastDir === 'right' ? 'scaleX(-1)' : 'scaleX(1)'; + /* Show the idle/middle frame for the last direction walked + Frames at 2× scale (32px each): down=32, up=128, left=224, right=320 */ + const idleFrames = { down:'-32px', up:'-128px', left:'-224px', right:'-320px' }; + p.style.backgroundPositionX = idleFrames[this.state.lastDir] || '-32px'; } } } @@ -382,7 +384,7 @@ class Game { /* Player sprite stays horizontally centred; only Y shifts */ const p = document.getElementById('map-player'); if (p) { - const centreX = viewW / 2 - 20; + const centreX = viewW / 2 - 16; const centreY = viewH * 0.57 + this.state.worldY; p.style.left = centreX + 'px'; p.style.bottom = (viewH - centreY - 40) + 'px'; @@ -463,9 +465,9 @@ class Game { const p = document.getElementById('map-player'); if (p) { - p.style.left = (viewW / 2 - 20) + 'px'; + p.style.left = (viewW / 2 - 16) + 'px'; p.style.bottom = (viewH * 0.36) + 'px'; - p.style.transform = 'scaleX(-1)'; + p.className = 'map-player idle'; } this._applyCamera(); diff --git a/index.html b/index.html index 7b2d29c..9d47845 100644 --- a/index.html +++ b/index.html @@ -109,7 +109,7 @@
-
🧢
+
diff --git a/player.png b/player.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d5c316cfcf89261791ecbde37e84d4d00179ef GIT binary patch literal 6325 zcmeI0U1$_n6vxk{39N!LC+l=S@_~s#1Yf#NwWbIrA%2zCX4FuZRIw`CR~Ie21zUC% zyDJ9CHZ1KnE$u>IieRxNpf0uzR*Vn|K3HsnEqM?>3VChmQ_s2go{5f;BJ`~p)Zg5D z|M!2-|IB1JczST>wq;9`O95cnj_m`x091kQS2jII|2{bJ&Ci4v24CH?W$OETktIuh z>U8Gj{yqTlRcqG#xvT&7=#hMHZ|Cc`UmM*0{e}V40P(du2Kx5oe^o2vzuzOx;9a!wZVh8@u9q4m$ z#X|WJU0i6s&-b56zmUg&IoGtx^Vao}qXe;3yFG8cL-UB}^MRK0dK<(BdYYcM>Z{Ln zb#P(GSNy4t$8|D(n!f3f7v0bcAcYB=J-R4>6ec9Sw~$`3e(*^>*nr|I6u&TKJI*t9#E$#|Ur5=7X~0lJZNHi%`5m&v5o_d*cF1_}xZ>BTS1u&<26 zzB0y^Rfy}TP%13SK`gg+KA*`P>_iD7RQ;>ymFsrU1c87pt23FmS`LE*5lR8Z*HPAA z{KDk(b%Vkbzc5ux7hRnWm>?+J%F{G2L4--8uS<}CdcNy0+8{z{2sJ9@t?TqHLHxoD z{A{CSEPi1E9^*o{p#%|{09X%#u#5uXm&{ij2@()_zU#2rKTj!G*#_As?u3119QfHr z$vEsQV^GBDrg8;{m>>=s(!|vD z<5~J1kRU=uUnrD|po5q|K25}~A0H{uya^(df>n&4bQXoim-cC2AC;ja4bt@KR{?35 zZ+#6Nv||#)bGafyX`=~Z0-elL<+*&30!R>{dk*ok50NbT9E2(+#;Ec*ZJ@7Q8$=is ztoTW@-ctKffrh@?%MC+_Omc(T3RE~<+MjQzPSYU6Q;sX+$kiUiu}y_iii7Y5W|T_V zTXY+Bs>lYhj9eS9)h@kRhzxNM)-#6+ki6{2PjLVVVyJvB*rg}*s6Xw~eq^9x)F>kI zIj$3VXB_d;8wF6~6-<-?%04D8k?frKG3gcNah7}{xt?lzELTu&je?{Aq7^ENx|F&T}~kVCAJOap@mdX1@D^{@0R%T;v1JP@qxL-Q?q`@Y2x)G8+{y$NO(o z)1UG}d^#~pfR4&EKN<4Rx07F_n5Z$q-Cz5d78LulzV%LHmS3Tc#+?f^Y`|2Q@K=x=?=Vg#Xg{2#4?Vu(MfRbMa|ssUkp7_sym&_I>g5Z1S+$mv zw5&Sx8_6GkL%i<#b6N&!$e}+p)A7(u0G`*KQbRt?(oS@FUAaDg7?7SESbyFgLs!R!-MU~fdP9AzsJy;eV>H|N_~5WQ(D``VylXoc2Iwvo;r^XT3D p>XUcRs(;eqUuJ>|gPR35TzmP$&1Y|X@HH>(*s^oreE)$H{{X-k!7~5= literal 0 HcmV?d00001 diff --git a/style.css b/style.css index fc2664f..0930e50 100644 --- a/style.css +++ b/style.css @@ -100,10 +100,12 @@ html, body { @keyframes wrongShake { 0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)} } @keyframes npcFloat { 0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)} } @keyframes treeSway { 0%,100%{transform:rotate(-2deg)}50%{transform:rotate(2deg)} } -@keyframes walkLeft { 0%,100%{transform:scaleX(1) translateY(0)}50%{transform:scaleX(1) translateY(-4px)} } -@keyframes walkRight { 0%,100%{transform:scaleX(-1) translateY(0)}50%{transform:scaleX(-1) translateY(-4px)} } -@keyframes walkUp { 0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)} } -@keyframes walkDown { 0%,100%{transform:translateY(0)}50%{transform:translateY(4px)} } +/* Sprite walk — player.png 384x32px, 24 frames at 16x32px each + Layout: 0-2=down 3-5=up 6-8=left 9-11=right */ +@keyframes walkDown { from{background-position-x: 0px} to{background-position-x: -96px} } +@keyframes walkUp { from{background-position-x: -96px} to{background-position-x: -192px} } +@keyframes walkLeft { from{background-position-x:-192px} to{background-position-x: -288px} } +@keyframes walkRight { from{background-position-x:-288px} to{background-position-x: -384px} } @keyframes dpadPress { 0%{transform:scale(1)}50%{transform:scale(.88)}100%{transform:scale(1)} } @keyframes abPress { 0%{transform:scale(1)}40%{transform:scale(.82)}100%{transform:scale(1)} } @keyframes choiceCursor { 0%,100%{box-shadow:0 0 0 3px var(--yellow), 2px 2px 0 var(--darkgray)}50%{box-shadow:0 0 0 3px #ffe878, 2px 2px 0 var(--darkgray)} } @@ -469,16 +471,23 @@ html, body { /* Player is fixed to the viewport centre horizontally; only Y moves */ .map-player { position: absolute; - font-size: clamp(28px, 8vw, 40px); + width: 32px; + height: 64px; + background-image: url('./player.png'); + background-repeat: no-repeat; + background-size: 768px 64px; + background-position: 0 0; + image-rendering: pixelated; filter: drop-shadow(2px 3px 0 rgba(0,0,0,.4)); z-index: 10; - line-height: 1; + font-size: 0; + color: transparent; } -.map-player.walk-left { animation: walkLeft .25s steps(1) infinite; } -.map-player.walk-right { animation: walkRight .25s steps(1) infinite; } -.map-player.walk-up { animation: walkUp .25s steps(1) infinite; } -.map-player.walk-down { animation: walkDown .25s steps(1) infinite; } -.map-player.idle { animation: none; } +.map-player.walk-down { animation: walkDown .32s steps(3) infinite; } +.map-player.walk-up { animation: walkUp .32s steps(3) infinite; } +.map-player.walk-left { animation: walkLeft .32s steps(3) infinite; } +.map-player.walk-right { animation: walkRight .32s steps(3) infinite; } +.map-player.idle { animation: none; background-position-x: 0px; } /* Talk hint that floats above player when near NPC */ .map-talk-hint {