1
0
Fork 0

Fixed map screen not being interactive

This commit is contained in:
Michaël Lemaire 2018-06-06 19:09:31 +02:00
parent a5c845d369
commit b6261bb420
10 changed files with 153 additions and 61 deletions

View File

@ -8,6 +8,7 @@ Phaser 3 migration
* Fit the game in window size
* Fix top-right messages positions
* Fix valuebar requiring to be in root display list
* Restore unit tests about boundaries (in UITools)
Menu/settings/saves
-------------------

View File

@ -225,7 +225,8 @@ module TK.SpaceTac.UI {
return {
foreground: async () => {
if (reaction instanceof PersonalityReactionConversation) {
let conversation = UIConversation.newFromPieces(this.view, reaction.messages);
let builder = new UIBuilder(this.view, this.view.layer_overlay);
let conversation = UIConversation.newFromPieces(builder, reaction.messages);
await conversation.waitEnd();
} else {
console.warn("[LogProcessor] Unknown personality reaction type", reaction);

View File

@ -226,6 +226,15 @@ module TK.SpaceTac.UI {
return result;
}
/**
* Add a full-view capturing overlay
*/
overlay(options: UIOverlayOptions): UIOverlay {
let result = new UIOverlay(this.view, options);
this.add(result);
return result;
}
/**
* Change the content of an component
*

View File

@ -68,7 +68,7 @@ module TK.SpaceTac.UI {
/**
* Draw a background
*/
drawBackground(fill: number, border?: number, border_width = 0, alpha = 1, mouse_capture?: Function) {
drawBackground(fill: number, border?: number, border_width = 0, alpha = 1) {
if (this.background) {
this.background.destroy();
}
@ -76,11 +76,6 @@ module TK.SpaceTac.UI {
let rect = new Phaser.Geom.Rectangle(0, 0, this.width, this.height);
this.background = this.addInternalChild(new UIGraphics(this.view, "background"));
this.background.addRectangle(rect, fill, border_width, border, alpha);
if (mouse_capture) {
this.background.setInteractive(rect, Phaser.Geom.Rectangle.Contains);
this.background.on("pointerup", () => mouse_capture());
}
}
/**

View File

@ -27,5 +27,17 @@ module TK.SpaceTac.UI {
output.setTo(result.x, result.y, result.width, result.height);
return output;
}
/**
* Overload of setVisible, with fading support
*/
setVisible(visible: boolean, duration = 0): this {
if (duration) {
(<BaseView>this.scene).animations.setVisible(this, visible, duration);
} else {
super.setVisible(visible);
}
return this;
}
}
}

View File

@ -39,64 +39,98 @@ module TK.SpaceTac.UI {
/**
* Rectangle to display a message that may appear progressively, as in conversations
*/
export class UIConversationMessage extends UIComponent {
constructor(parent: BaseView | UIComponent, width: number, height: number, message: string, style = new UIConversationStyle()) {
super(parent, width, height);
export class UIConversationMessage {
private container: UIContainer
this.drawBackground(style.background, style.border, style.border_width, style.alpha);
constructor(private builder: UIBuilder, private width: number, private height: number, message: string, style = new UIConversationStyle(), forward?: Function) {
this.container = builder.container("conversation-message");
let builder = this.builder.styled(style.text);
if (!style.center) {
builder = builder.styled({ center: false, vcenter: false });
}
let offset = 0;
if (style.image_size && style.image) {
offset = style.image_size + style.padding;
width -= offset;
let ioffset = style.padding + Math.floor(style.image_size / 2);
builder.image(style.image, ioffset, ioffset, true);
if (style.image_caption) {
let text_size = Math.ceil(style.text.size ? style.text.size * 0.6 : 16);
builder.text(style.image_caption, ioffset, style.padding + style.image_size + text_size, {
size: text_size,
center: true
});
builder.styled(style.text).in(this.container, builder => {
if (!style.center) {
builder = builder.styled({ center: false, vcenter: false });
}
}
let text = builder.text(message, offset + (style.center ? width / 2 : style.padding), style.center ? height / 2 : style.padding, {
width: width - style.padding * 2
builder.graphics("background").addRectangle({ x: 0, y: 0, width: width, height: height },
style.background, style.border_width, style.border, style.alpha);
let offset = 0;
if (style.image_size && style.image) {
offset = style.image_size + style.padding;
width -= offset;
let ioffset = style.padding + Math.floor(style.image_size / 2);
builder.image(style.image, ioffset, ioffset, true);
if (style.image_caption) {
let text_size = Math.ceil(style.text.size ? style.text.size * 0.6 : 16);
builder.text(style.image_caption, ioffset, style.padding + style.image_size + text_size, {
size: text_size,
center: true
});
}
}
let text = builder.text(message, offset + (style.center ? width / 2 : style.padding), style.center ? height / 2 : style.padding, {
width: width - style.padding * 2
});
/*let i = 0;
let colorchar = () => {
text.clearColors();
if (i < message.length) {
text.addColor("transparent", i);
i++;
this.view.timer.schedule(10, colorchar);
}
}
colorchar();*/
if (forward) {
builder.button("common-arrow", this.width - 30, this.height - 30, forward, "Next", undefined, { center: true });
}
});
}
/*let i = 0;
let colorchar = () => {
text.clearColors();
if (i < message.length) {
text.addColor("transparent", i);
i++;
this.view.timer.schedule(10, colorchar);
}
}
colorchar();*/
destroy() {
this.container.destroy();
}
positionRelative(relx: number, rely: number) {
let view = this.builder.view;
let rx = (view.getWidth() - this.width) * relx;
let ry = (view.getHeight() - this.height) * rely;
this.container.setPosition(Math.round(rx), Math.round(ry));
}
setVisible(visible: boolean, duration = 0): void {
this.container.setVisible(visible, duration);
}
}
/**
* Display of an active conversation (sequence of messages)
*/
export class UIConversation extends UIComponent {
export class UIConversation {
private view: BaseView
private builder: UIBuilder
private container: UIContainer
private overlay: UIOverlay
private message?: UIConversationMessage
private step = -1
private on_step: UIConversationCallback
private ended = false
private on_end = new Phaser.Events.EventEmitter()
constructor(parent: BaseView, on_step: UIConversationCallback) {
super(parent, parent.getWidth(), parent.getHeight());
constructor(builder: UIBuilder, on_step: UIConversationCallback) {
this.view = builder.view;
this.drawBackground(0x404450, undefined, undefined, 0.7, () => this.forward());
this.container = builder.container("conversation");
this.builder = builder.in(this.container);
this.overlay = this.builder.overlay({
color: 0x404450,
alpha: 0.7,
on_click: () => this.forward()
});
this.setVisible(false);
this.on_step = on_step;
@ -104,13 +138,33 @@ module TK.SpaceTac.UI {
this.forward();
}
/**
* Clear the content of previous message, if any
*/
clearContent(): void {
if (this.message) {
this.message.destroy();
this.message = undefined;
}
}
/**
* Set the global visibility
*/
setVisible(visible: boolean, duration = 0): void {
this.container.setVisible(visible, duration);
}
/**
* Destroy the conversation handler
*/
destroy() {
if (!this.ended) {
this.ended = true;
this.on_end.emit("done");
}
super.destroy();
this.container.destroy();
}
/**
@ -132,9 +186,8 @@ module TK.SpaceTac.UI {
setCurrentMessage(style: UIConversationStyle, content: string, width: number, height: number, relx: number, rely: number): void {
this.clearContent();
let message = new UIConversationMessage(this, width, height, content, style);
message.addButton(width - 60, height - 60, () => this.forward(), "common-arrow");
message.setPositionInsideParent(relx, rely);
this.message = new UIConversationMessage(this.builder, width, height, content, style, () => this.forward());
this.message.positionRelative(relx, rely);
this.setVisible(true, 700);
}
@ -151,7 +204,7 @@ module TK.SpaceTac.UI {
style.image_size = 256;
let own = this.view.gameui.session.player.is(ship.fleet.player);
this.setCurrentMessage(style, content, 900, 300, own ? 0.1 : 0.9, own ? 0.2 : 0.8);
this.setCurrentMessage(style, content, 900, 310, own ? 0.1 : 0.9, own ? 0.2 : 0.8);
}
/**
@ -167,8 +220,8 @@ module TK.SpaceTac.UI {
/**
* Convenience to create a conversation from a list of pieces
*/
static newFromPieces(view: BaseView, pieces: UIConversationPiece[]): UIConversation {
let result = new UIConversation(view, (conversation, step) => {
static newFromPieces(builder: UIBuilder, pieces: UIConversationPiece[]): UIConversation {
let result = new UIConversation(builder, (conversation, step) => {
if (step >= pieces.length) {
return false;
} else {

View File

@ -0,0 +1,21 @@
module TK.SpaceTac.UI {
export interface UIOverlayOptions {
color: number,
alpha?: number,
on_click?: Function
}
/**
* UI component to display a semi-transparent overlay that fills the whole view and captures inputs
*/
export class UIOverlay extends UIGraphics {
constructor(view: BaseView, options: UIOverlayOptions) {
super(view, "overlay");
let rect = { x: 0, y: 0, width: view.getWidth(), height: view.getHeight() };
this.addRectangle(rect, options.color, undefined, undefined, options.alpha);
this.setInteractive(rect, (rect: Phaser.Geom.Rectangle, x: number, y: number) => Phaser.Geom.Rectangle.Contains(rect, x, y) && UITools.isVisible(this));
this.on("pointerup", options.on_click || nop);
}
}
}

View File

@ -152,9 +152,10 @@ module TK.SpaceTac.UI {
return () => {
let style = new UIConversationStyle();
style.center = true;
let display = new UIConversationMessage(this.view, 900, 200, message, style);
display.setPositionInsideParent(0.5, 0.9);
display.moveToLayer(this.getLayer(layer, clear));
let parent = this.getLayer(layer, clear);
let builder = new UIBuilder(this.view, parent);
let display = new UIConversationMessage(builder, 900, 200, message, style);
display.positionRelative(0.5, 0.9);
display.setVisible(false);
display.setVisible(true, 500);
}

View File

@ -8,8 +8,8 @@ module TK.SpaceTac.UI {
dialog: MissionPartConversation | null = null
on_ended: Function | null = null
constructor(parent: BaseView) {
super(parent, () => true);
constructor(builder: UIBuilder) {
super(builder, () => true);
}
/**

View File

@ -116,8 +116,7 @@ module TK.SpaceTac.UI {
this.character_sheet = new CharacterSheet(this, CharacterSheetMode.EDITION);
this.character_sheet.moveToLayer(this.layer_overlay);
this.conversation = new MissionConversationDisplay(this);
this.conversation.moveToLayer(this.layer_overlay);
this.conversation = new MissionConversationDisplay(builder.in(this.layer_overlay));
this.audio.startMusic("spring-thaw");