Add pokeball bounce sequence after catch: Pokemon disappears, ball rests and bounces with SFX before showing result
This commit is contained in:
@@ -267,6 +267,7 @@ const SFX = (() => {
|
|||||||
confirm() { seq([{f:523,d:.08},{f:784,d:.15}], 'square', 0.18); },
|
confirm() { seq([{f:523,d:.08},{f:784,d:.15}], 'square', 0.18); },
|
||||||
catch() { seq([{f:330,d:.08},{f:440,d:.08},{f:523,d:.08},{f:659,d:.15},{f:784,d:.25}], 'square', 0.2); },
|
catch() { seq([{f:330,d:.08},{f:440,d:.08},{f:523,d:.08},{f:659,d:.15},{f:784,d:.25}], 'square', 0.2); },
|
||||||
pokeball() { seq([{f:600,d:.06},{f:500,d:.06},{f:400,d:.06},{f:300,d:.1}], 'triangle', 0.15); },
|
pokeball() { seq([{f:600,d:.06},{f:500,d:.06},{f:400,d:.06},{f:300,d:.1}], 'triangle', 0.15); },
|
||||||
|
pokeballBounce() { seq([{f:300,d:.04},{f:500,d:.06},{f:200,d:.08}], 'triangle', 0.12); },
|
||||||
escape() { seq([{f:400,d:.08},{f:350,d:.08},{f:250,d:.15}], 'sawtooth', 0.12); },
|
escape() { seq([{f:400,d:.08},{f:350,d:.08},{f:250,d:.15}], 'sawtooth', 0.12); },
|
||||||
attack() { seq([{f:200,d:.04},{f:400,d:.04},{f:600,d:.04},{f:800,d:.03},{f:1000,d:.03},{f:600,d:.06}], 'sawtooth', 0.2); },
|
attack() { seq([{f:200,d:.04},{f:400,d:.04},{f:600,d:.04},{f:800,d:.03},{f:1000,d:.03},{f:600,d:.06}], 'sawtooth', 0.2); },
|
||||||
battleWin() { seq([{f:523,d:.1},{f:659,d:.1},{f:784,d:.12},{f:1047,d:.15},{f:1319,d:.25}], 'square', 0.22); },
|
battleWin() { seq([{f:523,d:.1},{f:659,d:.1},{f:784,d:.12},{f:1047,d:.15},{f:1319,d:.25}], 'square', 0.22); },
|
||||||
@@ -1445,6 +1446,8 @@ class Game {
|
|||||||
|
|
||||||
const catchScreen = document.getElementById('screen-catch');
|
const catchScreen = document.getElementById('screen-catch');
|
||||||
const pokemonEl = document.getElementById('catch-wild-pokemon');
|
const pokemonEl = document.getElementById('catch-wild-pokemon');
|
||||||
|
const nameEl = document.getElementById('catch-wild-name');
|
||||||
|
const levelEl = document.getElementById('catch-wild-level');
|
||||||
|
|
||||||
const ball = document.createElement('img');
|
const ball = document.createElement('img');
|
||||||
ball.src = './favicon.ico';
|
ball.src = './favicon.ico';
|
||||||
@@ -1454,24 +1457,53 @@ class Game {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const pokeRect = pokemonEl.getBoundingClientRect();
|
const pokeRect = pokemonEl.getBoundingClientRect();
|
||||||
const screenRect = catchScreen.getBoundingClientRect();
|
const screenRect = catchScreen.getBoundingClientRect();
|
||||||
|
const burstX = pokeRect.left - screenRect.left + pokeRect.width / 2;
|
||||||
|
const burstY = pokeRect.top - screenRect.top + pokeRect.height * 0.25;
|
||||||
|
|
||||||
const burst = document.createElement('div');
|
const burst = document.createElement('div');
|
||||||
burst.className = 'pokeball-burst';
|
burst.className = 'pokeball-burst';
|
||||||
burst.style.left = (pokeRect.left - screenRect.left + pokeRect.width / 2) + 'px';
|
burst.style.left = burstX + 'px';
|
||||||
burst.style.top = (pokeRect.top - screenRect.top + pokeRect.height * 0.25) + 'px';
|
burst.style.top = burstY + 'px';
|
||||||
catchScreen.appendChild(burst);
|
catchScreen.appendChild(burst);
|
||||||
|
|
||||||
ball.remove();
|
ball.remove();
|
||||||
pokemonEl.style.opacity = '0';
|
pokemonEl.style.opacity = '0';
|
||||||
pokemonEl.style.transform = 'scale(0.3)';
|
pokemonEl.style.transform = 'scale(0)';
|
||||||
pokemonEl.style.transition = 'opacity .3s, transform .3s';
|
pokemonEl.style.transition = 'opacity .2s, transform .2s';
|
||||||
|
if (nameEl) nameEl.style.display = 'none';
|
||||||
|
if (levelEl) levelEl.style.display = 'none';
|
||||||
|
|
||||||
setTimeout(() => {
|
const restBall = document.createElement('img');
|
||||||
burst.remove();
|
restBall.src = './favicon.ico';
|
||||||
pokemonEl.style.opacity = '1';
|
restBall.className = 'pokeball-rest';
|
||||||
pokemonEl.style.transform = '';
|
restBall.style.left = (burstX - 20) + 'px';
|
||||||
pokemonEl.style.transition = '';
|
restBall.style.top = (burstY + 20) + 'px';
|
||||||
this._showCatchResult(wild, canCatch);
|
catchScreen.appendChild(restBall);
|
||||||
}, 600);
|
|
||||||
|
setTimeout(() => burst.remove(), 500);
|
||||||
|
|
||||||
|
let bounceCount = 0;
|
||||||
|
const doBounce = () => {
|
||||||
|
const maxBounces = canCatch ? 3 : 2;
|
||||||
|
if (bounceCount >= maxBounces) {
|
||||||
|
restBall.remove();
|
||||||
|
pokemonEl.style.opacity = '1';
|
||||||
|
pokemonEl.style.transform = '';
|
||||||
|
pokemonEl.style.transition = '';
|
||||||
|
if (nameEl) nameEl.style.display = '';
|
||||||
|
if (levelEl) levelEl.style.display = '';
|
||||||
|
this._showCatchResult(wild, canCatch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bounceCount++;
|
||||||
|
SFX.pokeballBounce();
|
||||||
|
restBall.classList.remove('pokeball-bounce-anim');
|
||||||
|
void restBall.offsetWidth;
|
||||||
|
restBall.classList.add('pokeball-bounce-anim');
|
||||||
|
setTimeout(doBounce, 600);
|
||||||
|
};
|
||||||
|
|
||||||
|
setTimeout(doBounce, 600);
|
||||||
}, 700);
|
}, 700);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1425,3 +1425,24 @@ html, body {
|
|||||||
.party-select-badge.badge-fainted {
|
.party-select-badge.badge-fainted {
|
||||||
color:var(--red);
|
color:var(--red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── POKEBALL REST + BOUNCE ─────────────────────────────── */
|
||||||
|
.pokeball-rest {
|
||||||
|
position:absolute;
|
||||||
|
width:40px;
|
||||||
|
height:40px;
|
||||||
|
z-index:200;
|
||||||
|
image-rendering:pixelated;
|
||||||
|
}
|
||||||
|
.pokeball-bounce-anim {
|
||||||
|
animation:pokeballBounce .5s ease-out;
|
||||||
|
}
|
||||||
|
@keyframes pokeballBounce {
|
||||||
|
0% { transform:translateY(0); }
|
||||||
|
20% { transform:translateY(-24px) rotate(-10deg); }
|
||||||
|
40% { transform:translateY(0) rotate(0deg); }
|
||||||
|
55% { transform:translateY(-12px) rotate(8deg); }
|
||||||
|
70% { transform:translateY(0) rotate(0deg); }
|
||||||
|
82% { transform:translateY(-5px) rotate(-4deg); }
|
||||||
|
100% { transform:translateY(0) rotate(0deg); }
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user