Change targetting line to dashed
This commit is contained in:
@@ -125,7 +125,10 @@ export const GAME_CONFIG = {
|
||||
// Targeting
|
||||
targetingLineColor: 0xff0000,
|
||||
targetingLineWidth: 2,
|
||||
targetingLineAlpha: 0.7
|
||||
targetingLineAlpha: 0.7,
|
||||
targetingLineDash: 6,
|
||||
targetingLineGap: 4,
|
||||
targetingLineShorten: 8
|
||||
},
|
||||
|
||||
gameplay: {
|
||||
|
||||
@@ -207,7 +207,7 @@ export class GameScene extends Phaser.Scene {
|
||||
if (this.targetingSystem.isActive && this.targetingSystem.itemId === item.id) {
|
||||
// Already targeting - execute shoot
|
||||
if (this.targetingSystem.cursorPos) {
|
||||
this.executeThrow(this.targetingSystem.cursorPos.x, this.targetingSystem.cursorPos.y);
|
||||
this.executeThrow();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -219,6 +219,8 @@ export class GameScene extends Phaser.Scene {
|
||||
item.id,
|
||||
player.pos,
|
||||
this.world,
|
||||
this.entityManager,
|
||||
this.playerId,
|
||||
this.dungeonRenderer.seenArray,
|
||||
this.world.width,
|
||||
{ x: tx, y: ty }
|
||||
@@ -240,7 +242,7 @@ export class GameScene extends Phaser.Scene {
|
||||
if (this.targetingSystem.isActive && this.targetingSystem.itemId === item.id) {
|
||||
// Already targeting - execute throw
|
||||
if (this.targetingSystem.cursorPos) {
|
||||
this.executeThrow(this.targetingSystem.cursorPos.x, this.targetingSystem.cursorPos.y);
|
||||
this.executeThrow();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -251,6 +253,8 @@ export class GameScene extends Phaser.Scene {
|
||||
item.id,
|
||||
player.pos,
|
||||
this.world,
|
||||
this.entityManager,
|
||||
this.playerId,
|
||||
this.dungeonRenderer.seenArray,
|
||||
this.world.width,
|
||||
{ x: tx, y: ty }
|
||||
@@ -323,7 +327,7 @@ export class GameScene extends Phaser.Scene {
|
||||
// Only Left Click throws
|
||||
if (p.button === 0) {
|
||||
if (this.targetingSystem.cursorPos) {
|
||||
this.executeThrow(this.targetingSystem.cursorPos.x, this.targetingSystem.cursorPos.y);
|
||||
this.executeThrow();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -615,7 +619,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
|
||||
|
||||
private executeThrow(_targetX: number, _targetY: number) {
|
||||
private executeThrow() {
|
||||
const success = this.targetingSystem.executeThrow(
|
||||
this.world,
|
||||
this.playerId,
|
||||
|
||||
@@ -28,7 +28,7 @@ export class EventBridge {
|
||||
commitActionFn: (action: any) => void,
|
||||
emitUIUpdateFn: () => void,
|
||||
restartGameFn: () => void,
|
||||
executeThrowFn: (x: number, y: number) => void
|
||||
executeThrowFn: () => void
|
||||
): void {
|
||||
// Menu state listeners (from UI)
|
||||
this.scene.events.on("menu-toggled", (isOpen: boolean) => {
|
||||
@@ -115,7 +115,7 @@ export class EventBridge {
|
||||
if (targetingSystem.isActive && targetingSystem.itemId === item.id) {
|
||||
// Already targeting - execute throw
|
||||
if (targetingSystem.cursorPos) {
|
||||
executeThrowFn(targetingSystem.cursorPos.x, targetingSystem.cursorPos.y);
|
||||
executeThrowFn();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -124,6 +124,8 @@ export class EventBridge {
|
||||
item.id,
|
||||
player.pos,
|
||||
(this.scene as any).world,
|
||||
(this.scene as any).entityManager,
|
||||
(this.scene as any).playerId,
|
||||
dungeonRenderer.seenArray,
|
||||
(this.scene as any).world.width
|
||||
);
|
||||
|
||||
@@ -16,6 +16,11 @@ export class TargetingSystem {
|
||||
private active: boolean = false;
|
||||
private targetingItemId: string | null = null;
|
||||
private cursor: Vec2 | null = null;
|
||||
|
||||
// Context for predictive visual
|
||||
private world: World | null = null;
|
||||
private entityManager: EntityManager | null = null;
|
||||
private playerId: EntityId | null = null;
|
||||
|
||||
constructor(scene: Phaser.Scene) {
|
||||
this.graphics = scene.add.graphics();
|
||||
@@ -35,11 +40,16 @@ export class TargetingSystem {
|
||||
itemId: string,
|
||||
playerPos: Vec2,
|
||||
world: World,
|
||||
entityManager: EntityManager,
|
||||
playerId: EntityId,
|
||||
seenArray: Uint8Array,
|
||||
worldWidth: number,
|
||||
initialTargetPos?: Vec2
|
||||
): void {
|
||||
this.targetingItemId = itemId;
|
||||
this.world = world;
|
||||
this.entityManager = entityManager;
|
||||
this.playerId = playerId;
|
||||
this.active = true;
|
||||
|
||||
// Auto-target closest visible enemy
|
||||
@@ -122,6 +132,9 @@ export class TargetingSystem {
|
||||
this.active = false;
|
||||
this.targetingItemId = null;
|
||||
this.cursor = null;
|
||||
this.world = null;
|
||||
this.entityManager = null;
|
||||
this.playerId = null;
|
||||
this.graphics.clear();
|
||||
this.crosshairSprite.setVisible(false);
|
||||
console.log("Targeting cancelled");
|
||||
@@ -164,18 +177,72 @@ export class TargetingSystem {
|
||||
const startX = playerPos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const startY = playerPos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
const endX = this.cursor.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const endY = this.cursor.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
const aimEndX = this.cursor.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const aimEndY = this.cursor.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
// Update crosshair position
|
||||
this.crosshairSprite.setPosition(endX, endY);
|
||||
// Predictive impact point
|
||||
let finalEndX = aimEndX;
|
||||
let finalEndY = aimEndY;
|
||||
|
||||
// Draw Line
|
||||
if (this.world && this.entityManager && this.playerId !== null) {
|
||||
const result = traceProjectile(this.world, playerPos, this.cursor, this.entityManager, this.playerId);
|
||||
const bPos = result.blockedPos;
|
||||
|
||||
finalEndX = bPos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
finalEndY = bPos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
}
|
||||
|
||||
// Update crosshair position to ACTUAL impact point
|
||||
this.crosshairSprite.setPosition(finalEndX, finalEndY);
|
||||
|
||||
// Draw Main Line (dashed to impact)
|
||||
this.graphics.lineStyle(
|
||||
GAME_CONFIG.ui.targetingLineWidth,
|
||||
GAME_CONFIG.ui.targetingLineColor,
|
||||
GAME_CONFIG.ui.targetingLineAlpha
|
||||
);
|
||||
this.graphics.lineBetween(startX, startY, endX, endY);
|
||||
|
||||
const dx = finalEndX - startX;
|
||||
const dy = finalEndY - startY;
|
||||
const dist = Math.sqrt(dx * dx + dy * dy);
|
||||
const shortenAmt = GAME_CONFIG.ui.targetingLineShorten;
|
||||
|
||||
if (dist > shortenAmt) {
|
||||
const ratio = (dist - shortenAmt) / dist;
|
||||
const shortenedEndX = startX + dx * ratio;
|
||||
const shortenedEndY = startY + dy * ratio;
|
||||
this.drawDashedLine(startX, startY, shortenedEndX, shortenedEndY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Manual dashed line implementation for Phaser Graphics
|
||||
*/
|
||||
private drawDashedLine(x1: number, y1: number, x2: number, y2: number): void {
|
||||
const dashLen = GAME_CONFIG.ui.targetingLineDash;
|
||||
const gapLen = GAME_CONFIG.ui.targetingLineGap;
|
||||
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance === 0) return;
|
||||
|
||||
const angle = Math.atan2(dy, dx);
|
||||
const cos = Math.cos(angle);
|
||||
const sin = Math.sin(angle);
|
||||
|
||||
let currentDist = 0;
|
||||
while (currentDist < distance) {
|
||||
const len = Math.min(dashLen, distance - currentDist);
|
||||
const sx = x1 + currentDist * cos;
|
||||
const sy = y1 + currentDist * sin;
|
||||
const ex = sx + len * cos;
|
||||
const ey = sy + len * sin;
|
||||
|
||||
this.graphics.lineBetween(sx, sy, ex, ey);
|
||||
currentDist += dashLen + gapLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user