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 { ItemManager } from "../../../scenes/systems/ItemManager";
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";
// Mock World and EntityManager

View File

@@ -68,8 +68,7 @@ export class GameScene extends Phaser.Scene {
this.dungeonRenderer = new DungeonRenderer(this);
this.cameraController = new CameraController(this.cameras.main);
this.itemManager = new ItemManager(this.world, this.entityManager);
const targetingGraphics = this.add.graphics().setDepth(2000);
this.targetingSystem = new TargetingSystem(targetingGraphics);
this.targetingSystem = new TargetingSystem(this);
// Launch UI Scene
this.scene.launch("GameUI");
@@ -213,12 +212,16 @@ export class GameScene extends Phaser.Scene {
return;
}
const { x: tx, y: ty } = this.getPointerTilePos(this.input.activePointer);
this.targetingSystem.startTargeting(
item.id,
player.pos,
this.world,
this.dungeonRenderer.seenArray,
this.world.width
this.world.width,
{ x: tx, y: ty }
);
this.emitUIUpdate();
return;
@@ -242,12 +245,15 @@ export class GameScene extends Phaser.Scene {
return;
}
const { x: tx, y: ty } = this.getPointerTilePos(this.input.activePointer);
this.targetingSystem.startTargeting(
item.id,
player.pos,
this.world,
this.dungeonRenderer.seenArray,
this.world.width
this.world.width,
{ x: tx, y: ty }
);
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 { TILE_SIZE } from "../../core/constants";
import { GAME_CONFIG } from "../../core/config/GameConfig";
import { UI_CONFIG } from "../../core/config/ui";
import { traceProjectile, getClosestVisibleEnemy } from "../../engine/gameplay/CombatLogic";
import type { EntityManager } from "../../engine/EntityManager";
@@ -11,12 +12,20 @@ import type { EntityManager } from "../../engine/EntityManager";
*/
export class TargetingSystem {
private graphics: Phaser.GameObjects.Graphics;
private crosshairSprite: Phaser.GameObjects.Sprite;
private active: boolean = false;
private targetingItemId: string | null = null;
private cursor: Vec2 | null = null;
constructor(graphics: Phaser.GameObjects.Graphics) {
this.graphics = graphics;
constructor(scene: Phaser.Scene) {
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,
world: World,
seenArray: Uint8Array,
worldWidth: number
worldWidth: number,
initialTargetPos?: Vec2
): void {
this.targetingItemId = itemId;
this.active = true;
@@ -37,11 +47,14 @@ export class TargetingSystem {
if (closest) {
this.cursor = closest;
} else if (initialTargetPos) {
this.cursor = { ...initialTargetPos };
} 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");
}
@@ -52,7 +65,7 @@ export class TargetingSystem {
if (!this.active) return;
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.cursor = null;
this.graphics.clear();
this.crosshairSprite.setVisible(false);
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) {
this.graphics.clear();
this.crosshairSprite.setVisible(false);
return;
}
this.graphics.clear();
this.crosshairSprite.setVisible(true);
const startX = playerPos.x * 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 endY = this.cursor.y * TILE_SIZE + TILE_SIZE / 2;
// Update crosshair position
this.crosshairSprite.setPosition(endX, endY);
// Draw Line
this.graphics.lineStyle(
GAME_CONFIG.ui.targetingLineWidth,
GAME_CONFIG.ui.targetingLineColor,
GAME_CONFIG.ui.targetingLineAlpha
);
this.graphics.lineBetween(startX, startY, endX, endY);
this.graphics.strokeRect(
this.cursor.x * TILE_SIZE,
this.cursor.y * TILE_SIZE,
TILE_SIZE,
TILE_SIZE
);
}
}