Added ship hovering system
This commit is contained in:
parent
4efaafafd9
commit
37b7bd40d2
|
@ -103,10 +103,17 @@ module SpaceTac.Game {
|
|||
// Force an injection of events in the battle log to simulate the initial state
|
||||
// For instance, this may be called after 'start', to use the log subscription system
|
||||
// to initialize a battle UI
|
||||
// Attributes 'play_order' and 'playing_ship' should be defined before calling this
|
||||
injectInitialEvents(): void {
|
||||
// TODO Simulate initial ship placement
|
||||
var log = this.log;
|
||||
|
||||
// Simulate initial ship placement
|
||||
this.play_order.forEach((ship) => {
|
||||
log.add(new Events.MoveEvent(ship, ship.arena_x, ship.arena_y));
|
||||
});
|
||||
|
||||
// Simulate game turn
|
||||
this.log.add(new Events.ShipChangeEvent(this.playing_ship, this.playing_ship));
|
||||
log.add(new Events.ShipChangeEvent(this.playing_ship, this.playing_ship));
|
||||
}
|
||||
|
||||
// Create a quick random battle, for testing purposes
|
||||
|
|
|
@ -6,14 +6,37 @@ module SpaceTac.Game {
|
|||
// Full list of battle events
|
||||
events: Events.BaseLogEvent[];
|
||||
|
||||
// List of subscribers
|
||||
private subscribers: Function[];
|
||||
|
||||
// Create an initially empty log
|
||||
constructor() {
|
||||
this.events = [];
|
||||
this.subscribers = [];
|
||||
}
|
||||
|
||||
// Add a battle event to the log
|
||||
add(event: Events.BaseLogEvent) {
|
||||
this.events.push(event);
|
||||
|
||||
this.subscribers.forEach((subscriber) => {
|
||||
subscriber(event);
|
||||
});
|
||||
}
|
||||
|
||||
// Subscribe a callback to receive further events
|
||||
subscribe(callback: (event: Events.BaseLogEvent) => void): Function {
|
||||
this.subscribers.push(callback);
|
||||
return callback;
|
||||
}
|
||||
|
||||
// Unsubscribe a callback
|
||||
// Pass the value returned by 'subscribe' as argument
|
||||
unsubscribe(callback: Function): void {
|
||||
var index = this.subscribers.indexOf(callback);
|
||||
if (index >= 0) {
|
||||
this.subscribers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
src/scripts/game/events/MoveEvent.ts
Normal file
8
src/scripts/game/events/MoveEvent.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
module SpaceTac.Game.Events {
|
||||
// Event logged when a ship moves
|
||||
export class MoveEvent extends BaseLogEvent {
|
||||
constructor(ship: Ship, x: number, y: number) {
|
||||
super("move", ship, Target.newFromLocation(x, y));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/// <reference path="../definitions/jasmine.d.ts"/>
|
||||
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||
|
||||
module SpaceTac.Specs {
|
||||
describe("Battle", function () {
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||
|
||||
module SpaceTac.Specs {
|
||||
|
||||
// Check a single game log event
|
||||
|
@ -27,7 +29,34 @@ module SpaceTac.Specs {
|
|||
}
|
||||
}
|
||||
|
||||
// Fake event
|
||||
class FakeEvent extends Game.Events.BaseLogEvent {
|
||||
constructor() {
|
||||
super("fake");
|
||||
}
|
||||
}
|
||||
|
||||
describe("BattleLog", function () {
|
||||
it("forwards events to subscribers, until unsubscribe", function () {
|
||||
var log = new Game.BattleLog();
|
||||
var received = [];
|
||||
var fake = new FakeEvent();
|
||||
|
||||
var sub = log.subscribe(function (event) {
|
||||
received.push(event);
|
||||
});
|
||||
|
||||
log.add(fake);
|
||||
expect(received).toEqual([fake]);
|
||||
|
||||
log.add(fake);
|
||||
expect(received).toEqual([fake, fake]);
|
||||
|
||||
log.unsubscribe(sub);
|
||||
log.add(fake);
|
||||
expect(received).toEqual([fake, fake]);
|
||||
});
|
||||
|
||||
it("logs ship change events", function () {
|
||||
var battle = Game.Battle.newQuickRandom();
|
||||
expect(battle.log.events.length).toBe(0);
|
||||
|
@ -36,5 +65,19 @@ module SpaceTac.Specs {
|
|||
expect(battle.log.events.length).toBe(1);
|
||||
checkEvent(battle.log.events[0], battle.play_order[0], "ship_change", battle.play_order[1]);
|
||||
});
|
||||
|
||||
it("can receive simulated initial state events", function (){
|
||||
var battle = Game.Battle.newQuickRandom();
|
||||
|
||||
expect(battle.log.events.length).toBe(0);
|
||||
|
||||
battle.injectInitialEvents();
|
||||
|
||||
expect(battle.log.events.length).toBe(9);
|
||||
for (var i = 0; i < 8; i++) {
|
||||
checkEvent(battle.log.events[i], battle.play_order[i], "move", null, battle.play_order[i].arena_x, battle.play_order[i].arena_y);
|
||||
}
|
||||
checkEvent(battle.log.events[8], battle.playing_ship, "ship_change", battle.playing_ship);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/// <reference path="../definitions/jasmine.d.ts"/>
|
||||
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||
|
||||
module SpaceTac.Specs {
|
||||
describe("Ship", function(){
|
|
@ -17,15 +17,30 @@ module SpaceTac.View {
|
|||
// Targetting mode (null if we're not in this mode)
|
||||
targetting: Targetting;
|
||||
|
||||
// Card to display current playing ship
|
||||
card_playing: Widgets.ShipCard;
|
||||
|
||||
// Card to display hovered ship
|
||||
card_hovered: Widgets.ShipCard;
|
||||
|
||||
// Currently hovered ship
|
||||
ship_hovered: Game.Ship;
|
||||
|
||||
// Subscription to the battle log
|
||||
log_subscription: any;
|
||||
|
||||
// Init the view, binding it to a specific battle
|
||||
init(player, battle) {
|
||||
this.player = player;
|
||||
this.battle = battle;
|
||||
this.targetting = null;
|
||||
this.ship_hovered = null;
|
||||
this.log_subscription = null;
|
||||
}
|
||||
|
||||
// Create view graphics
|
||||
create() {
|
||||
var battleview = this;
|
||||
var game = this.game;
|
||||
var player = this.player;
|
||||
|
||||
|
@ -37,28 +52,83 @@ module SpaceTac.View {
|
|||
game.add.existing(this.arena);
|
||||
var arena = this.arena;
|
||||
|
||||
this.card_playing = new Widgets.ShipCard(this, 500, 0);
|
||||
this.card_hovered = new Widgets.ShipCard(this, 500, 300);
|
||||
|
||||
game.stage.backgroundColor = 0x000000;
|
||||
|
||||
// Add ship buttons to UI
|
||||
this.battle.play_order.forEach(function(ship: Game.Ship, rank: number){
|
||||
new Widgets.ShipListItem(ui, 0, rank * 50, ship.getPlayer() === player);
|
||||
this.battle.play_order.forEach(function (ship: Game.Ship, rank: number) {
|
||||
new Widgets.ShipListItem(battleview, 0, rank * 50, ship, ship.getPlayer() === player);
|
||||
});
|
||||
|
||||
// Add ship sprites to arena
|
||||
this.battle.play_order.forEach(function(ship: Game.Ship){
|
||||
new Arena.ShipArenaSprite(arena, ship);
|
||||
this.battle.play_order.forEach(function (ship: Game.Ship) {
|
||||
new Arena.ShipArenaSprite(battleview, ship);
|
||||
});
|
||||
|
||||
// Subscribe to log events
|
||||
this.battle.log.subscribe((event) => {
|
||||
battleview.processBattleEvent(event);
|
||||
});
|
||||
this.battle.injectInitialEvents();
|
||||
}
|
||||
|
||||
// Leaving the view, we unbind the battle
|
||||
shutdown() {
|
||||
if (this.log_subscription) {
|
||||
this.battle.log.unsubscribe(this.log_subscription);
|
||||
this.log_subscription = null;
|
||||
}
|
||||
|
||||
if (this.ui) {
|
||||
this.ui.destroy();
|
||||
this.ui = null;
|
||||
}
|
||||
|
||||
if (this.arena) {
|
||||
this.arena.destroy();
|
||||
this.arena = null;
|
||||
}
|
||||
|
||||
if (this.card_playing) {
|
||||
this.card_playing.destroy();
|
||||
this.card_playing = null;
|
||||
}
|
||||
|
||||
if (this.card_hovered) {
|
||||
this.card_hovered.destroy();
|
||||
this.card_hovered = null;
|
||||
}
|
||||
|
||||
this.battle = null;
|
||||
}
|
||||
|
||||
this.ui.destroy();
|
||||
this.ui = null;
|
||||
// Process a BaseLogEvent
|
||||
processBattleEvent(event: Game.Events.BaseLogEvent) {
|
||||
console.log("Battle event", event);
|
||||
if (event.code == "ship_change") {
|
||||
// Playing ship changed
|
||||
this.card_playing.setShip(event.target.ship);
|
||||
}
|
||||
}
|
||||
|
||||
this.arena.destroy();
|
||||
this.arena = null;
|
||||
// Method called when cursor starts hovering over a ship (or its icon)
|
||||
cursorOnShip(ship: Game.Ship): void {
|
||||
this.setShipHovered(ship);
|
||||
}
|
||||
|
||||
// Method called when cursor stops hovering over a ship (or its icon)
|
||||
cursorOffShip(ship: Game.Ship): void {
|
||||
if (this.ship_hovered === ship) {
|
||||
this.setShipHovered(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the currently hovered ship
|
||||
setShipHovered(ship: Game.Ship): void {
|
||||
this.ship_hovered = ship;
|
||||
this.card_hovered.setShip(ship);
|
||||
}
|
||||
|
||||
// Enter targetting mode
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
module SpaceTac.Arena {
|
||||
module SpaceTac.View.Arena {
|
||||
// Ship sprite in the arena (BattleView)
|
||||
export class ShipArenaSprite extends Phaser.Sprite {
|
||||
constructor(arena: Phaser.Group, ship: Game.Ship) {
|
||||
super(arena.game, ship.arena_x, ship.arena_y, "arena-ship");
|
||||
export class ShipArenaSprite extends Phaser.Button {
|
||||
constructor(battleview: BattleView, ship: Game.Ship) {
|
||||
super(battleview.game, ship.arena_x, ship.arena_y, "arena-ship");
|
||||
|
||||
this.scale.set(0.1, 0.1);
|
||||
this.rotation = ship.arena_angle;
|
||||
this.anchor.set(0.5, 0.5);
|
||||
|
||||
arena.add(this);
|
||||
battleview.arena.add(this);
|
||||
|
||||
this.onInputOver.add(() => {
|
||||
battleview.cursorOnShip(ship);
|
||||
});
|
||||
this.onInputOut.add(() => {
|
||||
battleview.cursorOffShip(ship);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
src/scripts/view/widgets/ShipCard.ts
Normal file
23
src/scripts/view/widgets/ShipCard.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
module SpaceTac.View.Widgets {
|
||||
// Card to display detailed information about a ship
|
||||
export class ShipCard extends Phaser.Sprite {
|
||||
// Displayed ship
|
||||
private ship: Game.Ship;
|
||||
|
||||
// Build an empty ship card
|
||||
constructor(battleview: BattleView, x: number, y: number) {
|
||||
super(battleview.game, x, y, "ui-ship-card");
|
||||
|
||||
this.ship = null;
|
||||
this.visible = false;
|
||||
|
||||
battleview.ui.add(this);
|
||||
}
|
||||
|
||||
// Set the currently displayed ship (null to hide)
|
||||
setShip(ship: Game.Ship) {
|
||||
this.ship = ship;
|
||||
this.visible = (ship !== null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,22 @@
|
|||
module SpaceTac.View.Widgets {
|
||||
// One item in a ship list (used in BattleView)
|
||||
export class ShipListItem extends Phaser.Button {
|
||||
// Reference to the ship game object
|
||||
private ship: Game.Ship;
|
||||
|
||||
// Create a ship button for the battle ship list
|
||||
constructor(ui: UIGroup, x: number, y: number, owned: boolean) {
|
||||
super(ui.game, x, y, owned ? 'ui-shiplist-own' : 'ui-shiplist-enemy');
|
||||
ui.add(this);
|
||||
constructor(battleview: BattleView, x: number, y: number, ship:Game.Ship, owned: boolean) {
|
||||
this.ship = ship;
|
||||
|
||||
super(battleview.game, x, y, owned ? 'ui-shiplist-own' : 'ui-shiplist-enemy');
|
||||
battleview.ui.add(this);
|
||||
|
||||
this.onInputOver.add(() => {
|
||||
battleview.cursorOnShip(ship);
|
||||
});
|
||||
this.onInputOut.add(() => {
|
||||
battleview.cursorOffShip(ship);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue