Spaces:
Paused
Paused
Mohammad Shahid commited on
Commit ·
ffc2bc9
1
Parent(s): 0108657
fixed the prompt
Browse files- components/BattleArena.tsx +37 -36
- lib/AiPrompts.ts +5 -5
components/BattleArena.tsx
CHANGED
|
@@ -1446,6 +1446,8 @@ const BattleArena = ({ battleSetup,
|
|
| 1446 |
isDraw: boolean
|
| 1447 |
) => {
|
| 1448 |
let victoryFrameId: number;
|
|
|
|
|
|
|
| 1449 |
|
| 1450 |
const victoryLoop = () => {
|
| 1451 |
// Stop the loop if the component unmounts
|
|
@@ -1454,6 +1456,35 @@ const BattleArena = ({ battleSetup,
|
|
| 1454 |
return;
|
| 1455 |
}
|
| 1456 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1457 |
// 1. Redraw the background and final state
|
| 1458 |
ctx.save();
|
| 1459 |
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
@@ -2140,49 +2171,19 @@ const BattleArena = ({ battleSetup,
|
|
| 2140 |
|
| 2141 |
setBattleReport(report);
|
| 2142 |
|
| 2143 |
-
//
|
| 2144 |
-
|
|
|
|
| 2145 |
setTimeout(() => {
|
| 2146 |
-
// The .stop() call will trigger the onstop handler, which handles all cleanup.
|
| 2147 |
mediaRecorderRef.current?.stop();
|
| 2148 |
-
|
| 2149 |
-
// CRITICAL: Stop the game loop entirely in automation mode to save CPU
|
| 2150 |
-
if (isAutomationTriggered) {
|
| 2151 |
-
console.log("[Automation] Recording stopped - terminating game loop to save CPU");
|
| 2152 |
-
cancelAnimationFrame(animationFrameId);
|
| 2153 |
-
// Clear the canvas to black to indicate the game has stopped
|
| 2154 |
-
ctx.fillStyle = "#000000";
|
| 2155 |
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 2156 |
-
ctx.fillStyle = "white";
|
| 2157 |
-
ctx.font = "bold 32px sans-serif";
|
| 2158 |
-
ctx.textAlign = "center";
|
| 2159 |
-
ctx.fillText("Battle Complete - Processing Upload...", canvas.width / 2, canvas.height / 2);
|
| 2160 |
-
return; // Exit completely - no more rendering
|
| 2161 |
-
}
|
| 2162 |
-
}, 2500); // 2.5s delay to capture victory animation
|
| 2163 |
}
|
| 2164 |
|
| 2165 |
// --- STOP THE MAIN LOOP AND START THE VICTORY LOOP ---
|
| 2166 |
cancelAnimationFrame(animationFrameId);
|
| 2167 |
|
| 2168 |
-
//
|
| 2169 |
-
|
| 2170 |
-
console.log("[Automation] Skipping victory animation loop - CPU optimization");
|
| 2171 |
-
// Just draw final state once and stop
|
| 2172 |
-
ctx.save();
|
| 2173 |
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 2174 |
-
ctx.fillStyle = "#0f0f23";
|
| 2175 |
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 2176 |
-
ctx.fillStyle = "white";
|
| 2177 |
-
ctx.font = "bold 48px sans-serif";
|
| 2178 |
-
ctx.textAlign = "center";
|
| 2179 |
-
const winnerName = gameState.winner ? gameState.winner.name : "DRAW";
|
| 2180 |
-
ctx.fillText(`${winnerName.toUpperCase()} WINS!`, canvas.width / 2, canvas.height / 2);
|
| 2181 |
-
ctx.restore();
|
| 2182 |
-
} else {
|
| 2183 |
-
// Normal victory sequence for manual mode
|
| 2184 |
-
startVictorySequence(gameState.winner, activeFighters.length === 0);
|
| 2185 |
-
}
|
| 2186 |
|
| 2187 |
return; // Exit the game loop immediately
|
| 2188 |
}
|
|
|
|
| 1446 |
isDraw: boolean
|
| 1447 |
) => {
|
| 1448 |
let victoryFrameId: number;
|
| 1449 |
+
let victoryFrameCount = 0;
|
| 1450 |
+
const maxVictoryFrames = isAutomationTriggered ? 25 * 2.5 : Infinity; // 2.5 seconds at 25fps for automation, infinite for manual
|
| 1451 |
|
| 1452 |
const victoryLoop = () => {
|
| 1453 |
// Stop the loop if the component unmounts
|
|
|
|
| 1456 |
return;
|
| 1457 |
}
|
| 1458 |
|
| 1459 |
+
// In automation mode, stop the victory animation after 2.5 seconds
|
| 1460 |
+
if (isAutomationTriggered && victoryFrameCount >= maxVictoryFrames) {
|
| 1461 |
+
console.log("[Automation] Victory animation complete, stopping canvas rendering and recording");
|
| 1462 |
+
|
| 1463 |
+
// Stop recording if it's still running
|
| 1464 |
+
if (mediaRecorderRef.current?.state === "recording") {
|
| 1465 |
+
console.log("[Automation] Stopping recording after victory animation");
|
| 1466 |
+
mediaRecorderRef.current.stop();
|
| 1467 |
+
}
|
| 1468 |
+
|
| 1469 |
+
// Draw final static frame
|
| 1470 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1471 |
+
ctx.fillStyle = "#000000";
|
| 1472 |
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 1473 |
+
ctx.fillStyle = "#ffffff";
|
| 1474 |
+
ctx.font = "bold 32px sans-serif";
|
| 1475 |
+
ctx.textAlign = "center";
|
| 1476 |
+
ctx.fillText("Battle Complete", canvas.width / 2, canvas.height / 2 - 40);
|
| 1477 |
+
ctx.fillStyle = "#00ff00";
|
| 1478 |
+
ctx.font = "24px sans-serif";
|
| 1479 |
+
ctx.fillText("Processing upload...", canvas.width / 2, canvas.height / 2 + 20);
|
| 1480 |
+
|
| 1481 |
+
// Stop the animation loop - this will drop CPU to ~0%
|
| 1482 |
+
cancelAnimationFrame(victoryFrameId);
|
| 1483 |
+
return;
|
| 1484 |
+
}
|
| 1485 |
+
|
| 1486 |
+
victoryFrameCount++;
|
| 1487 |
+
|
| 1488 |
// 1. Redraw the background and final state
|
| 1489 |
ctx.save();
|
| 1490 |
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
|
| 2171 |
|
| 2172 |
setBattleReport(report);
|
| 2173 |
|
| 2174 |
+
// In automation mode, we'll let the victory sequence handle recording stop timing
|
| 2175 |
+
// For manual mode, stop recording after a delay
|
| 2176 |
+
if (!isAutomationTriggered && mediaRecorderRef.current?.state === "recording") {
|
| 2177 |
setTimeout(() => {
|
|
|
|
| 2178 |
mediaRecorderRef.current?.stop();
|
| 2179 |
+
}, 2500); // 2.5s delay to capture victory animation in manual mode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2180 |
}
|
| 2181 |
|
| 2182 |
// --- STOP THE MAIN LOOP AND START THE VICTORY LOOP ---
|
| 2183 |
cancelAnimationFrame(animationFrameId);
|
| 2184 |
|
| 2185 |
+
// Start the victory sequence (it will handle automation timing internally)
|
| 2186 |
+
startVictorySequence(gameState.winner, activeFighters.length === 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2187 |
|
| 2188 |
return; // Exit the game loop immediately
|
| 2189 |
}
|
lib/AiPrompts.ts
CHANGED
|
@@ -114,13 +114,13 @@ Your response MUST be a single, valid JSON object. Do not add any text, explanat
|
|
| 114 |
- **TANK/BERSERKER Attack:** Tier 6 (6 pts) -> 24 Dmg, Tier 7 (7 pts) -> 28 Dmg
|
| 115 |
|
| 116 |
**BASIC ATTACK TYPE (Choose ONE, costs points):**
|
| 117 |
-
- **'CONTACT'**: 1 point. (Berserker cost is 0.5 pts). Deals damage on collision.
|
| 118 |
- **'MELEE'**: 1 point. (Brawler cost is 0.5 pts). Close-range attack. Range 250-350.
|
| 119 |
- **'RANGED'**: 2 points. (Marksman cost is 1 pt). Fires a projectile. Range 500-700.
|
| 120 |
|
| 121 |
-
**BASIC ATTACK COOLDOWN (Costs points, only for 'MELEE' or 'RANGED'):**
|
| 122 |
-
- **Melee Cooldown:** 1.5s (3 pts), 2.0s (2 pts), 2.5s (1 pt)
|
| 123 |
-
- **Ranged Cooldown:**
|
| 124 |
|
| 125 |
- **heroHealth:** Use the HP value from your chosen Health tier.
|
| 126 |
- **heroSpeed:** Use the speed multiplier from your chosen Speed tier.
|
|
@@ -128,7 +128,7 @@ Your response MUST be a single, valid JSON object. Do not add any text, explanat
|
|
| 128 |
**Step 4: Design the Basic Attack**
|
| 129 |
- **type:** 'RANGED', 'MELEE', or 'CONTACT'.
|
| 130 |
- **damage:** Use the value from your chosen Attack tier.
|
| 131 |
-
- **cooldown:** Time in seconds.
|
| 132 |
- **range:** Max distance. 0 for 'CONTACT'.
|
| 133 |
- **knockback:** A value between 10-15.
|
| 134 |
|
|
|
|
| 114 |
- **TANK/BERSERKER Attack:** Tier 6 (6 pts) -> 24 Dmg, Tier 7 (7 pts) -> 28 Dmg
|
| 115 |
|
| 116 |
**BASIC ATTACK TYPE (Choose ONE, costs points):**
|
| 117 |
+
- **'CONTACT'**: 1 point. (Berserker cost is 0.5 pts). Deals damage on collision. Cooldown is required and must be chosen from the MELEE cooldown table below.
|
| 118 |
- **'MELEE'**: 1 point. (Brawler cost is 0.5 pts). Close-range attack. Range 250-350.
|
| 119 |
- **'RANGED'**: 2 points. (Marksman cost is 1 pt). Fires a projectile. Range 500-700.
|
| 120 |
|
| 121 |
+
**BASIC ATTACK COOLDOWN (Costs points, only for 'MELEE', 'CONTACT', or 'RANGED'):**
|
| 122 |
+
- **Melee/Contact Cooldown:** 1.5s (3 pts), 2.0s (2 pts), 2.5s (1 pt)
|
| 123 |
+
- **Ranged Cooldown:** 2.0s (4 pts), 3.5s (2 pts), 4.0s (1 pt)
|
| 124 |
|
| 125 |
- **heroHealth:** Use the HP value from your chosen Health tier.
|
| 126 |
- **heroSpeed:** Use the speed multiplier from your chosen Speed tier.
|
|
|
|
| 128 |
**Step 4: Design the Basic Attack**
|
| 129 |
- **type:** 'RANGED', 'MELEE', or 'CONTACT'.
|
| 130 |
- **damage:** Use the value from your chosen Attack tier.
|
| 131 |
+
- **cooldown:** Time in seconds. For 'CONTACT', use the same cooldown options as 'MELEE'.
|
| 132 |
- **range:** Max distance. 0 for 'CONTACT'.
|
| 133 |
- **knockback:** A value between 10-15.
|
| 134 |
|