Skip to content

Commit 8547aa7

Browse files
committed
feat: implement attack/ultimate movement intent thresholds and player engagement idle logic in battle mode
1 parent 5695fbb commit 8547aa7

2 files changed

Lines changed: 26 additions & 8 deletions

File tree

app.min.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ const BATTLE_ARROW_HEAD = 170;
7979
const BATTLE_ARROW_RECOVER_TIME = 0.22;
8080
const BATTLE_DESPAWN_MARGIN = 360;
8181
const BATTLE_EXPLOSION_MASK = PERF_TIER >= 1.5 ? 31 : 63;
82+
const ATTACK_INTENT_SPEED = 2.4;
83+
const ULTIMATE_INTENT_SPEED = 7.5;
84+
const PLAYER_ENGAGED_MS = 4500;
8285
const BATTLE_TINT_P1 = { r: 0.44, g: 0.36, b: 1.0 };
8386
const BATTLE_TINT_P2 = { r: 0.82, g: 0.28, b: 1.0 };
8487
const BATTLE_EXPLOSION_DEFAULT = { r: 1, g: 0.7, b: 0.2 };
@@ -129,7 +132,8 @@ const battle = {
129132
explosions: [],
130133
roundOver: false,
131134
roundResetTime: 0,
132-
winner: null
135+
winner: null,
136+
lastPlayerActionAt: 0
133137
};
134138

135139
// === AUDIO ===
@@ -266,6 +270,7 @@ function resetBattle() {
266270
battle.roundOver = false;
267271
battle.roundResetTime = 0;
268272
battle.winner = null;
273+
battle.lastPlayerActionAt = 0;
269274
}
270275

271276
function getBattleGesture(landmarks, isPinching) {
@@ -398,6 +403,7 @@ function tryFireChargedAttack(fighter) {
398403
const enemy = (fighter === battle.p1) ? battle.p2 : battle.p1;
399404
if (enemy.active && fighter.chargeAmount > 0.08) {
400405
fireBattleBeam(fighter, enemy, fighter.lastAttackGesture || 'normal');
406+
if (fighter === battle.p1) battle.lastPlayerActionAt = Date.now();
401407
} else {
402408
fighter.chargeAmount = 0;
403409
fighter.charging = false;
@@ -424,7 +430,10 @@ function updateFighterFromHand(fighter, hand, landmarks) {
424430
fighter.shielding = isShielding;
425431
fighter.shieldStrength += ((isShielding ? 1.0 : 0) - fighter.shieldStrength) * 0.25;
426432

427-
const isAttacking = (gesture === 'pinch' || gesture === 'volley' || gesture === 'fireball');
433+
const isDirectAttack = gesture === 'pinch';
434+
const isGestureAttack = (gesture === 'volley' || gesture === 'fireball');
435+
const hasAttackIntent = isDirectAttack || fighter.charging || hand.speed > ATTACK_INTENT_SPEED;
436+
const isAttacking = isDirectAttack || (isGestureAttack && hasAttackIntent);
428437
const wasAttacking = fighter.charging;
429438

430439
if (gesture === 'fist' && wasAttacking && !fighter.shielding) {
@@ -438,6 +447,7 @@ function updateFighterFromHand(fighter, hand, landmarks) {
438447
fighter.chargeAmount = Math.min(1, fighter.chargeAmount + (gesture === 'fireball' ? 0.025 : 0.032));
439448
fighter.pinchLossFrames = 0;
440449
fighter.lastAttackGesture = gesture;
450+
if (fighter === battle.p1) battle.lastPlayerActionAt = Date.now();
441451
} else if (wasAttacking && !isAttacking && !fighter.shielding) {
442452
fighter.pinchLossFrames = (fighter.pinchLossFrames || 0) + 1;
443453
if (fighter.pinchLossFrames < 4) {
@@ -1133,7 +1143,8 @@ function updateBattleState(hasTwoHands) {
11331143
}
11341144
battle.p2.pos.lerp(battle.p2.targetPos, 0.01);
11351145

1136-
if (!battle.roundOver && battle.p1.active) {
1146+
const playerEngaged = battle.p1.charging || battle.p1.beam.active || Date.now() - battle.lastPlayerActionAt < PLAYER_ENGAGED_MS;
1147+
if (!battle.roundOver && battle.p1.active && playerEngaged) {
11371148
if (!battle.p2.charging && Math.random() < 0.004) battle.p2.charging = true;
11381149
if (battle.p2.charging) {
11391150
battle.p2.chargeAmount = Math.min(1, battle.p2.chargeAmount + 0.012);
@@ -1147,6 +1158,11 @@ function updateBattleState(hasTwoHands) {
11471158
if (battle.p2.shielding && Math.random() < 0.025) battle.p2.shielding = false;
11481159
battle.p2.shieldStrength += ((battle.p2.shielding ? 1.0 : 0) - battle.p2.shieldStrength) * 0.12;
11491160
}
1161+
} else {
1162+
battle.p2.charging = false;
1163+
battle.p2.chargeAmount *= 0.88;
1164+
battle.p2.shielding = false;
1165+
battle.p2.shieldStrength *= 0.9;
11501166
}
11511167
} else {
11521168
if (hasTwoHands) {
@@ -1173,7 +1189,8 @@ function updateBattleState(hasTwoHands) {
11731189
}
11741190

11751191
// ULTIMATE DIAMOND COMBO DETECT (works in both Battle and Survival if you use 2 hands)
1176-
if (battleModeActive && !battle.roundOver && comboCount >= 0 && hands.left.active && hands.right.active) {
1192+
const ultimateIntent = (hands.left.pinch && hands.right.pinch) || (hands.left.speed + hands.right.speed) > ULTIMATE_INTENT_SPEED;
1193+
if (battleModeActive && !battle.roundOver && comboCount >= 0 && hands.left.active && hands.right.active && ultimateIntent) {
11771194
const dx = hands.left.pos.x - hands.right.pos.x;
11781195
const dy = hands.left.pos.y - hands.right.pos.y;
11791196
const distSq = dx * dx + dy * dy;
@@ -1257,7 +1274,8 @@ function animate() {
12571274
const p2BeamPush = 5 + p2Beam.power * 7;
12581275

12591276
// Supernova trigger (duel mode)
1260-
if (isDuelMode && hasTwoHands) {
1277+
const duelIntent = (hands.left.pinch && hands.right.pinch) || (hands.left.speed + hands.right.speed) > ULTIMATE_INTENT_SPEED;
1278+
if (isDuelMode && hasTwoHands && duelIntent) {
12611279
const ax = hands.right.pos.x - hands.left.pos.x;
12621280
const ay = hands.right.pos.y - hands.left.pos.y;
12631281
const az = hands.right.pos.z - hands.left.pos.z;

index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<span class="ico"></span> Swarm: 1 finger &nbsp;•&nbsp;
4141
<span class="ico">✌️</span> Duel: 2 hands &nbsp;•&nbsp;
4242
<span class="ico">🤏</span> Pinch = boost &nbsp;•&nbsp;
43-
<span class="ico">⚔️</span> Battle: pinch/3/open = charge, fist/release = fire, 2 fingers = shield &nbsp;•&nbsp;
43+
<span class="ico">⚔️</span> Battle: pinch or move with 3/open = charge, fist/release = fire &nbsp;•&nbsp;
4444
<span class="ico">🎵</span> Audio reacts to music
4545
</div>
4646

@@ -67,7 +67,7 @@
6767
<strong>Manual</strong>
6868
<p><b>Swarm</b> — show one index finger and move it around.</p>
6969
<p><b>Duel</b> — needs two hands; particles split into two swarms following each index finger.</p>
70-
<p><b>Battle ⚡</b> — pinch, 3 fingers, or open hand to charge; make a fist or release to fire. Index + middle fingers shield.</p>
70+
<p><b>Battle ⚡</b> — pinch to charge, or move your hand with 3 fingers/open hand; make a fist or release to fire. Index + middle fingers shield.</p>
7171
<p><b>Pinch</b> — boosts that hand's gravity 3×, particles glow gold.</p>
7272
<p><b>Supernova 💥</b> — in Duel mode, bring hands close together to detonate.</p>
7373
<p><b>Beat-Drop 🎵</b> — load music or use mic; particles pulse to bass and beats.</p>
@@ -115,7 +115,7 @@
115115

116116
<div id="footer">Created by <b>Yogender</b> · Quantum Flux v2.1</div>
117117

118-
<script src="app.min.js?v=2.3.5"></script>
118+
<script src="app.min.js?v=2.3.6"></script>
119119
</body>
120120

121121
</html>

0 commit comments

Comments
 (0)