Change crosshair targeting sprite

This commit is contained in:
Peter Stockings
2026-01-20 22:56:16 +11:00
parent d4f763d1d0
commit 1a91aa5274
4 changed files with 55 additions and 20 deletions

8
src/core/config/ui.ts Normal file
View File

@@ -0,0 +1,8 @@
export const UI_CONFIG = {
targeting: {
crosshair: {
textureKey: "weapons",
frame: 35
}
}
};

View File

@@ -2,7 +2,7 @@
import { describe, it, expect, beforeEach } from "vitest"; import { describe, it, expect, beforeEach } from "vitest";
import { ItemManager } from "../../../scenes/systems/ItemManager"; import { ItemManager } from "../../../scenes/systems/ItemManager";
import { EntityManager } from "../../EntityManager"; import { EntityManager } from "../../EntityManager";
import type { World, CombatantActor, RangedWeaponItem, AmmoItem, Item } from "../../../core/types"; import type { World, CombatantActor, RangedWeaponItem, AmmoItem } from "../../../core/types";
import { ITEMS } from "../../../core/config/Items"; import { ITEMS } from "../../../core/config/Items";
// Mock World and EntityManager // Mock World and EntityManager

View File

@@ -68,8 +68,7 @@ export class GameScene extends Phaser.Scene {
this.dungeonRenderer = new DungeonRenderer(this); this.dungeonRenderer = new DungeonRenderer(this);
this.cameraController = new CameraController(this.cameras.main); this.cameraController = new CameraController(this.cameras.main);
this.itemManager = new ItemManager(this.world, this.entityManager); this.itemManager = new ItemManager(this.world, this.entityManager);
const targetingGraphics = this.add.graphics().setDepth(2000); this.targetingSystem = new TargetingSystem(this);
this.targetingSystem = new TargetingSystem(targetingGraphics);
// Launch UI Scene // Launch UI Scene
this.scene.launch("GameUI"); this.scene.launch("GameUI");
@@ -213,12 +212,16 @@ export class GameScene extends Phaser.Scene {
return; return;
} }
const { x: tx, y: ty } = this.getPointerTilePos(this.input.activePointer);
this.targetingSystem.startTargeting( this.targetingSystem.startTargeting(
item.id, item.id,
player.pos, player.pos,
this.world, this.world,
this.dungeonRenderer.seenArray, this.dungeonRenderer.seenArray,
this.world.width this.world.width,
{ x: tx, y: ty }
); );
this.emitUIUpdate(); this.emitUIUpdate();
return; return;
@@ -242,12 +245,15 @@ export class GameScene extends Phaser.Scene {
return; return;
} }
const { x: tx, y: ty } = this.getPointerTilePos(this.input.activePointer);
this.targetingSystem.startTargeting( this.targetingSystem.startTargeting(
item.id, item.id,
player.pos, player.pos,
this.world, this.world,
this.dungeonRenderer.seenArray, this.dungeonRenderer.seenArray,
this.world.width this.world.width,
{ x: tx, y: ty }
); );
this.emitUIUpdate(); this.emitUIUpdate();
} }
@@ -671,4 +677,12 @@ export class GameScene extends Phaser.Scene {
} }
} }
private getPointerTilePos(pointer: Phaser.Input.Pointer): { x: number, y: number } {
const worldPoint = this.cameras.main.getWorldPoint(pointer.x, pointer.y);
return {
x: Math.floor(worldPoint.x / TILE_SIZE),
y: Math.floor(worldPoint.y / TILE_SIZE)
};
}
} }

View File

@@ -2,6 +2,7 @@ import Phaser from "phaser";
import type { World, CombatantActor, Item, Vec2, EntityId } from "../../core/types"; import type { World, CombatantActor, Item, Vec2, EntityId } from "../../core/types";
import { TILE_SIZE } from "../../core/constants"; import { TILE_SIZE } from "../../core/constants";
import { GAME_CONFIG } from "../../core/config/GameConfig"; import { GAME_CONFIG } from "../../core/config/GameConfig";
import { UI_CONFIG } from "../../core/config/ui";
import { traceProjectile, getClosestVisibleEnemy } from "../../engine/gameplay/CombatLogic"; import { traceProjectile, getClosestVisibleEnemy } from "../../engine/gameplay/CombatLogic";
import type { EntityManager } from "../../engine/EntityManager"; import type { EntityManager } from "../../engine/EntityManager";
@@ -11,12 +12,20 @@ import type { EntityManager } from "../../engine/EntityManager";
*/ */
export class TargetingSystem { export class TargetingSystem {
private graphics: Phaser.GameObjects.Graphics; private graphics: Phaser.GameObjects.Graphics;
private crosshairSprite: Phaser.GameObjects.Sprite;
private active: boolean = false; private active: boolean = false;
private targetingItemId: string | null = null; private targetingItemId: string | null = null;
private cursor: Vec2 | null = null; private cursor: Vec2 | null = null;
constructor(graphics: Phaser.GameObjects.Graphics) { constructor(scene: Phaser.Scene) {
this.graphics = graphics; this.graphics = scene.add.graphics();
this.graphics.setDepth(2000); // High depth to draw over world
// Create crosshair sprite but hide it initially
this.crosshairSprite = scene.add.sprite(0, 0, UI_CONFIG.targeting.crosshair.textureKey, UI_CONFIG.targeting.crosshair.frame);
this.crosshairSprite.setDepth(2001); // On top of line
this.crosshairSprite.setVisible(false);
this.crosshairSprite.setAlpha(0.8);
} }
/** /**
@@ -27,7 +36,8 @@ export class TargetingSystem {
playerPos: Vec2, playerPos: Vec2,
world: World, world: World,
seenArray: Uint8Array, seenArray: Uint8Array,
worldWidth: number worldWidth: number,
initialTargetPos?: Vec2
): void { ): void {
this.targetingItemId = itemId; this.targetingItemId = itemId;
this.active = true; this.active = true;
@@ -37,11 +47,14 @@ export class TargetingSystem {
if (closest) { if (closest) {
this.cursor = closest; this.cursor = closest;
} else if (initialTargetPos) {
this.cursor = { ...initialTargetPos };
} else { } else {
this.cursor = null; // Default to existing cursor or player pos
this.cursor = this.cursor ? { ...this.cursor } : { ...playerPos };
} }
this.drawLine(playerPos); this.updateVisuals(playerPos);
console.log("Targeting Mode: ON"); console.log("Targeting Mode: ON");
} }
@@ -52,7 +65,7 @@ export class TargetingSystem {
if (!this.active) return; if (!this.active) return;
this.cursor = { x: worldPos.x, y: worldPos.y }; this.cursor = { x: worldPos.x, y: worldPos.y };
this.drawLine(playerPos); this.updateVisuals(playerPos);
} }
/** /**
@@ -110,6 +123,7 @@ export class TargetingSystem {
this.targetingItemId = null; this.targetingItemId = null;
this.cursor = null; this.cursor = null;
this.graphics.clear(); this.graphics.clear();
this.crosshairSprite.setVisible(false);
console.log("Targeting cancelled"); console.log("Targeting cancelled");
} }
@@ -135,15 +149,17 @@ export class TargetingSystem {
} }
/** /**
* Draw targeting line from player to cursor * Draw targeting line and update crosshair
*/ */
private drawLine(playerPos: Vec2): void { private updateVisuals(playerPos: Vec2): void {
if (!this.cursor) { if (!this.cursor) {
this.graphics.clear(); this.graphics.clear();
this.crosshairSprite.setVisible(false);
return; return;
} }
this.graphics.clear(); this.graphics.clear();
this.crosshairSprite.setVisible(true);
const startX = playerPos.x * TILE_SIZE + TILE_SIZE / 2; const startX = playerPos.x * TILE_SIZE + TILE_SIZE / 2;
const startY = playerPos.y * TILE_SIZE + TILE_SIZE / 2; const startY = playerPos.y * TILE_SIZE + TILE_SIZE / 2;
@@ -151,18 +167,15 @@ export class TargetingSystem {
const endX = this.cursor.x * 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 endY = this.cursor.y * TILE_SIZE + TILE_SIZE / 2;
// Update crosshair position
this.crosshairSprite.setPosition(endX, endY);
// Draw Line
this.graphics.lineStyle( this.graphics.lineStyle(
GAME_CONFIG.ui.targetingLineWidth, GAME_CONFIG.ui.targetingLineWidth,
GAME_CONFIG.ui.targetingLineColor, GAME_CONFIG.ui.targetingLineColor,
GAME_CONFIG.ui.targetingLineAlpha GAME_CONFIG.ui.targetingLineAlpha
); );
this.graphics.lineBetween(startX, startY, endX, endY); this.graphics.lineBetween(startX, startY, endX, endY);
this.graphics.strokeRect(
this.cursor.x * TILE_SIZE,
this.cursor.y * TILE_SIZE,
TILE_SIZE,
TILE_SIZE
);
} }
} }