Fixed character sheet layering
This commit is contained in:
parent
99882829a9
commit
4312dcf893
2
TODO.md
2
TODO.md
|
@ -34,7 +34,6 @@ Character sheet
|
|||
* Allow to cancel spent skill points (and confirm when closing the sheet)
|
||||
* Add filters and sort options for cargo and shop
|
||||
* Display level and slot type on equipment
|
||||
* Fix dragged equipment being under attributes (put attributes in a layer)
|
||||
|
||||
Battle
|
||||
------
|
||||
|
@ -96,6 +95,7 @@ Common UI
|
|||
|
||||
* Split atlases by asset stage
|
||||
* UIBuilder.button should be able to handle hover and pushed images
|
||||
* If ProgressiveMessage animation performance is bad, show the text directly
|
||||
* Add caret/focus to text input
|
||||
* Mobile: think UI layout so that fingers do not block the view (right and left handed)
|
||||
* Mobile: display tooltips larger and on the side of screen where the finger is not
|
||||
|
|
BIN
graphics/exported/common/arrow-down.png
Normal file
BIN
graphics/exported/common/arrow-down.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
graphics/exported/common/arrow-left.png
Normal file
BIN
graphics/exported/common/arrow-left.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
graphics/exported/common/arrow-right.png
Normal file
BIN
graphics/exported/common/arrow-right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
graphics/exported/common/arrow-up.png
Normal file
BIN
graphics/exported/common/arrow-up.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -21,13 +21,13 @@ module TK.SpaceTac.UI.Specs {
|
|||
|
||||
sheet.show(ship1);
|
||||
expect(sheet.portraits.length).toBe(2);
|
||||
expect(sheet.equipments.length).toBe(3);
|
||||
expect(sheet.layer_equipments.length).toBe(3);
|
||||
expect(sheet.ship_cargo.length).toBe(3);
|
||||
|
||||
// First item fits in the free slot
|
||||
let source = <CharacterCargo>sheet.ship_cargo.children[0];
|
||||
let dest = <CharacterFleetMember>sheet.portraits.children[1];
|
||||
let equ = <CharacterEquipment>sheet.equipments.children[0];
|
||||
let equ = <CharacterEquipment>sheet.layer_equipments.children[0];
|
||||
expect(dest.ship).toBe(ship2);
|
||||
expect(equ.item).toBe(equ1);
|
||||
expect(ship1.cargo).toContain(equ1);
|
||||
|
@ -39,7 +39,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
// Second item goes to cargo
|
||||
source = <CharacterCargo>sheet.ship_cargo.children[0];
|
||||
dest = <CharacterFleetMember>sheet.portraits.children[1];
|
||||
equ = <CharacterEquipment>sheet.equipments.children[1];
|
||||
equ = <CharacterEquipment>sheet.layer_equipments.children[1];
|
||||
expect(dest.ship).toBe(ship2);
|
||||
expect(equ.item).toBe(equ2);
|
||||
expect(ship1.cargo).toContain(equ2);
|
||||
|
@ -51,7 +51,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
// Third item has no more room
|
||||
source = <CharacterCargo>sheet.ship_cargo.children[0];
|
||||
dest = <CharacterFleetMember>sheet.portraits.children[1];
|
||||
equ = <CharacterEquipment>sheet.equipments.children[2];
|
||||
equ = <CharacterEquipment>sheet.layer_equipments.children[2];
|
||||
expect(dest.ship).toBe(ship2);
|
||||
expect(equ.item).toBe(equ3);
|
||||
expect(ship1.cargo).toContain(equ3);
|
||||
|
|
|
@ -26,14 +26,14 @@ module TK.SpaceTac.UI.Specs {
|
|||
expect(loot_slot instanceof CharacterLootSlot).toBe(true);
|
||||
|
||||
// loot to cargo
|
||||
let equ2s = <CharacterEquipment>sheet.equipments.children[1];
|
||||
let equ2s = <CharacterEquipment>sheet.layer_equipments.children[1];
|
||||
expect(equ2s.item).toBe(equ2);
|
||||
equ2s.applyDragDrop(loot_slot, cargo_slot, false);
|
||||
expect(ship.cargo).toEqual([equ1, equ2]);
|
||||
expect(loot).toEqual([]);
|
||||
|
||||
// discard to cargo
|
||||
let equ1s = <CharacterEquipment>sheet.equipments.children[0];
|
||||
let equ1s = <CharacterEquipment>sheet.layer_equipments.children[0];
|
||||
expect(equ1s.item).toBe(equ1);
|
||||
equ1s.applyDragDrop(cargo_slot, loot_slot, false);
|
||||
expect(ship.cargo).toEqual([equ2]);
|
||||
|
|
|
@ -56,14 +56,14 @@ module TK.SpaceTac.UI.Specs {
|
|||
sheet.show(ship, false);
|
||||
|
||||
expect(sheet.loot_slots.visible).toBe(false);
|
||||
expect(sheet.equipments.children.length).toBe(2);
|
||||
expect(sheet.layer_equipments.children.length).toBe(2);
|
||||
|
||||
sheet.setLoot(loot);
|
||||
|
||||
expect(sheet.loot_slots.visible).toBe(true);
|
||||
expect(sheet.equipments.children.length).toBe(4);
|
||||
expect(sheet.layer_equipments.children.length).toBe(4);
|
||||
|
||||
let findsprite = (equ: Equipment) => nn(first(<CharacterEquipment[]>sheet.equipments.children, sp => sp.item == equ));
|
||||
let findsprite = (equ: Equipment) => nn(first(<CharacterEquipment[]>sheet.layer_equipments.children, sp => sp.item == equ));
|
||||
let draddrop = (sp: CharacterEquipment, dest: CharacterCargo | CharacterSlot) => {
|
||||
sp.applyDragDrop(sp.container, dest, false);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ module TK.SpaceTac.UI {
|
|||
// Parent view
|
||||
view: BaseView
|
||||
|
||||
// UI components builder
|
||||
builder: UIBuilder
|
||||
|
||||
// X positions
|
||||
xshown: number
|
||||
xhidden: number
|
||||
|
@ -33,7 +36,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
// Ship skill upgrade
|
||||
ship_upgrade_points: Phaser.Text
|
||||
ship_upgrades: Phaser.Group
|
||||
layer_upgrades: Phaser.Group
|
||||
|
||||
// Ship slots
|
||||
ship_slots: Phaser.Group
|
||||
|
@ -58,8 +61,9 @@ module TK.SpaceTac.UI {
|
|||
members: CharacterFleetMember[] = []
|
||||
portraits: Phaser.Group
|
||||
|
||||
// Layer for draggable equipments
|
||||
equipments: Phaser.Group
|
||||
// Layers
|
||||
layer_attibutes: Phaser.Group
|
||||
layer_equipments: Phaser.Group
|
||||
|
||||
// Credits
|
||||
credits: Phaser.Text
|
||||
|
@ -71,6 +75,7 @@ module TK.SpaceTac.UI {
|
|||
super(view.game, 0, 0, "character-sheet");
|
||||
|
||||
this.view = view;
|
||||
this.builder = new UIBuilder(view, this);
|
||||
|
||||
this.x = xhidden;
|
||||
this.xshown = xshown;
|
||||
|
@ -80,65 +85,33 @@ module TK.SpaceTac.UI {
|
|||
if (!onclose) {
|
||||
onclose = () => this.hide();
|
||||
}
|
||||
this.close_button = view.newButton("character-close", 1920, 0, onclose);
|
||||
this.close_button = this.builder.button("character-close", 1920, 0, onclose, "Close the character sheet");
|
||||
this.close_button.anchor.set(1, 0);
|
||||
this.addChild(this.close_button);
|
||||
view.tooltip.bindStaticText(this.close_button, "Close the character sheet");
|
||||
|
||||
this.addChild(view.newText("Level", 420, 1052, 24));
|
||||
this.addChild(view.newText("Available points", 894, 1052, 24));
|
||||
this.builder.text("Level", 420, 1052, { size: 24 });
|
||||
this.builder.text("Available points", 894, 1052, { size: 24 });
|
||||
|
||||
this.ship_name = view.newText("", 758, 48, 30);
|
||||
this.addChild(this.ship_name);
|
||||
|
||||
this.ship_level = view.newText("", 554, 1052, 30);
|
||||
this.addChild(this.ship_level);
|
||||
this.ship_name = this.builder.text("", 758, 48, { size: 30 });
|
||||
this.ship_level = this.builder.text("", 554, 1052, { size: 30 });
|
||||
this.ship_upgrade_points = this.builder.text("", 1068, 1052, { size: 30 });
|
||||
this.ship_slots = this.builder.group("slots", 372, 120);
|
||||
this.ship_cargo = this.builder.group("cargo", 1240, 86);
|
||||
this.loot_slots = this.builder.group("loot", 1270, 670);
|
||||
this.loot_slots.visible = false;
|
||||
this.portraits = this.builder.group("portraits", 152, 0);
|
||||
this.credits = this.builder.text("", 136, 38, { size: 30 });
|
||||
this.mode_title = this.builder.text("", 1566, 648, { size: 18 });
|
||||
this.loot_next = this.builder.button("common-arrow-right", 1890, 850, () => this.paginate(1), "Show next items");
|
||||
this.loot_next.anchor.set(0.5);
|
||||
this.loot_prev = this.builder.button("common-arrow-left", 1238, 850, () => this.paginate(-1), "Show previous items");
|
||||
this.loot_prev.anchor.set(0.5);
|
||||
|
||||
this.ship_experience = new ValueBar(this.view, "character-experience", ValueBarOrientation.EAST, 516, 1067);
|
||||
this.addChild(this.ship_experience.node);
|
||||
|
||||
this.ship_upgrade_points = view.newText("", 1068, 1052, 30);
|
||||
this.addChild(this.ship_upgrade_points);
|
||||
|
||||
this.ship_upgrades = new Phaser.Group(this.game);
|
||||
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.ship_cargo = new Phaser.Group(this.game);
|
||||
this.ship_cargo.position.set(1240, 86);
|
||||
this.addChild(this.ship_cargo);
|
||||
|
||||
this.loot_slots = new Phaser.Group(this.game);
|
||||
this.loot_slots.position.set(1270, 670);
|
||||
this.loot_slots.visible = false;
|
||||
this.addChild(this.loot_slots);
|
||||
|
||||
this.portraits = new Phaser.Group(this.game);
|
||||
this.portraits.position.set(152, 0);
|
||||
this.addChild(this.portraits);
|
||||
|
||||
this.credits = view.newText("", 136, 38, 30);
|
||||
this.addChild(this.credits);
|
||||
|
||||
this.equipments = new Phaser.Group(this.game);
|
||||
this.addChild(this.equipments);
|
||||
|
||||
this.mode_title = view.newText("", 1566, 648, 18);
|
||||
this.addChild(this.mode_title);
|
||||
|
||||
this.loot_next = new Phaser.Button(this.game, 1890, 850, "common-arrow", () => this.paginate(1));
|
||||
this.loot_next.anchor.set(0.5, 0.5);
|
||||
UIComponent.setButtonSound(this.loot_next);
|
||||
this.addChild(this.loot_next);
|
||||
|
||||
this.loot_prev = new Phaser.Button(this.game, 1238, 850, "common-arrow", () => this.paginate(-1));
|
||||
this.loot_prev.anchor.set(0.5, 0.5);
|
||||
this.loot_prev.angle = 180;
|
||||
UIComponent.setButtonSound(this.loot_prev);
|
||||
this.addChild(this.loot_prev);
|
||||
this.layer_attibutes = this.builder.group("attributes");
|
||||
this.layer_upgrades = this.builder.group("upgrades");
|
||||
this.layer_equipments = this.builder.group("equipments");
|
||||
|
||||
let x1 = 402;
|
||||
let x2 = 802;
|
||||
|
@ -161,29 +134,22 @@ module TK.SpaceTac.UI {
|
|||
* Add an attribute display
|
||||
*/
|
||||
private addAttribute(attribute: keyof ShipAttributes, x: number, y: number) {
|
||||
let button = this.view.newButton("character-attribute", x, y);
|
||||
this.addChild(button);
|
||||
this.view.tooltip.bindDynamicText(button, () => this.ship.getAttributeDescription(attribute));
|
||||
let builder = this.builder.in(this.layer_attibutes);
|
||||
|
||||
let button = builder.button("character-attribute", x, y, undefined, () => this.ship.getAttributeDescription(attribute));
|
||||
|
||||
let attrname = capitalize(SHIP_ATTRIBUTES[attribute].name);
|
||||
let name = new Phaser.Text(this.game, 120, 22, attrname,
|
||||
{ align: "center", font: "20pt SpaceTac", fill: "#c9d8ef", stroke: "#395665", strokeThickness: 1 });
|
||||
name.anchor.set(0.5);
|
||||
button.addChild(name);
|
||||
builder.in(button).text(attrname, 120, 22, { size: 20, color: "#c9d8ef", stroke_width: 1, stroke_color: "#395665" });
|
||||
|
||||
let value = this.view.newText("", 264, 24, 18, "#ffffff", true, true);
|
||||
button.addChild(value);
|
||||
let value = builder.in(button).text("", 264, 24, { size: 18, bold: true });
|
||||
|
||||
this.attributes[attribute] = value;
|
||||
|
||||
if (SHIP_SKILLS.hasOwnProperty(attribute)) {
|
||||
let upgrade_button = this.view.newButton("character-skill-upgrade", x + 292, y, () => {
|
||||
this.builder.in(this.layer_upgrades).button("character-skill-upgrade", x + 292, y, () => {
|
||||
this.ship.upgradeSkill(<keyof ShipSkills>attribute);
|
||||
this.refresh();
|
||||
});
|
||||
this.ship_upgrades.add(upgrade_button);
|
||||
|
||||
this.view.tooltip.bindStaticText(upgrade_button, `Spend one point to upgrade ${attrname}`);
|
||||
}, `Spend one point to upgrade ${attrname}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +188,7 @@ module TK.SpaceTac.UI {
|
|||
show(ship: Ship, animate = true, sound = true) {
|
||||
this.ship = ship;
|
||||
|
||||
this.equipments.removeAll(true);
|
||||
this.layer_equipments.removeAll(true);
|
||||
|
||||
let upgrade_points = ship.getAvailableUpgradePoints();
|
||||
|
||||
|
@ -230,7 +196,7 @@ module TK.SpaceTac.UI {
|
|||
this.ship_level.setText(ship.level.get().toString());
|
||||
this.ship_experience.setValue(ship.level.getExperience(), ship.level.getNextGoal());
|
||||
this.ship_upgrade_points.setText(upgrade_points.toString());
|
||||
this.ship_upgrades.visible = !ship.critical && upgrade_points > 0;
|
||||
this.layer_upgrades.visible = !ship.critical && upgrade_points > 0;
|
||||
|
||||
iteritems(<any>ship.attributes, (key, value: ShipAttribute) => {
|
||||
let text = this.attributes[key];
|
||||
|
@ -249,7 +215,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
if (slot.attached) {
|
||||
let equipment = new CharacterEquipment(this, slot.attached, slot_display);
|
||||
this.equipments.addChild(equipment);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -263,7 +229,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
if (idx < this.ship.cargo.length) {
|
||||
let equipment = new CharacterEquipment(this, this.ship.cargo[idx], cargo_slot);
|
||||
this.equipments.addChild(equipment);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -345,7 +311,7 @@ module TK.SpaceTac.UI {
|
|||
* Update the price tags on each equipment, for a specific shop
|
||||
*/
|
||||
updatePrices(shop: Shop) {
|
||||
this.equipments.children.forEach((equipement: CharacterEquipment) => {
|
||||
this.layer_equipments.children.forEach((equipement: CharacterEquipment) => {
|
||||
equipement.setPrice(shop.getPrice(equipement.item));
|
||||
});
|
||||
}
|
||||
|
@ -377,7 +343,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
if (idx < items.length) {
|
||||
let equipment = new CharacterEquipment(this, items[idx], loot_slot);
|
||||
this.equipments.addChild(equipment);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
expect(shop_slot instanceof CharacterShopSlot).toBe(true);
|
||||
|
||||
// sell
|
||||
let equ1s = <CharacterEquipment>sheet.equipments.children[0];
|
||||
let equ1s = <CharacterEquipment>sheet.layer_equipments.children[0];
|
||||
expect(equ1s.item).toBe(equ1);
|
||||
equ1s.applyDragDrop(cargo_slot, shop_slot, false);
|
||||
expect(ship.cargo).toEqual([]);
|
||||
|
@ -37,7 +37,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
expect(fleet.credits).toBe(220);
|
||||
|
||||
// buy
|
||||
let equ2s = <CharacterEquipment>sheet.equipments.children[1];
|
||||
let equ2s = <CharacterEquipment>sheet.layer_equipments.children[1];
|
||||
expect(equ2s.item).toBe(equ2);
|
||||
equ2s.applyDragDrop(shop_slot, cargo_slot, false);
|
||||
expect(ship.cargo).toEqual([equ2]);
|
||||
|
@ -45,7 +45,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
expect(fleet.credits).toBe(100);
|
||||
|
||||
// not enough money
|
||||
equ1s = <CharacterEquipment>sheet.equipments.children[0];
|
||||
equ1s = <CharacterEquipment>sheet.layer_equipments.children[0];
|
||||
expect(equ1s.item).toBe(equ1);
|
||||
equ1s.applyDragDrop(shop_slot, cargo_slot, false);
|
||||
expect(ship.cargo).toEqual([equ2]);
|
||||
|
|
|
@ -50,20 +50,22 @@ module TK.SpaceTac.UI {
|
|||
}
|
||||
});
|
||||
|
||||
this.input.keyboard.addCallbacks(this, undefined, (event: KeyboardEvent) => {
|
||||
if (this.debug) {
|
||||
console.log(event);
|
||||
}
|
||||
|
||||
this.forceLeaveHovered();
|
||||
|
||||
if (!contains(["Control", "Shift", "Alt", "Meta"], event.key)) {
|
||||
this.keyPress(event.key);
|
||||
if (event.code != event.key) {
|
||||
this.keyPress(event.code);
|
||||
if (!this.game.headless) {
|
||||
this.input.keyboard.addCallbacks(this, undefined, (event: KeyboardEvent) => {
|
||||
if (this.debug) {
|
||||
console.log(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.forceLeaveHovered();
|
||||
|
||||
if (!contains(["Control", "Shift", "Alt", "Meta"], event.key)) {
|
||||
this.keyPress(event.key);
|
||||
if (event.code != event.key) {
|
||||
this.keyPress(event.code);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -111,6 +111,12 @@ module TK.SpaceTac.UI.Specs {
|
|||
check(["View layers", "base", 0], Phaser.Text, "", { shadowColor: "rgba(0,0,0,0)" });
|
||||
check(["View layers", "base", 1], Phaser.Text, "", { shadowColor: "rgba(0,0,0,0.6)", shadowFill: true, shadowOffsetX: 3, shadowOffsetY: 4, shadowBlur: 6, shadowStroke: true });
|
||||
|
||||
builder.clear();
|
||||
builder.text("", 0, 0, {});
|
||||
builder.text("", 0, 0, { stroke_width: 2, stroke_color: "#ff0000" });
|
||||
check(["View layers", "base", 0], Phaser.Text, "", { stroke: "black", strokeThickness: 0 });
|
||||
check(["View layers", "base", 1], Phaser.Text, "", { stroke: "#ff0000", strokeThickness: 2 });
|
||||
|
||||
builder.clear();
|
||||
builder.text("", 0, 0, {});
|
||||
builder.text("", 0, 0, { bold: true });
|
||||
|
|
|
@ -5,6 +5,7 @@ module TK.SpaceTac.UI {
|
|||
export type UIText = Phaser.Text
|
||||
export type UIImage = Phaser.Image
|
||||
export type UIButton = Phaser.Button
|
||||
export type UIGroup = Phaser.Group
|
||||
export type UIContainer = Phaser.Group | Phaser.Image
|
||||
|
||||
/**
|
||||
|
@ -14,6 +15,8 @@ module TK.SpaceTac.UI {
|
|||
size?: number
|
||||
color?: string
|
||||
shadow?: boolean
|
||||
stroke_width?: number
|
||||
stroke_color?: string
|
||||
bold?: boolean
|
||||
center?: boolean
|
||||
vcenter?: boolean
|
||||
|
@ -33,6 +36,10 @@ module TK.SpaceTac.UI {
|
|||
// Shadow under the text
|
||||
shadow = false
|
||||
|
||||
// Stroke around the letters
|
||||
stroke_width = 0
|
||||
stroke_color = "#ffffff"
|
||||
|
||||
// Bold text
|
||||
bold = false
|
||||
|
||||
|
@ -105,7 +112,7 @@ module TK.SpaceTac.UI {
|
|||
/**
|
||||
* Add a group of components
|
||||
*/
|
||||
group(name: string, x = 0, y = 0): UIContainer {
|
||||
group(name: string, x = 0, y = 0): UIGroup {
|
||||
let result = new Phaser.Group(this.game, undefined, name);
|
||||
result.position.set(x, y);
|
||||
this.add(result);
|
||||
|
@ -132,6 +139,10 @@ module TK.SpaceTac.UI {
|
|||
if (style.shadow) {
|
||||
result.setShadow(3, 4, "rgba(0,0,0,0.6)", 6);
|
||||
}
|
||||
if (style.stroke_width) {
|
||||
result.stroke = style.stroke_color;
|
||||
result.strokeThickness = style.stroke_width;
|
||||
}
|
||||
this.add(result);
|
||||
return result;
|
||||
}
|
||||
|
@ -154,7 +165,7 @@ module TK.SpaceTac.UI {
|
|||
/**
|
||||
* Add a clickable button
|
||||
*/
|
||||
button(name: string, x = 0, y = 0, onclick?: Function): UIButton {
|
||||
button(name: string, x = 0, y = 0, onclick?: Function, tooltip?: string | (() => string)): UIButton {
|
||||
let info = this.view.getImageInfo(name);
|
||||
let result = new Phaser.Button(this.game, x, y, info.key, onclick || nop, null, info.frame, info.frame);
|
||||
result.name = name;
|
||||
|
@ -163,6 +174,13 @@ module TK.SpaceTac.UI {
|
|||
if (clickable) {
|
||||
UIComponent.setButtonSound(result);
|
||||
}
|
||||
if (tooltip) {
|
||||
if (typeof tooltip == "string") {
|
||||
this.view.tooltip.bindStaticText(result, tooltip);
|
||||
} else {
|
||||
this.view.tooltip.bindDynamicText(result, tooltip);
|
||||
}
|
||||
}
|
||||
this.add(result);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue