areaclick event blocked for bbCodeText in a TextBox with interactive set to true
xanmankey opened this issue · comments
Hi,
I just wanted to point out something that I noticed, it could be an entirely intentional choice or just a bug in my code. I'm making a dialog system for a game, utilizing the areaclick
event of BBCodeText
for dialog options and TextBox
for displaying the text, but when I set textBox to interactive, the areaclick event never calls.
Here's my code
import TextBox from "phaser3-rex-plugins/templates/ui/textbox/TextBox";
import { CustomScene, DialogPath } from "../objects/scene";
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
const COLOR_PRIMARY = 0x4e342e;
const COLOR_DARK = 0x260e04;
const COLOR_LIGHT = 0xc4a484;
const GetValue = Phaser.Utils.Objects.GetValue;
interface TextBoxConfig {
wrapWidth?: number | undefined;
fixedWidth?: number | undefined;
fixedHeight?: number | undefined;
titleText?: string | undefined;
}
// TODO: play around w/ why the yes-no buttons render so off
export const createTextBox = (
scene: CustomScene,
x: number,
y: number,
text: string,
config: TextBoxConfig,
dialogPaths: DialogPath[] | undefined
) => {
const wrapWidth = GetValue(config, "wrapWidth", 0);
const fixedWidth = GetValue(config, "fixedWidth", 0);
const fixedHeight = GetValue(config, "fixedHeight", 0);
const titleText = GetValue(config, "titleText", undefined);
var textBox = scene.rexUI.add
.textBox({
x: x,
y: y,
background: scene.rexUI.add.roundRectangle(
x,
y,
fixedWidth,
fixedHeight,
20,
COLOR_PRIMARY,
COLOR_DARK
),
icon: scene.rexUI.add.roundRectangle(
x,
y,
fixedHeight,
fixedWidth,
20,
COLOR_LIGHT
),
text: getBBCodeText(
scene,
wrapWidth,
fixedWidth,
fixedHeight,
text,
dialogPaths
),
action: scene.add
.image(0, 0, "nextPage")
.setTint(COLOR_DARK)
.setVisible(false),
title: titleText
? scene.add.text(0, 0, titleText, { fontSize: "24px" })
: undefined,
separator: titleText
? scene.rexUI.add.roundRectangle(
x,
y,
fixedHeight,
fixedWidth,
20,
COLOR_LIGHT
)
: undefined,
space: {
left: 20,
right: 20,
top: 20,
bottom: 20,
icon: 10,
text: 10,
separator: 6,
},
align: {
title: "center",
},
})
.setOrigin(0)
// .setInteractive() - This line prevents the areaclick handler from working
.setDepth(7);
textBox.on(
"pageend",
function () {
console.log("page end");
if (dialogPaths == undefined) {
if (this!.isLastPage) {
console.log("Last page, returning!");
scene.isTextBoxCompleted = true;
return;
}
}
var icon = this.getElement("action").setVisible(true);
this.resetChildVisibleState(icon);
icon.y -= 30;
scene.tweens.add({
targets: icon,
y: "+=30", // '+=100'
ease: "Bounce", // 'Cubic', 'Elastic', 'Bounce', 'Back'
duration: 500,
repeat: 0, // -1: infinity
yoyo: false,
});
},
textBox
);
textBox.layout();
return textBox;
};
// TODO: make the bbcodetext selectable if selectable is specified
// I also want my font size to be scalable...
export const getBBCodeText = (
scene: CustomScene,
wrapWidth: number | undefined,
fixedWidth: number | undefined,
fixedHeight: number | undefined,
text: string,
dialogPaths: DialogPath[] | undefined
) => {
// Adapt to fit each line on a page
return scene.rexUI.add
.BBCodeText(0, 0, text, {
// fixedWidth: wrapWidth,
fixedHeight: fixedHeight,
fontSize: "20px",
wrap: {
mode: "word",
width: wrapWidth,
},
maxLines: 3,
interactive: true,
delimiters: "[]",
})
.on("areaclick", function (key: string) {
console.log("Dialog path callback function works");
});
};
And here's where I call my code
if (tile instanceof Phaser.Tilemaps.Tile) {
if (Input.Keyboard.JustDown(spacebar)) {
// Learned about Ctrl + Shift + \: go to bracket, a game changer
if (!this.isTextBoxCompleted) {
switch (tile.index) {
case 0:
// Book
// NOTE that because position is inconsistent, tilemap layers are used to identify tiles
switch (tile.tilemapLayer) {
case objLayer:
this.interact(
"'42: the answer to life, the universe, and everything' - The Hitchhiker's Guide to the Galaxy"
);
break;
case objLayer2:
this.interact(
"'A book has been taken. A book has been taken? You summoned the Watch, Carrot drew himself up proudly, because someone's taken a book? You think that's worse than murder?' - Guards Guards"
);
break;
case objLayer3:
this.interact(
"'The world was to me a secret which I desired to divine.' - Frankenstein"
);
break;
case objLayer4:
this.interact(
"'Success is not delivering a feature; success is learning how to solve the customer’s problem.' - The Lean Startup"
);
break;
case objLayer5:
this.interact(
'But until a person can say deeply and honestly, "I am what I am today because of the choices I made yesterday," that person cannot say, "I choose otherwise."\' - The Seven Habits of Highly Effective People'
);
break;
case objLayer6:
this.interact(
"'Is there intelligence without life? Is there mind without communication? Is there language without living? Is there thought without experience?' - Alan Turing: The Enigma"
);
break;
default:
break;
}
case 1:
// Electrowav
this.interact(
"It appears to be a shameless plug for [url=https://www.youtube.com/@electrowav]youtube.com/@electrowav[/url]"
);
break;
case 2:
// Piano upper left
break;
case 3:
// Piano upper right
break;
case 4:
// Shoe
break;
case 5:
// Soccer Ball
break;
case 6:
// Basketball
break;
case 7:
// Blank
break;
case 8:
break;
case 9:
// PlantL
this.interact(
"Don't mind me, I'm just hanging out with my buddy, yellow"
);
break;
case 10:
// PlantR
this.interact(
"Don't mind me, I'm just hanging out with my buddy, green"
);
break;
case 11:
// Piano Bottom Left
break;
case 12:
// Piano Bottom Right
break;
case 13:
// Shoe With Logo
break;
case 14:
// Trumpet standing up
this.interact(
"Now's your chance, don't blow it!\n\nYou're now an accomplished trumpet player",
{ audioKey: "trumpet", pageNumber: 2, loop: false }
);
break;
case 15:
// TableL
break;
case 16:
// TableR
break;
case 17:
// Bookshelf top left
switch (tile.tilemapLayer) {
case objLayer:
this.interact("One book, two book, red book, blue book");
break;
case objLayer2:
this.interact(
"On-time book, overdue book, old book, new book"
);
break;
case objLayer3:
this.interact(
"This one has 5 stars. This one has memoirs."
);
break;
case objLayer4:
this.interact("Say! What a lot of books there are");
break;
default:
break;
}
break;
case 18:
// Bookshelf top right
switch (tile.tilemapLayer) {
case objLayer:
this.interact("One book, two book, red book, blue book");
break;
case objLayer2:
this.interact(
"On-time book, overdue book, old book, new book"
);
break;
case objLayer3:
this.interact(
"This one has 5 stars. This one has memoirs."
);
break;
case objLayer4:
this.interact("Say! What a lot of books there are");
break;
default:
break;
}
break;
case 19:
// Shoes
this.interact(
"All of a sudden you feel as though you're looking at a pair of shoes."
);
break;
case 20:
// Xbox
this.interact(
"Xbox: It's a controller... kind of. \nThe buttons are all swapped... \n\nWhat kind of person thought that this would be a good idea?"
);
break;
case 21:
// Switch
// TODO: selectable dialog options (use the below syntax at: https://rexrainbow.github.io/phaser3-rex-notes/docs/site/bbcodetext/?h=bbco)
// [area=key]text[/area]
this.interact(
"It's a game console; turn it on?\n\n[area=yes]yes[/area] [area=no]no[/area]\n",
undefined,
[
{
key: "yes",
interactOptions: {
text: "It's your favorite, The Legend of Zeldo: Smell of the Forest!",
audio: {
audioKey: "botw",
pageNumber: 2,
loop: true,
},
dialogPaths: undefined,
},
},
{
key: "no",
interactOptions: undefined,
},
]
);
break;
case 22:
// Code for 22
break;
case 23:
// Code for 23
break;
case 24:
// Code for 24
break;
case 25:
// Code for 25
break;
case 26:
// Code for 26
break;
case 27:
// Code for 27
break;
case 28:
// Code for 28
break;
// case 29:
// // Code for 29
// break;
// case 30:
// // Code for 30
// break;
// case 31:
// // Code for 31
// break;
// case 32:
// // Code for 32
// break;
// case 33:
// // Code for 33
// break;
// case 34:
// // Code for 34
// break;
// case 35:
// // Code for 35
// break;
// case 36:
// // Code for 36
// break;
// case 37:
// // Code for 37
// break;
// case 38:
// // Code for 38
// break;
// // case 39:
// // // Code for 39
// // break;
// case 40:
// // Code for 40
// break;
// case 41:
// // Code for 41
// break;
// case 42:
// // Code for 42
// break;
// case 43:
// // Code for 43
// break;
// case 44:
// // Code for 44
// break;
// case 45:
// // Code for 45
// break;
// case 46:
// // Code for 46
// break;
// // case 47:
// // // Code for 47
// // break;
// case 48:
// // Code for 48
// break;
// case 49:
// // Code for 49
// break;
// case 50:
// // Code for 50
// break;
// case 51:
// // Code for 51
// break;
// case 52:
// // Code for 52
// break;
// case 53:
// // Code for 53
// break;
// case 54:
// // Code for 54
// break;
// case 55:
// // Code for 55
// break;
default:
// Note that if the textbox has interactive enabled, you can't interact
// with the bbCodeText (it overwrites it)
createTextBox(
this,
0,
200,
"[area=yes]yes[/area] [area=no]no[/area]\n",
// "Test text",
{
wrapWidth: 275,
},
[
{
key: "yes",
interactOptions: {
text: "It's your favorite, The Legend of Zeldo: Smell of the Forest!",
audio: {
audioKey: "botw",
pageNumber: 2,
loop: true,
},
dialogPaths: undefined,
},
},
{
key: "no",
interactOptions: undefined,
},
]
);
break;
}
} else {
// Reset flow of game state
console.log("Destroying interact box");
this.interactBox!.destroy();
this.interactBox = undefined;
this.isTextBoxCompleted = false;
this.player.isInteracting = false;
}
}
}
}
);
Thanks for the incredible package and UI!
Since TextBox and BBCodeText are overlapping, only one game object will receive touch event.
In your case, TextBox is created after BBCodeText (new game object will render above old game object if they have the same depth), so it will get touch event but BBCodeText won't.
Completely missed that, thank you! Good to know that's the case for the future