mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-23 04:08:03 +00:00
fix: update combat configurations and debug visuals for improved gameplay and debugging experience
This commit is contained in:
@@ -43,12 +43,12 @@ export const COMBAT_CONFIG = {
|
||||
npc: {
|
||||
defaultMaxHP: 100,
|
||||
defaultPunchDamage: 10,
|
||||
defaultPunchRange: 50,
|
||||
defaultPunchRange: 32,
|
||||
defaultAttackCooldown: 2000,
|
||||
attackWindupDuration: 500,
|
||||
chaseSpeed: 120,
|
||||
chaseRange: 400,
|
||||
attackStopDistance: 45
|
||||
attackStopDistance: 32
|
||||
},
|
||||
ui: {
|
||||
maxHearts: 5,
|
||||
|
||||
@@ -707,7 +707,7 @@ export async function create() {
|
||||
|
||||
// Initialize NPC Behavior Manager (async lazy loading)
|
||||
if (window.npcManager) {
|
||||
import('../systems/npc-behavior.js?v=6')
|
||||
import('../systems/npc-behavior.js?v=7')
|
||||
.then(module => {
|
||||
window.npcBehaviorManager = new module.NPCBehaviorManager(this, window.npcManager);
|
||||
console.log('✅ NPC Behavior Manager initialized');
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
CLICK_INDICATOR_DURATION,
|
||||
SPRITE_PADDING_BOTTOM_ATLAS,
|
||||
SPRITE_PADDING_BOTTOM_LEGACY
|
||||
} from '../utils/constants.js?v=8';
|
||||
} from '../utils/constants.js?v=9';
|
||||
|
||||
export let player = null;
|
||||
export let targetPoint = null;
|
||||
@@ -763,67 +763,77 @@ function drawPathDebug(fromX, fromY, smoothed, raw) {
|
||||
}
|
||||
if (!gameRef || !smoothed || smoothed.length === 0) return;
|
||||
|
||||
const debugMode = !!window.breakEscapeDebug;
|
||||
const g = gameRef.add.graphics();
|
||||
g.setDepth(900); // above most objects, below UI
|
||||
pathDebugGraphics = g;
|
||||
|
||||
// --- Raw path nodes (small grey circles) ---
|
||||
if (raw && raw.length > 0) {
|
||||
g.fillStyle(0x888888, 0.55);
|
||||
for (const p of raw) {
|
||||
g.fillCircle(p.x, p.y, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: all points including player origin
|
||||
const allPoints = [{ x: fromX, y: fromY }, ...smoothed];
|
||||
|
||||
// --- Smoothed path line ---
|
||||
g.lineStyle(2, 0x00ffff, 0.9);
|
||||
g.beginPath();
|
||||
g.moveTo(allPoints[0].x, allPoints[0].y);
|
||||
for (let i = 1; i < allPoints.length; i++) {
|
||||
g.lineTo(allPoints[i].x, allPoints[i].y);
|
||||
}
|
||||
g.strokePath();
|
||||
|
||||
// --- Waypoint circles + index labels ---
|
||||
for (let i = 0; i < smoothed.length; i++) {
|
||||
const p = smoothed[i];
|
||||
// Outer ring
|
||||
g.lineStyle(2, 0x00ffff, 1);
|
||||
g.fillStyle(0x003333, 0.7);
|
||||
g.fillCircle(p.x, p.y, 7);
|
||||
g.strokeCircle(p.x, p.y, 7);
|
||||
// Index text in scene (not part of graphics object)
|
||||
const label = gameRef.add.text(p.x + 9, p.y - 7, String(i + 1), {
|
||||
fontSize: '10px', color: '#00ffff', stroke: '#000000', strokeThickness: 2
|
||||
}).setDepth(901).setAlpha(0.9);
|
||||
// Track labels so they can be cleared with the graphics
|
||||
if (!g._debugLabels) g._debugLabels = [];
|
||||
g._debugLabels.push(label);
|
||||
}
|
||||
|
||||
// --- Fade-out tween (3 s) ---
|
||||
gameRef.tweens.add({
|
||||
targets: g,
|
||||
alpha: { from: 1, to: 0 },
|
||||
duration: 3000,
|
||||
ease: 'Linear',
|
||||
onUpdate: () => {
|
||||
// Keep labels in sync with graphics alpha
|
||||
if (g._debugLabels) {
|
||||
for (const lbl of g._debugLabels) lbl.setAlpha(g.alpha);
|
||||
}
|
||||
},
|
||||
onComplete: () => {
|
||||
if (g._debugLabels) {
|
||||
for (const lbl of g._debugLabels) lbl.destroy();
|
||||
}
|
||||
g.destroy();
|
||||
if (pathDebugGraphics === g) pathDebugGraphics = null;
|
||||
if (debugMode) {
|
||||
// ── FULL DEBUG VIEW ──────────────────────────────────────────────────
|
||||
// Raw path nodes (small grey circles)
|
||||
if (raw && raw.length > 0) {
|
||||
g.fillStyle(0x888888, 0.55);
|
||||
for (const p of raw) g.fillCircle(p.x, p.y, 3);
|
||||
}
|
||||
});
|
||||
|
||||
// Smoothed path — cyan line
|
||||
g.lineStyle(2, 0x00ffff, 0.9);
|
||||
g.beginPath();
|
||||
g.moveTo(allPoints[0].x, allPoints[0].y);
|
||||
for (let i = 1; i < allPoints.length; i++) g.lineTo(allPoints[i].x, allPoints[i].y);
|
||||
g.strokePath();
|
||||
|
||||
// Waypoint circles + index labels
|
||||
for (let i = 0; i < smoothed.length; i++) {
|
||||
const p = smoothed[i];
|
||||
g.lineStyle(2, 0x00ffff, 1);
|
||||
g.fillStyle(0x003333, 0.7);
|
||||
g.fillCircle(p.x, p.y, 7);
|
||||
g.strokeCircle(p.x, p.y, 7);
|
||||
const label = gameRef.add.text(p.x + 9, p.y - 7, String(i + 1), {
|
||||
fontSize: '10px', color: '#00ffff', stroke: '#000000', strokeThickness: 2
|
||||
}).setDepth(901).setAlpha(0.9);
|
||||
if (!g._debugLabels) g._debugLabels = [];
|
||||
g._debugLabels.push(label);
|
||||
}
|
||||
|
||||
// 3 s fade
|
||||
gameRef.tweens.add({
|
||||
targets: g,
|
||||
alpha: { from: 1, to: 0 },
|
||||
duration: 3000,
|
||||
ease: 'Linear',
|
||||
onUpdate: () => {
|
||||
if (g._debugLabels) for (const lbl of g._debugLabels) lbl.setAlpha(g.alpha);
|
||||
},
|
||||
onComplete: () => {
|
||||
if (g._debugLabels) for (const lbl of g._debugLabels) lbl.destroy();
|
||||
g.destroy();
|
||||
if (pathDebugGraphics === g) pathDebugGraphics = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// ── NORMAL VIEW — thin white line, same color/duration as click indicator ──
|
||||
g.lineStyle(1.5, 0xffffff, 0.6);
|
||||
g.beginPath();
|
||||
g.moveTo(allPoints[0].x, allPoints[0].y);
|
||||
for (let i = 1; i < allPoints.length; i++) g.lineTo(allPoints[i].x, allPoints[i].y);
|
||||
g.strokePath();
|
||||
|
||||
// Match click-indicator fade duration (CLICK_INDICATOR_DURATION = 800 ms)
|
||||
gameRef.tweens.add({
|
||||
targets: g,
|
||||
alpha: { from: 0.7, to: 0 },
|
||||
duration: CLICK_INDICATOR_DURATION,
|
||||
ease: 'Sine.easeOut',
|
||||
onComplete: () => {
|
||||
g.destroy();
|
||||
if (pathDebugGraphics === g) pathDebugGraphics = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function movePlayerToPoint(x, y) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { GAME_CONFIG } from './utils/constants.js?v=8';
|
||||
import { GAME_CONFIG } from './utils/constants.js?v=9';
|
||||
import { preload, create, update } from './core/game.js?v=41';
|
||||
import { initializeNotifications } from './systems/notifications.js?v=7';
|
||||
// Bluetooth scanner is now handled as a minigame
|
||||
// Biometrics is now handled as a minigame
|
||||
import { startLockpickingMinigame } from './systems/minigame-starters.js?v=1';
|
||||
import { initializeDebugSystem } from './systems/debug.js?v=7';
|
||||
import { initializeDebugSystem } from './systems/debug.js?v=8';
|
||||
import { initializeUI } from './ui/panels.js?v=9';
|
||||
import { initializeModals } from './ui/modals.js?v=7';
|
||||
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
// Debug system variables
|
||||
let debugMode = false;
|
||||
let debugLevel = 1; // 1 = basic, 2 = detailed, 3 = verbose
|
||||
let visualDebugMode = true; // TEMPORARY: Visual debug (collision boxes, movement vectors) - on for testing
|
||||
let visualDebugMode = false; // Off by default; toggle with backtick key at runtime
|
||||
|
||||
// Expose current visual-debug state globally so other modules (player.js,
|
||||
// npc-behavior.js) can read it without an import.
|
||||
window.breakEscapeDebug = visualDebugMode;
|
||||
window.pathfindingDebug = visualDebugMode;
|
||||
|
||||
// Initialize the debug system
|
||||
export function initializeDebugSystem() {
|
||||
@@ -25,10 +30,15 @@ export function initializeDebugSystem() {
|
||||
`color: #0077FF; font-weight: bold;`);
|
||||
}
|
||||
} else {
|
||||
// Regular backtick toggles visual debug mode (collision boxes, movement vectors)
|
||||
// Regular backtick toggles visual debug mode (collision boxes, NPC/player paths)
|
||||
visualDebugMode = !visualDebugMode;
|
||||
// Keep global flags in sync so player.js and npc-behavior.js pick up the change
|
||||
window.breakEscapeDebug = visualDebugMode;
|
||||
window.pathfindingDebug = visualDebugMode;
|
||||
console.log(`%c[DEBUG] === VISUAL DEBUG MODE ${visualDebugMode ? 'ENABLED' : 'DISABLED'} ===`,
|
||||
`color: ${visualDebugMode ? '#00AA00' : '#DD0000'}; font-weight: bold;`);
|
||||
console.log('%c Backtick → visual debug (paths, collision boxes)', 'color:#888');
|
||||
console.log('%c Shift+` → console debug mode', 'color:#888');
|
||||
|
||||
// Update physics debug display if game exists
|
||||
updatePhysicsDebugDisplay();
|
||||
@@ -36,7 +46,7 @@ export function initializeDebugSystem() {
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Debug system initialized');
|
||||
console.log('Debug system initialized (visual debug OFF — press ` to toggle)');
|
||||
}
|
||||
|
||||
// Function to update physics debug display
|
||||
|
||||
@@ -1108,7 +1108,7 @@ class NPCBehavior {
|
||||
|
||||
// Get attack range from hostile system
|
||||
const attackRange = window.npcHostileSystem ?
|
||||
window.npcHostileSystem.getState(this.npcId)?.attackRange || 50 : 50;
|
||||
window.npcHostileSystem.getState(this.npcId)?.attackRange || 32 : 32;
|
||||
|
||||
// If in attack range, try to attack
|
||||
if (distance <= attackRange) {
|
||||
@@ -1244,7 +1244,8 @@ class NPCBehavior {
|
||||
);
|
||||
this.chasePath = smoothed;
|
||||
this.chasePathIndex = 0;
|
||||
this._drawChasePathDebug(smoothed);
|
||||
if (window.breakEscapeDebug) this._drawChasePathDebug(smoothed);
|
||||
else this._clearChasePathDebug();
|
||||
} else {
|
||||
// No path found (unreachable or grid not ready)
|
||||
this.chasePath = [];
|
||||
@@ -1255,10 +1256,10 @@ class NPCBehavior {
|
||||
);
|
||||
}
|
||||
|
||||
/** Draw the current chase path as a red overlay for debugging. */
|
||||
/** Draw the current chase path as a red overlay for debugging (debug mode only). */
|
||||
_drawChasePathDebug(path) {
|
||||
this._clearChasePathDebug();
|
||||
if (!path || path.length === 0) return;
|
||||
if (!window.breakEscapeDebug || !path || path.length === 0) return;
|
||||
|
||||
const scene = this.scene || window.game?.scene?.scenes[0];
|
||||
if (!scene) return;
|
||||
|
||||
@@ -259,8 +259,12 @@ export class PlayerCombat {
|
||||
// Get player facing direction
|
||||
const direction = window.player.lastDirection || 'down';
|
||||
|
||||
// Draw debug hit area
|
||||
this.drawPunchHitbox(playerX, playerY, punchRange, direction);
|
||||
// Draw debug hit area (only when debug mode is on)
|
||||
if (window.breakEscapeDebug) {
|
||||
this.drawPunchHitbox(playerX, playerY, punchRange, direction);
|
||||
} else if (this.hitboxGraphics) {
|
||||
this.hitboxGraphics.clear(); // ensure no stale overlay if debug was just toggled off
|
||||
}
|
||||
|
||||
// Get all NPCs from rooms
|
||||
let hitCount = 0;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// DEBUG FLAG — flip this single constant to true to enable all debug visuals:
|
||||
// • Phaser physics collision-box overlay
|
||||
// • Player path-finding line with waypoint circles and index labels
|
||||
// • NPC hostile chase-path overlay
|
||||
// • Console pathfinding spam (window.pathfindingDebug)
|
||||
// You can also toggle at runtime with the backtick key (visual) or
|
||||
// Shift+backtick (console), or set window.breakEscapeDebug = true in DevTools.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
export const BREAK_ESCAPE_DEBUG = false;
|
||||
|
||||
// Game constants
|
||||
export const TILE_SIZE = 32;
|
||||
export const DOOR_ALIGN_OVERLAP = 32 * 3;
|
||||
@@ -86,7 +97,7 @@ export const GAME_CONFIG = typeof Phaser !== 'undefined' ? {
|
||||
default: 'arcade',
|
||||
arcade: {
|
||||
gravity: { y: 0 },
|
||||
debug: true // TEMPORARY: enable physics collision box visualisation
|
||||
debug: BREAK_ESCAPE_DEBUG // Toggle via BREAK_ESCAPE_DEBUG constant above
|
||||
}
|
||||
}
|
||||
} : null;
|
||||
Reference in New Issue
Block a user