[P3][UI][QoL] Fix tooltips going out of screen on mobile & other improvements (#4792)
* [ui] Fix tooltip placement when using touchscreen * [ui] make candy friendship tooltip hitbox bigger
This commit is contained in:
parent
7a0c88e661
commit
433d4b4fc9
|
@ -242,6 +242,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
private pokemonEggMoveContainers: Phaser.GameObjects.Container[];
|
private pokemonEggMoveContainers: Phaser.GameObjects.Container[];
|
||||||
private pokemonEggMoveBgs: Phaser.GameObjects.NineSlice[];
|
private pokemonEggMoveBgs: Phaser.GameObjects.NineSlice[];
|
||||||
private pokemonEggMoveLabels: Phaser.GameObjects.Text[];
|
private pokemonEggMoveLabels: Phaser.GameObjects.Text[];
|
||||||
|
private pokemonCandyContainer: Phaser.GameObjects.Container;
|
||||||
private pokemonCandyIcon: Phaser.GameObjects.Sprite;
|
private pokemonCandyIcon: Phaser.GameObjects.Sprite;
|
||||||
private pokemonCandyDarknessOverlay: Phaser.GameObjects.Sprite;
|
private pokemonCandyDarknessOverlay: Phaser.GameObjects.Sprite;
|
||||||
private pokemonCandyOverlayIcon: Phaser.GameObjects.Sprite;
|
private pokemonCandyOverlayIcon: Phaser.GameObjects.Sprite;
|
||||||
|
@ -686,31 +687,36 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonLuckText.setOrigin(0, 0);
|
this.pokemonLuckText.setOrigin(0, 0);
|
||||||
this.starterSelectContainer.add(this.pokemonLuckText);
|
this.starterSelectContainer.add(this.pokemonLuckText);
|
||||||
|
|
||||||
this.pokemonCandyIcon = this.scene.add.sprite(4.5, 18, "candy");
|
// Candy icon and count
|
||||||
|
this.pokemonCandyContainer = this.scene.add.container(4.5, 18);
|
||||||
|
|
||||||
|
this.pokemonCandyIcon = this.scene.add.sprite(0, 0, "candy");
|
||||||
this.pokemonCandyIcon.setScale(0.5);
|
this.pokemonCandyIcon.setScale(0.5);
|
||||||
this.pokemonCandyIcon.setOrigin(0, 0);
|
this.pokemonCandyIcon.setOrigin(0, 0);
|
||||||
this.starterSelectContainer.add(this.pokemonCandyIcon);
|
this.pokemonCandyContainer.add(this.pokemonCandyIcon);
|
||||||
|
|
||||||
this.pokemonFormText = addTextObject(this.scene, 6, 42, "Form", TextStyle.WINDOW_ALT, { fontSize: "42px" });
|
this.pokemonCandyOverlayIcon = this.scene.add.sprite(0, 0, "candy_overlay");
|
||||||
this.pokemonFormText.setOrigin(0, 0);
|
|
||||||
this.starterSelectContainer.add(this.pokemonFormText);
|
|
||||||
|
|
||||||
this.pokemonCandyOverlayIcon = this.scene.add.sprite(4.5, 18, "candy_overlay");
|
|
||||||
this.pokemonCandyOverlayIcon.setScale(0.5);
|
this.pokemonCandyOverlayIcon.setScale(0.5);
|
||||||
this.pokemonCandyOverlayIcon.setOrigin(0, 0);
|
this.pokemonCandyOverlayIcon.setOrigin(0, 0);
|
||||||
this.starterSelectContainer.add(this.pokemonCandyOverlayIcon);
|
this.pokemonCandyContainer.add(this.pokemonCandyOverlayIcon);
|
||||||
|
|
||||||
this.pokemonCandyDarknessOverlay = this.scene.add.sprite(4.5, 18, "candy");
|
this.pokemonCandyDarknessOverlay = this.scene.add.sprite(0, 0, "candy");
|
||||||
this.pokemonCandyDarknessOverlay.setScale(0.5);
|
this.pokemonCandyDarknessOverlay.setScale(0.5);
|
||||||
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
|
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
|
||||||
this.pokemonCandyDarknessOverlay.setTint(0x000000);
|
this.pokemonCandyDarknessOverlay.setTint(0x000000);
|
||||||
this.pokemonCandyDarknessOverlay.setAlpha(0.50);
|
this.pokemonCandyDarknessOverlay.setAlpha(0.50);
|
||||||
this.pokemonCandyDarknessOverlay.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
this.pokemonCandyContainer.add(this.pokemonCandyDarknessOverlay);
|
||||||
this.starterSelectContainer.add(this.pokemonCandyDarknessOverlay);
|
|
||||||
|
|
||||||
this.pokemonCandyCountText = addTextObject(this.scene, 14, 18, "x0", TextStyle.WINDOW_ALT, { fontSize: "56px" });
|
this.pokemonCandyCountText = addTextObject(this.scene, 9.5, 0, "x0", TextStyle.WINDOW_ALT, { fontSize: "56px" });
|
||||||
this.pokemonCandyCountText.setOrigin(0, 0);
|
this.pokemonCandyCountText.setOrigin(0, 0);
|
||||||
this.starterSelectContainer.add(this.pokemonCandyCountText);
|
this.pokemonCandyContainer.add(this.pokemonCandyCountText);
|
||||||
|
|
||||||
|
this.pokemonCandyContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, 30, 20), Phaser.Geom.Rectangle.Contains);
|
||||||
|
this.starterSelectContainer.add(this.pokemonCandyContainer);
|
||||||
|
|
||||||
|
this.pokemonFormText = addTextObject(this.scene, 6, 42, "Form", TextStyle.WINDOW_ALT, { fontSize: "42px" });
|
||||||
|
this.pokemonFormText.setOrigin(0, 0);
|
||||||
|
this.starterSelectContainer.add(this.pokemonFormText);
|
||||||
|
|
||||||
this.pokemonCaughtHatchedContainer = this.scene.add.container(2, 25);
|
this.pokemonCaughtHatchedContainer = this.scene.add.container(2, 25);
|
||||||
this.pokemonCaughtHatchedContainer.setScale(0.5);
|
this.pokemonCaughtHatchedContainer.setScale(0.5);
|
||||||
|
@ -2822,10 +2828,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonShinyIcon.setY(135);
|
this.pokemonShinyIcon.setY(135);
|
||||||
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
||||||
[
|
[
|
||||||
this.pokemonCandyIcon,
|
this.pokemonCandyContainer,
|
||||||
this.pokemonCandyOverlayIcon,
|
|
||||||
this.pokemonCandyDarknessOverlay,
|
|
||||||
this.pokemonCandyCountText,
|
|
||||||
this.pokemonHatchedIcon,
|
this.pokemonHatchedIcon,
|
||||||
this.pokemonHatchedCountText
|
this.pokemonHatchedCountText
|
||||||
].map(c => c.setVisible(false));
|
].map(c => c.setVisible(false));
|
||||||
|
@ -2834,31 +2837,26 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonCaughtHatchedContainer.setY(25);
|
this.pokemonCaughtHatchedContainer.setY(25);
|
||||||
this.pokemonShinyIcon.setY(117);
|
this.pokemonShinyIcon.setY(117);
|
||||||
this.pokemonCandyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
|
this.pokemonCandyIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[0])));
|
||||||
this.pokemonCandyIcon.setVisible(true);
|
|
||||||
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
|
this.pokemonCandyOverlayIcon.setTint(argbFromRgba(rgbHexToRgba(colorScheme[1])));
|
||||||
this.pokemonCandyOverlayIcon.setVisible(true);
|
|
||||||
this.pokemonCandyDarknessOverlay.setVisible(true);
|
|
||||||
this.pokemonCandyCountText.setText(`x${this.scene.gameData.starterData[species.speciesId].candyCount}`);
|
this.pokemonCandyCountText.setText(`x${this.scene.gameData.starterData[species.speciesId].candyCount}`);
|
||||||
this.pokemonCandyCountText.setVisible(true);
|
this.pokemonCandyContainer.setVisible(true);
|
||||||
this.pokemonFormText.setY(42);
|
this.pokemonFormText.setY(42);
|
||||||
this.pokemonHatchedIcon.setVisible(true);
|
this.pokemonHatchedIcon.setVisible(true);
|
||||||
this.pokemonHatchedCountText.setVisible(true);
|
this.pokemonHatchedCountText.setVisible(true);
|
||||||
|
|
||||||
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
||||||
const candyCropY = 16 - (16 * (currentFriendship / friendshipCap));
|
const candyCropY = 16 - (16 * (currentFriendship / friendshipCap));
|
||||||
|
this.pokemonCandyDarknessOverlay.setCrop(0, 0, 16, candyCropY);
|
||||||
|
|
||||||
if (this.pokemonCandyDarknessOverlay.visible) {
|
this.pokemonCandyContainer.on("pointerover", () => {
|
||||||
this.pokemonCandyDarknessOverlay.on("pointerover", () => {
|
|
||||||
this.scene.ui.showTooltip("", `${currentFriendship}/${friendshipCap}`, true);
|
this.scene.ui.showTooltip("", `${currentFriendship}/${friendshipCap}`, true);
|
||||||
this.activeTooltip = "CANDY";
|
this.activeTooltip = "CANDY";
|
||||||
});
|
});
|
||||||
this.pokemonCandyDarknessOverlay.on("pointerout", () => {
|
this.pokemonCandyContainer.on("pointerout", () => {
|
||||||
this.scene.ui.hideTooltip();
|
this.scene.ui.hideTooltip();
|
||||||
this.activeTooltip = undefined;
|
this.activeTooltip = undefined;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
this.pokemonCandyDarknessOverlay.setCrop(0, 0, 16, candyCropY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2934,10 +2932,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonPassiveLabelText.setVisible(false);
|
this.pokemonPassiveLabelText.setVisible(false);
|
||||||
this.pokemonNatureLabelText.setVisible(false);
|
this.pokemonNatureLabelText.setVisible(false);
|
||||||
this.pokemonCaughtHatchedContainer.setVisible(false);
|
this.pokemonCaughtHatchedContainer.setVisible(false);
|
||||||
this.pokemonCandyIcon.setVisible(false);
|
this.pokemonCandyContainer.setVisible(false);
|
||||||
this.pokemonCandyOverlayIcon.setVisible(false);
|
|
||||||
this.pokemonCandyDarknessOverlay.setVisible(false);
|
|
||||||
this.pokemonCandyCountText.setVisible(false);
|
|
||||||
this.pokemonFormText.setVisible(false);
|
this.pokemonFormText.setVisible(false);
|
||||||
|
|
||||||
const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, true, true);
|
const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, true, true);
|
||||||
|
@ -2971,10 +2966,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonPassiveLabelText.setVisible(false);
|
this.pokemonPassiveLabelText.setVisible(false);
|
||||||
this.pokemonNatureLabelText.setVisible(false);
|
this.pokemonNatureLabelText.setVisible(false);
|
||||||
this.pokemonCaughtHatchedContainer.setVisible(false);
|
this.pokemonCaughtHatchedContainer.setVisible(false);
|
||||||
this.pokemonCandyIcon.setVisible(false);
|
this.pokemonCandyContainer.setVisible(false);
|
||||||
this.pokemonCandyOverlayIcon.setVisible(false);
|
|
||||||
this.pokemonCandyDarknessOverlay.setVisible(false);
|
|
||||||
this.pokemonCandyCountText.setVisible(false);
|
|
||||||
this.pokemonFormText.setVisible(false);
|
this.pokemonFormText.setVisible(false);
|
||||||
|
|
||||||
this.setSpeciesDetails(species!, { // TODO: is this bang correct?
|
this.setSpeciesDetails(species!, { // TODO: is this bang correct?
|
||||||
|
@ -3005,7 +2997,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
|| !isNullOrUndefined(formIndex) || !isNullOrUndefined(shiny) || !isNullOrUndefined(variant);
|
|| !isNullOrUndefined(formIndex) || !isNullOrUndefined(shiny) || !isNullOrUndefined(variant);
|
||||||
|
|
||||||
if (this.activeTooltip === "CANDY") {
|
if (this.activeTooltip === "CANDY") {
|
||||||
if (this.lastSpecies) {
|
if (this.lastSpecies && this.pokemonCandyContainer.visible) {
|
||||||
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
||||||
this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3230,6 +3222,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
this.pokemonPassiveLockedIcon.setVisible(!isUnlocked);
|
this.pokemonPassiveLockedIcon.setVisible(!isUnlocked);
|
||||||
this.pokemonPassiveLockedIcon.setPosition(iconPosition.x, iconPosition.y);
|
this.pokemonPassiveLockedIcon.setPosition(iconPosition.x, iconPosition.y);
|
||||||
|
|
||||||
|
} else if (this.activeTooltip === "PASSIVE") {
|
||||||
|
// No passive and passive tooltip is active > hide it
|
||||||
|
this.scene.ui.hideTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pokemonNatureText.setText(getNatureName(natureIndex as unknown as Nature, true, true, false, this.scene.uiTheme));
|
this.pokemonNatureText.setText(getNatureName(natureIndex as unknown as Nature, true, true, false, this.scene.uiTheme));
|
||||||
|
|
|
@ -184,7 +184,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||||
this.candyShadow.setTint(0x000000);
|
this.candyShadow.setTint(0x000000);
|
||||||
this.candyShadow.setAlpha(0.50);
|
this.candyShadow.setAlpha(0.50);
|
||||||
this.candyShadow.setScale(0.8);
|
this.candyShadow.setScale(0.8);
|
||||||
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 30, 16), Phaser.Geom.Rectangle.Contains);
|
||||||
this.summaryContainer.add(this.candyShadow);
|
this.summaryContainer.add(this.candyShadow);
|
||||||
|
|
||||||
this.candyCountText = addTextObject(this.scene, 20, -146, "x0", TextStyle.WINDOW_ALT, { fontSize: "76px" });
|
this.candyCountText = addTextObject(this.scene, 20, -146, "x0", TextStyle.WINDOW_ALT, { fontSize: "76px" });
|
||||||
|
@ -203,7 +203,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||||
this.friendshipShadow.setTint(0x000000);
|
this.friendshipShadow.setTint(0x000000);
|
||||||
this.friendshipShadow.setAlpha(0.50);
|
this.friendshipShadow.setAlpha(0.50);
|
||||||
this.friendshipShadow.setScale(0.8);
|
this.friendshipShadow.setScale(0.8);
|
||||||
this.friendshipShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
this.friendshipShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 50, 16), Phaser.Geom.Rectangle.Contains);
|
||||||
this.summaryContainer.add(this.friendshipShadow);
|
this.summaryContainer.add(this.friendshipShadow);
|
||||||
|
|
||||||
this.friendshipText = addTextObject(this.scene, 20, -66, "x0", TextStyle.WINDOW_ALT, { fontSize: "76px" });
|
this.friendshipText = addTextObject(this.scene, 20, -66, "x0", TextStyle.WINDOW_ALT, { fontSize: "76px" });
|
||||||
|
|
35
src/ui/ui.ts
35
src/ui/ui.ts
|
@ -391,6 +391,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||||
this.tooltipContent.y = title ? 16 : 4;
|
this.tooltipContent.y = title ? 16 : 4;
|
||||||
this.tooltipBg.width = Math.min(Math.max(this.tooltipTitle.displayWidth, this.tooltipContent.displayWidth) + 12, 838);
|
this.tooltipBg.width = Math.min(Math.max(this.tooltipTitle.displayWidth, this.tooltipContent.displayWidth) + 12, 838);
|
||||||
this.tooltipBg.height = (title ? 31 : 19) + 10.5 * (wrappedContent.split("\n").length - 1);
|
this.tooltipBg.height = (title ? 31 : 19) + 10.5 * (wrappedContent.split("\n").length - 1);
|
||||||
|
this.tooltipTitle.x = this.tooltipBg.width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideTooltip(): void {
|
hideTooltip(): void {
|
||||||
|
@ -400,12 +401,34 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||||
|
|
||||||
update(): void {
|
update(): void {
|
||||||
if (this.tooltipContainer.visible) {
|
if (this.tooltipContainer.visible) {
|
||||||
const xReverse = this.scene.game.input.mousePointer && this.scene.game.input.mousePointer.x >= this.scene.game.canvas.width - this.tooltipBg.width * 6 - 12;
|
const isTouch = (this.scene as BattleScene).inputMethod === "touch";
|
||||||
const yReverse = this.scene.game.input.mousePointer && this.scene.game.input.mousePointer.y >= this.scene.game.canvas.height - this.tooltipBg.height * 6 - 12;
|
const pointerX = this.scene.game.input.activePointer.x;
|
||||||
this.tooltipContainer.setPosition(
|
const pointerY = this.scene.game.input.activePointer.y;
|
||||||
!xReverse ? this.scene.game.input.mousePointer!.x / 6 + 2 : this.scene.game.input.mousePointer!.x / 6 - this.tooltipBg.width - 2,
|
const tooltipWidth = this.tooltipBg.width;
|
||||||
!yReverse ? this.scene.game.input.mousePointer!.y / 6 + 2 : this.scene.game.input.mousePointer!.y / 6 - this.tooltipBg.height - 2,
|
const tooltipHeight = this.tooltipBg.height;
|
||||||
);
|
const padding = 2;
|
||||||
|
|
||||||
|
// Default placement is top left corner of the screen on mobile. Otherwise below the cursor, to the right
|
||||||
|
let x = isTouch ? padding : pointerX / 6 + padding;
|
||||||
|
let y = isTouch ? padding : pointerY / 6 + padding;
|
||||||
|
|
||||||
|
if (isTouch) {
|
||||||
|
// If we are in the top left quadrant on mobile, move the tooltip to the top right corner
|
||||||
|
if (pointerX <= this.scene.game.canvas.width / 2 && pointerY <= this.scene.game.canvas.height / 2) {
|
||||||
|
x = this.scene.game.canvas.width / 6 - tooltipWidth - padding;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the tooltip would go offscreen on the right, or is close to it, move to the left of the cursor
|
||||||
|
if (x + tooltipWidth + padding > this.scene.game.canvas.width / 6) {
|
||||||
|
x = Math.max(padding, pointerX / 6 - tooltipWidth - padding);
|
||||||
|
}
|
||||||
|
// If the tooltip would go offscreen at the bottom, or is close to it, move above the cursor
|
||||||
|
if (y + tooltipHeight + padding > this.scene.game.canvas.height / 6) {
|
||||||
|
y = Math.max(padding, pointerY / 6 - tooltipHeight - padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tooltipContainer.setPosition(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue