Skip to content

Commit 00c85ec

Browse files
committed
context menu usability improvements
1 parent 3952b6b commit 00c85ec

File tree

6 files changed

+58
-26
lines changed

6 files changed

+58
-26
lines changed

src/controllers/game/contextmenu/controller.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {ContainerKeys} from "../../../inversify.config";
1212
export class ContextMenuController extends BaseController {
1313

1414
private _selectedUnit: BaseUnit;
15+
private _hoveredUnit: BaseUnit;
1516
private _menuElement: HTMLElement;
1617

1718
constructor(
@@ -25,7 +26,7 @@ export class ContextMenuController extends BaseController {
2526
}
2627

2728
preload() {
28-
this._gameSubject.subscribe(GameEvent.UnitSelected, this._showMenuForUnit);
29+
this._gameSubject.subscribe(GameEvent.UnitSelected, this._selectUnit);
2930
this._gameSubject.subscribe(GameEvent.CancelAction, this._deselectAndHideMenu);
3031
this._gameSubject.subscribe(GameEvent.UnitAttackActionSelected, this._hideMenu);
3132
this._gameSubject.subscribe(GameEvent.UnitWaitActionSelected, this._hideMenu);
@@ -45,14 +46,37 @@ export class ContextMenuController extends BaseController {
4546
this._gameSubject.dispatch(GameEvent.UnitWaitActionSelected, this._selectedUnit);
4647
break;
4748
case 'cancel':
48-
this._gameSubject.dispatch(GameEvent.CancelAction);
49+
this._gameSubject.dispatch(GameEvent.CancelAction, this._selectedUnit);
4950
break;
5051
default:
5152
console.error('Invalid action dispatched on actionSelected');
5253
}
5354
});
5455
}
5556

57+
update() {
58+
let foundUnitUnderCursor = false;
59+
60+
this._gameSubject.units.forEach(unit => {
61+
let inBounds = unit.spr.isoBounds.containsXY(this._inputSubject.cursorPos.x, this._inputSubject.cursorPos.y);
62+
63+
if(inBounds) {
64+
foundUnitUnderCursor = true;
65+
this._hoveredUnit = unit;
66+
}
67+
});
68+
69+
if (!foundUnitUnderCursor)
70+
this._hoveredUnit = null;
71+
}
72+
73+
render() {
74+
if(!!this._hoveredUnit) {
75+
this._game.debug.text(`${this._hoveredUnit.name} HP: ${this._hoveredUnit.hp}/${this._hoveredUnit.stats.hp}`, 2, 34, "#a7aebe");
76+
this._game.debug.text(JSON.stringify(this._hoveredUnit.stats).replace(/[{}"]/g, '').replace(/,/g, ', '), 2, 54, "#a7aebe");
77+
}
78+
}
79+
5680
private _hideMenu = (): void => {
5781
this._menuElement.style.display = 'none';
5882
};
@@ -70,13 +94,8 @@ export class ContextMenuController extends BaseController {
7094
// ---------- EVENT HANDLERS ----------
7195
// ------------------------------------
7296

73-
private _showMenuForUnit = (unit: BaseUnit): void => {
74-
if(unit.hasActedThisTurn || unit.belongsToPlayer !== 0) //player 0 is the user
75-
return;
76-
97+
private _selectUnit = (unit: BaseUnit): void => {
7798
this._selectedUnit = unit;
78-
79-
this._showMenu();
8099
};
81100

82101
private _deselectAndHideMenu = (): void => {

src/controllers/game/grid/controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ export class GridController extends BaseController {
112112
this._activeCell = null;
113113
}
114114

115+
//TODO: maybe we should just dispatch gridCellActivated and let unit controller handle dispatching UnitAttack or UnitMove. We need to check that it is a valid unit to attack etc...
116+
115117
// if we tapped a destination cell for MOVE action
116118
if (!!this._unitHighlightedForMove && clickedCell.highlighted) {
117119
this._unhighlightAll();
@@ -130,7 +132,6 @@ export class GridController extends BaseController {
130132
this._activeCell = clickedCell;
131133

132134
// we didn't tap a cell for an action, so lets cancel any pending actions
133-
this._gameSubject.dispatch(GameEvent.CancelAction, clickedCell);
134135
this._gameSubject.dispatch(GameEvent.GridCellActivated, clickedCell);
135136
}
136137
}

src/controllers/game/unit/controller.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class UnitController extends BaseController {
2929
preload() {
3030
this._gameSubject.subscribe(GameEvent.LoadMapCompleted, this._initializeUnits);
3131
this._gameSubject.subscribe(GameEvent.GridCellActivated, this._trySelectUnit);
32-
this._gameSubject.subscribe(GameEvent.CancelAction, this._deselectUnit);
32+
this._gameSubject.subscribe(GameEvent.CancelAction, this._deselectAndResetPosition);
3333
this._gameSubject.subscribe(GameEvent.UnitWaitActionSelected, this._unitFinishedTurn);
3434
this._gameSubject.subscribe(GameEvent.UnitMove, this._tryMoveUnit);
3535
this._gameSubject.subscribe(GameEvent.UnitMoveCompleted, this._flagUnitAsMoved);
@@ -45,13 +45,6 @@ export class UnitController extends BaseController {
4545
this._game.iso.simpleSort(this._game['isoUnitsGroup']);
4646
}
4747

48-
render() {
49-
if(!!this._selectedUnit) {
50-
this._game.debug.text(`${this._selectedUnit.name} HP: ${this._selectedUnit.hp}`, 2, 34, "#a7aebe");
51-
this._game.debug.text('Base Unit Stats:' + JSON.stringify(this._selectedUnit.stats), 2, 54, "#a7aebe");
52-
}
53-
}
54-
5548
// ------------------------------------
5649
// ---------- EVENT HANDLERS ----------
5750
// ------------------------------------
@@ -63,6 +56,9 @@ export class UnitController extends BaseController {
6356
};
6457

6558
private _trySelectUnit = (cell: GridCell): void => {
59+
if(!!this._selectedUnit)
60+
this._gameSubject.dispatch(GameEvent.CancelAction, this._selectedUnit);
61+
6662
let unitAtCell = this.units.find(unit => unit.x == cell.x && unit.y == cell.y);
6763
if(!!unitAtCell && this._selectedUnit !== unitAtCell) {
6864
this._selectedUnit = unitAtCell;
@@ -74,8 +70,17 @@ export class UnitController extends BaseController {
7470
}
7571
};
7672

77-
private _deselectUnit = (): void => {
73+
private _deselectAndResetPosition = (unit: BaseUnit): void => {
7874
this._selectedUnit = null;
75+
76+
if (!!unit && !unit.hasActedThisTurn) {
77+
unit.hasMovedThisTurn = false;
78+
79+
unit.spr.isoX = this._config.cellSize * unit.committedX;
80+
unit.spr.isoY = this._config.cellSize * unit.committedY;
81+
unit.x = unit.committedX;
82+
unit.y = unit.committedY;
83+
}
7984
};
8085

8186
private _tryMoveUnit = (destinationCell: GridCell): void => {
@@ -110,6 +115,8 @@ export class UnitController extends BaseController {
110115

111116
private _unitFinishedTurn = (unit: BaseUnit): void => {
112117
unit.hasActedThisTurn = true;
118+
unit.committedX = unit.x;
119+
unit.committedY = unit.y;
113120
unit.setTint(0xaaaaaa);
114121

115122
let unitsForPlayer = this.units.filter(x => x.belongsToPlayer === unit.belongsToPlayer && !x.isDead);

src/game_objects/units/base.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ export abstract class BaseUnit implements Unit {
1818

1919
x: number;
2020
y: number;
21-
22-
hp: number;
21+
22+
committedX: number; //stores original position until a move is committed by selecting an action.
23+
committedY: number;
24+
25+
hp: number; //current hp
2326

2427
stats: Stats;
2528

@@ -40,6 +43,8 @@ export abstract class BaseUnit implements Unit {
4043
this.belongsToPlayer = unit.belongsToPlayer;
4144
this.x = unit.x;
4245
this.y = unit.y;
46+
this.committedX = unit.x;
47+
this.committedY = unit.y;
4348
this.stats = unit.stats;
4449
this.abilities = unit.abilities;
4550

@@ -58,7 +63,7 @@ export abstract class BaseUnit implements Unit {
5863
this.spr.scale.x = sign;
5964
this.y = y;
6065
}
61-
66+
6267
setTint(tint: number) {
6368
this.spr.tint = tint;
6469
this.currentTint = tint;

src/services/army_command_strategy/service.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as Phaser from 'phaser';
2-
import {IArmyCommandStrategy} from "./interface";
32
import Game = Phaser.Game;
43
import {GameSubject, GameEvent} from "../subject/game";
54
import {BaseUnit} from "../../game_objects/units/base";
65
import {InputSubject, InputEvent} from "../subject/input";
76
import Point3 = Phaser.Plugin.Isometric.Point3;
87
import {GameConfig} from "../../config";
98
import {GridCell} from "../../game_objects/grid/grid_cell";
9+
import {IArmyCommandStrategy} from "./interface";
1010

1111
export class DemoArmyCommandStrategy implements IArmyCommandStrategy {
1212
private _spottedEnemies: BaseUnit[] = [];
@@ -67,8 +67,7 @@ export class DemoArmyCommandStrategy implements IArmyCommandStrategy {
6767
if(unitToAttack && this._cellUnderUnit(unitToAttack).highlighted)
6868
setTimeout(() => this._tapLocation(unitToAttack), this._delay); //this._gameState.dispatch(GameEvent.UnitAttack, unitToAttack)
6969
else {
70-
this._gameState.dispatch(GameEvent.CancelAction);
71-
this._gameState.dispatch(GameEvent.UnitAttackCompleted, unit);
70+
this._gameState.dispatch(GameEvent.UnitWaitActionSelected, unit);
7271
}
7372
}
7473

src/services/map_builder/service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ export class MapBuilder implements IMapBuilder {
5858
for(let xx = 0; xx < this._map.layout.length; xx++) {
5959
let playerNum = parseInt(this._map.layout[yy][xx]);
6060
if(!isNaN(playerNum)) {
61-
this._unitsByPlayer[playerNum][armyIndices[playerNum]].x = xx;
62-
this._unitsByPlayer[playerNum][armyIndices[playerNum]].y = yy;
61+
let unit = this._unitsByPlayer[playerNum][armyIndices[playerNum]];
62+
unit.x = xx;
63+
unit.y = yy;
6364
armyIndices[playerNum]++;
6465
}
6566
}

0 commit comments

Comments
 (0)