diff --git a/out/assets/images/character/slot-power.png b/out/assets/images/character/slot-power.png new file mode 100644 index 0000000..9e313f0 Binary files /dev/null and b/out/assets/images/character/slot-power.png differ diff --git a/src/ui/Preload.ts b/src/ui/Preload.ts index 96f576c..2ca457f 100644 --- a/src/ui/Preload.ts +++ b/src/ui/Preload.ts @@ -83,6 +83,7 @@ module TS.SpaceTac.UI { this.loadImage("character/ship-selected.png"); this.loadImage("character/cargo-slot.png"); this.loadImage("character/equipment-slot.png"); + this.loadImage("character/slot-power.png"); // Load ships this.loadShip("scout"); diff --git a/src/ui/character/CharacterSheet.spec.ts b/src/ui/character/CharacterSheet.spec.ts index 16dddde..b629321 100644 --- a/src/ui/character/CharacterSheet.spec.ts +++ b/src/ui/character/CharacterSheet.spec.ts @@ -1,29 +1,48 @@ module TS.SpaceTac.UI.Specs { describe("CharacterSheet", function () { - let testgame = setupEmptyView(); - it("displays fleet and ship information", function () { - let view = testgame.baseview; - let sheet = new CharacterSheet(view, -1000); + describe("in UI", function () { + let testgame = setupEmptyView(); - expect(sheet.x).toEqual(-1000); + it("displays fleet and ship information", function () { + let view = testgame.baseview; + let sheet = new CharacterSheet(view, -1000); - let fleet = new Fleet(); - let ship1 = fleet.addShip(); - ship1.name = "Ship 1"; - let ship2 = fleet.addShip(); - ship2.name = "Ship 2"; + expect(sheet.x).toEqual(-1000); - sheet.show(ship1, false); + let fleet = new Fleet(); + let ship1 = fleet.addShip(); + ship1.addSlot(SlotType.Armor); + ship1.addSlot(SlotType.Engine); + ship1.addSlot(SlotType.Shield); + ship1.addSlot(SlotType.Weapon); + ship1.name = "Ship 1"; + let ship2 = fleet.addShip(); + ship2.addSlot(SlotType.Armor); + ship2.name = "Ship 2"; - expect(sheet.x).toEqual(0); - expect(sheet.portraits.length).toBe(2); - expect(sheet.ship_name.text).toEqual("Ship 1"); + sheet.show(ship1, false); - let portrait = sheet.portraits.getChildAt(1); - portrait.onInputUp.dispatch(); + expect(sheet.x).toEqual(0); + expect(sheet.portraits.length).toBe(2); - expect(sheet.ship_name.text).toEqual("Ship 2"); + expect(sheet.ship_name.text).toEqual("Ship 1"); + expect(sheet.ship_slots.length).toBe(4); + + let portrait = sheet.portraits.getChildAt(1); + portrait.onInputUp.dispatch(); + + expect(sheet.ship_name.text).toEqual("Ship 2"); + expect(sheet.ship_slots.length).toBe(1); + }); + }); + + it("fits slots in area", function () { + let result = CharacterSheet.getSlotPositions(6, 300, 200, 100, 100); + expect(result).toEqual({ + positions: [{ x: 0, y: 0 }, { x: 100, y: 0 }, { x: 200, y: 0 }, { x: 0, y: 100 }, { x: 100, y: 100 }, { x: 200, y: 100 }], + scaling: 1 + }); }); }); } diff --git a/src/ui/character/CharacterSheet.ts b/src/ui/character/CharacterSheet.ts index 5c75992..e302a73 100644 --- a/src/ui/character/CharacterSheet.ts +++ b/src/ui/character/CharacterSheet.ts @@ -22,6 +22,9 @@ module TS.SpaceTac.UI { // Ship upgrade points ship_upgrades: Phaser.Text; + // Ship slots + ship_slots: Phaser.Group; + // Fleet's portraits portraits: Phaser.Group; @@ -55,6 +58,10 @@ module TS.SpaceTac.UI { this.ship_upgrades.anchor.set(0.5, 0.5); this.addChild(this.ship_upgrades); + this.ship_slots = new Phaser.Group(this.game); + this.ship_slots.position.set(372, 120); + this.addChild(this.ship_slots); + this.portraits = new Phaser.Group(this.game); this.portraits.position.set(152, 0); this.addChild(this.portraits); @@ -139,6 +146,14 @@ module TS.SpaceTac.UI { } }); + let slotsinfo = CharacterSheet.getSlotPositions(ship.slots.length, 800, 454, 200, 200); + this.ship_slots.removeAll(true); + ship.slots.forEach((slot, idx) => { + let slot_display = new CharacterSlot(this, slotsinfo.positions[idx].x, slotsinfo.positions[idx].y, slot.type); + slot_display.scale.set(slotsinfo.scaling, slotsinfo.scaling); + this.ship_slots.addChild(slot_display); + }); + this.updateFleet(ship.fleet); if (animate) { @@ -159,7 +174,33 @@ module TS.SpaceTac.UI { } else { this.x = this.xhidden; } + } + /** + * Get the positions and scaling for slots, to fit in ship_slots group. + */ + static getSlotPositions(count: number, areawidth: number, areaheight: number, slotwidth: number, slotheight: number): { positions: { x: number, y: number }[], scaling: number } { + // Find grid size + let rows = 2; + let columns = 3; + while (count > rows * columns) { + rows += 1; + columns += 1; + } + + // Find scaling + let scaling = 1; + while (slotwidth * scaling > areawidth || slotheight * scaling > areaheight) { + scaling *= 0.99; + } + + // Position + let positions = range(count).map(i => { + let row = Math.floor(i / columns); + let column = i % columns; + return { x: column * (areawidth - slotwidth * scaling) / (columns - 1), y: row * (areaheight - slotheight * scaling) / (rows - 1) }; + }); + return { positions: positions, scaling: scaling }; } } } diff --git a/src/ui/character/CharacterSlot.ts b/src/ui/character/CharacterSlot.ts new file mode 100644 index 0000000..77e16da --- /dev/null +++ b/src/ui/character/CharacterSlot.ts @@ -0,0 +1,14 @@ +module TS.SpaceTac.UI { + /** + * Display a ship slot, with equipment attached to it + */ + export class CharacterSlot extends Phaser.Image { + constructor(sheet: CharacterSheet, x: number, y: number, slot: SlotType) { + super(sheet.game, x, y, "character-equipment-slot"); + + let sloticon = new Phaser.Image(this.game, 150, 150, `character-slot-${SlotType[slot].toLowerCase()}`); + sloticon.anchor.set(0.5, 0.5); + this.addChild(sloticon); + } + } +}