phaser
phaser copied to clipboard
Interactive Object can not be clickable while preload progress complete
Hey guys.
recently I tried to put some button that I use on other scene on second preloading. my project have 2 scene of preloading, first preload before title and second one assets loading before start game scene and then going to start game after loading . I tried put some buttons like mute sound, Fullscreen (except iPhone) and home button to cancel preload but none of them work during preload after complete preload these buttons can be interactive and clickable I try found any solution but I can not solve this problem yet. if any one have idea, I'm so glad to tail their advises.
here link of game that I work on it : http://94.182.204.121/public/games/reezball/index.html
and this capture video. I tried many times to push buttons on top of preload scene, but not work until preload progress complete :'(
Here's code example that use on this senario:
ToggleButton Class (use for sound and music button for mute or not and fullscreen )
class ToggleButton extends Phaser.GameObjects.Container {
constructor(config) {
super(config.scene);
this.scene = config.scene;
if (config.backKey === "") {
config.backKey = "empty";
}
this.name = config.name;
this.back = this.scene.add.image(0, 0, config.backKey);
this.onIcon = this.scene.add.image(0, 0, config.onIcon);
this.offIcon = this.scene.add.image(0, 0, config.offIcon);
Align.scaleToGameWidth(this.back, .1, this.scene.game);
Align.scaleToGameWidth(this.onIcon, .05, this.scene.game);
Align.scaleToGameWidth(this.offIcon, .05, this.scene.game);
this.add(this.back);
this.add(this.onIcon);
this.add(this.offIcon);
this.value = config.value;
if (config.event) {
this.event = config.event;
}
this.setIcons();
this.back.setInteractive();
this.back.on('pointerdown', this.toggle, this);
if (config.x) {
this.x = config.x;
}
if (config.y) {
this.y = config.y;
}
this.setSize(this.back.displayWidth, this.back.displayHeight);
this.scene.add.existing(this);
}
setNoScroll() {
this.back.setScrollFactor(0);
this.onIcon.setScrollFactor(0);
this.offIcon.setScrollFactor(0);
}
toggle() {
this.value = !this.value;
this.setIcons();
if (this.event) {
this.scene.game.emitter.emit(this.event, this.value);
}
}
setIcons() {
let value;
if (this.name === "fullscreenOn") {
value = this.scene.scale.isFullscreen;
this._setIcons(value);
setTimeout(function () {
if(typeof this.scene !== 'undefined'){
value = this.scene.scale.isFullscreen;
this._setIcons(value);
}
}.bind(this),400);
} else {
value = this.value;
this._setIcons(value);
}
}
_setIcons(value){
if (value === true) {
this.onIcon.visible = true;
this.offIcon.visible = false;
} else {
this.onIcon.visible = false;
this.offIcon.visible = true;
}
}
toggleCondition(){
return !!(this.onIcon.visible && !this.offIcon.visible);
}
destroy(fromScene) {
super.destroy(fromScene);
}
}
class SoundButtons extends Phaser.GameObjects.Container {
constructor(config) {
super(config.scene);
this.scene = config.scene;
this.musicButton = new ToggleButton({
scene: this.scene,
backKey: '',
onIcon: 'musicOn',
offIcon: 'musicOff',
event: EVENTS.TOGGLE_MUSIC,
value: this.scene.game.model.musicOn,
name: "musicOn",
});
this.sfxButton = new ToggleButton({
scene: this.scene,
backKey: '',
onIcon: 'sfxOn',
offIcon: 'sfxOff',
event: EVENTS.TOGGLE_SOUND,
value: this.scene.game.model.soundOn,
name: "soundOn"
});
this.add(this.musicButton);
this.add(this.sfxButton);
this.musicButton.x = this.musicButton.width / 2;
this.musicButton.y = this.musicButton.x;
//this.musicButton.setScrollFactor(0);
this.musicButton.setNoScroll();
//this.sfxButton.x = this.scene.game.config.width - this.sfxButton.width / 2;
this.sfxButton.x = this.musicButton.x + this.musicButton.width * 2 / 3;
this.sfxButton.y = this.musicButton.y;
//this.sfxButton.setScrollFactor(0);
this.sfxButton.setNoScroll();
this.scene.add.existing(this);
}
destroy(fromScene) {
super.destroy(fromScene);
}
}
class FullscreenButton extends Phaser.GameObjects.Container {
constructor(config) {
super(config.scene);
this.scene = config.scene;
if (
CONFIG.GAME_INFO.SWIPE_UP.CONDITION_TO_APPEAR ||
window.location.href.indexOf(CONFIG.GAME_INFO.ADDED_TO_HOME_SCREEN) !== -1
) {
return;
}
this.button = new ToggleButton({
scene: this.scene,
backKey: '',
onIcon: 'exit-fullscreen-button',
offIcon: 'enter-fullscreen-button',
event: EVENTS.TOGGLE_FULLSCREEN,
value: this.scene.game.model.fullscreenOn,
name: "fullscreenOn",
});
this.add(this.button);
switch (this.scene.scene.key) {
case "Game":
case "PreloadGameAssets":
this.button.x = this.scene.game.config.width - this.button.width * 2 / 3 - this.button.width / 2;
break;
default:
this.button.x = this.scene.game.config.width - this.button.width / 2;
break;
}
this.button.y = this.button.width / 2;
this.button.setNoScroll();
this.timer();
this.scene.add.existing(this);
}
setIcon() {
if (this.active) {
if (this.button.toggleCondition() !== this.scene.scale.isFullscreen) {
this.button.setIcons();
}
} else {
this.timerOBJ.destroy();
}
}
timer() {
this.timerOBJ = this.scene.time.addEvent({
delay: 1000,
callback: this.setIcon.bind(this),
repeat: -1
});
}
destroy(fromScene) {
super.destroy(fromScene);
}
}
BounceButton use for quite to home and cancel preloading
class BounceButton extends Phaser.GameObjects.Container {
constructor(config) {
if (!config.scene) {
console.log("missing scene!");
return;
}
super(config.scene);
this.init(config);
this.spawnButton();
}
init(config) {
this.config = config;
}
spawnButton() {
if (typeof this.config.text !== "undefined") {
switch (this.config.text.type) {
case "image":
this.text = this.scene.add.image(
this.config.x,
this.config.y,
this.config.text.value
);
break;
}
if (typeof this.config.text.margin !== "undefined") {
if (typeof this.config.text.margin.x !== "undefined") {
this.text.x += this.config.text.margin.x;
}
if (typeof this.config.text.margin.y !== "undefined") {
this.text.y += this.config.text.margin.y;
}
}
}
if (typeof this.config.background.atlas === "undefined") {
this.background = this.scene.add.image(
this.config.x,
this.config.y,
this.config.background.value
);
} else {
this.background = this.scene.add.image(
this.config.x,
this.config.y,
this.config.background.atlas,
this.config.background.value
);
}
if (typeof this.config.scaleToGameWidth !== "undefined") {
Align.scaleToGameWidth(
this.background,
this.config.scaleToGameWidth,
this.scene.game
);
if (typeof this.text !== "undefined") {
this.text.scale = this.background.scale;
}
}
if (typeof this.config.scaleToGameHeight !== "undefined") {
Align.scaleToGameHeight(this.background, this.config.scaleToGameHeight, this.scene.game);
if (typeof this.text !== "undefined") {
this.text.scale = this.background.scale;
}
}
if(typeof this.config.scale !== "undefined"){
this.background.scale = this.config.scale;
if (typeof this.text !== "undefined") {
this.text.scale = this.background.scale;
}
}
this.alternativeBackground = this.scene.add.image(
this.background.x,
this.background.y,
"empty"
);
this.alternativeBackground.displayHeight = this.background.displayHeight;
this.alternativeBackground.displayWidth = this.background.displayWidth;
this.interactiver = this.alternativeBackground.setInteractive();
this.alternativeBackground.on("pointerdown", this.onPush, this);
this.alternativeBackground.on("pointerup", this.onPull, this);
this.alternativeBackground.on("pointerout", this.onOut, this);
this.scene.children.bringToTop(this.background);
if (typeof this.text !== "undefined") {
this.scene.children.bringToTop(this.text);
}
this.scene.children.bringToTop(this.alternativeBackground);
this.firstScale = this.background.scale;
}
onPush() {
this.pushTween("push");
}
onPull() {
if(this.scene.scene.isPaused()){
return;
}
if (typeof this.config.onPush === "function") {
this.config.onPush();
}
if (
typeof this.config.sound !== "undefined" &&
typeof this.config.sound.push !== "undefined"
) {
this.config.scene.game.emitter.emit(EVENTS.PLAY_SOUND, this.config.sound.push);
}
this.pushTween("pull");
}
onOut() {
this.pushTween("pull");
}
pushTween(status) {
const pressure = (status === "push" ? 0.9 : 1);
if (typeof this.text !== "undefined") {
this.config.scene.tweens.add({
targets: this.text,
scale: this.firstScale * pressure,
ease: 'Linear',
duration: 100,
});
}
this.config.scene.tweens.add({
targets: this.background,
scale: this.firstScale * pressure,
ease: 'Linear',
duration: 100,
});
}
destroy(fromScene) {
this.background.destroy();
this.alternativeBackground.destroy();
if(typeof this.text !== "undefined"){
this.text.destroy();
}
super.destroy(fromScene);
}
}
ScenePreloadGameAssets preload all assets need to load to start game
class ScenePreloadGameAssets extends Phaser.Scene {
constructor() {
super("PreloadGameAssets");
}
init(data) {
this.gameMode = data.gameMode;
this.initAssetsToShow();
this.config = {
shirts: {},
};
}
initAssetsToShow() {
this.background = this.add.image(
this.game.centerX,
this.game.centerY,
"title-background"
);
Align.scaleToGameHeight(this.background, 1, this.game);
this.progressBarBackground = this.add.image(
this.game.centerX,
this.game.config.height * 2.2 / 3 - 55,
"progress-bar-background"
);
this.progressBarFill = this.add.image(
this.progressBarBackground.x,
this.progressBarBackground.y,
"progress-bar-fill"
);
this.progressBarFill.scaleX = 0;
this.game.emitter.emit(EVENTS.PLAY_SOUND, "preload-start");
this.spawnButtons();
}
spawnButtons() {
this.soundButton = new SoundButtons({scene: this});
this.fullscreenButton = new FullscreenButton({scene: this, soundButton: this.soundButton});
let y = this.soundButton.musicButton.y,
x = this.game.config.width - this.soundButton.musicButton.x;
this.homeButton = new BounceButton({
scene: this,
x: x,
y: y,
sound: {
push: "push-button",
},
scale: this.soundButton.musicButton.onIcon.scale,
background: {
value: "home-button",
},
onPush: this.returnToHome.bind(this),
});
}
returnToHome() {
new ConfirmComponent({
scene: this,
message: i18n.are_you_sure_to_return_to_title,
onConfirm: function () {
//this.destroy();
this.scene.start("Title");
}.bind(this),
});
}
destroyTexture() {
const ObjectsToDelete = [
"running-body-left",
"idle-body-left",
"jumping-body-left",
"kick-body-left",
"running-feet-left",
"idle-feet-left",
"jumping-feet-left",
"kick-feet-left",
"running-body-right",
"idle-body-right",
"jumping-body-right",
"kick-body-right",
"running-feet-right",
"idle-feet-right",
"jumping-feet-right",
"kick-feet-right",
"controller-background",
"field",
"stadium",
"sky",
"right-team-flag",
"left-team-flag",
"ball",
"head-left",
"head-right",
/*"controller",
"score_board",
"goal-gate-front",
"goal-gate-back",
"collider",
"kick-off-text",
"goal-text",
"out-text",
"offsides-text",
"foul-text",
"shadow",*/
];
for (let i = 0; i < ObjectsToDelete.length; i++) {
this.textures.remove(ObjectsToDelete[i]);
}
}
preload() {
this.load.on('progress', this.onProgress, this);
this.load.on('complete', this.onComplete, this);
this.skies = {
day: [
"day-sky-type-01.jpg",
"day-sky-type-02.jpg",
"day-sky-type-03.jpg",
"day-sky-type-04.jpg",
"day-sky-type-05.jpg",
"day-sky-type-06.jpg",
"day-sky-type-07.jpg",
],
night: [
"night-sky-type-01.jpg",
"night-sky-type-02.jpg",
"night-sky-type-03.jpg",
"night-sky-type-04.jpg",
],
};
let leftHead = Math.floor(Math.random() * 20) * 10;
let rightHead = Math.floor(Math.random() * 20) * 10;
let ball = Math.floor(1 + Math.random() * 20);
let field = Math.floor(1 + Math.random() * 8);
let controllerBackground = Math.floor(1 + Math.random() * 5);
leftHead = (
(leftHead < 10) ?
"00" :
(leftHead < 100) ?
"0" :
""
) + leftHead;
rightHead = (
(rightHead < 10) ?
"00" :
(rightHead < 100) ?
"0" :
""
) + rightHead;
this.config.heads = {
left: leftHead,
right: rightHead,
}
ball = (
(ball < 10) ?
"0" : ""
) + ball;
this.config.ball = ball;
ball = "ball-type-" + ball + ".png";
field = (
(field < 10) ?
"0" : ""
) + field;
this.config.field = field;
controllerBackground = (
(controllerBackground < 10) ?
"0" : ""
) + controllerBackground;
this.config.controllerBackground = controllerBackground;
//field = "08";
field = "field-type-" + field + ".png";
// controllerBackground = "05";
controllerBackground = "controller-background-type-" + controllerBackground + ".png";
const leftShirt = "type-00" + Math.floor(Math.random() * 6);
const rightShirt = "type-00" + Math.floor(Math.random() * 6);
this.config.shirts.left = leftShirt;
this.config.shirts.right = rightShirt;
const days = Object.keys(this.skies);
const dayMode = days[Math.floor(days.length * Math.random())];
this.config.dayMode = dayMode;
const tempSky = Math.floor(this.skies[dayMode].length * Math.random());
const sky = this.skies
[dayMode]
[tempSky];
this.config.sky = dayMode + "-" + tempSky;
const Images = {
["controller-background-" + this.config.controllerBackground]:
"controller-background/" + controllerBackground,
["field-" + this.config.field]: "fields/" + field,
"stadium": "stadium/stadium-1.png",
"goal-gate-front": "goal-gate/front.png",
"goal-gate-back": "goal-gate/back.png",
["sky-" + this.config.sky]: "sky/" + sky,
"right-team-flag": "flags/right-team-flag.png",
"left-team-flag": "flags/left-team-flag.png",
["ball-" + this.config.ball]: "balls/" + ball,
"collider": "fx/collider.jpg",
["head-" + this.config.heads.left]: "heads/head-type-" + leftHead + ".png",
["head-" + this.config.heads.right]: "heads/head-type-" + rightHead + ".png",
"kick-off-text": "text/kick-off.png",
"goal-text": "text/goal.png",
"out-text": "text/out.png",
"offsides-text": "text/offsides.png",
"foul-text": "text/foul.png",
"shadow": "fx/shadow.png",
};
const SpriteSheet = [];
let Advertise = {};
const ListOfAdvertise = {
"adds-001": {
"png": "add/adds-001.png",
"json": "add/adds-001.json",
},
"adds-002": {
"png": "add/adds-002.png",
"json": "add/adds-002.json",
},
"adds-003": {
"png": "add/adds-003.png",
"json": "add/adds-003.json",
},
"adds-004": {
"png": "add/adds-004.png",
"json": "add/adds-004.json",
},
"adds-005": {
"png": "add/adds-005.png",
"json": "add/adds-005.json",
},
"adds-006": {
"png": "add/adds-006.png",
"json": "add/adds-006.json",
},
"adds-007": {
"png": "add/adds-007.png",
"json": "add/adds-007.json",
},
"adds-008": {
"png": "add/adds-008.png",
"json": "add/adds-008.json",
},
"adds-009": {
"png": "add/adds-009.png",
"json": "add/adds-009.json",
},
"adds-010": {
"png": "add/adds-010.png",
"json": "add/adds-010.json",
},
"adds-011": {
"png": "add/adds-011.png",
"json": "add/adds-011.json",
},
"adds-012": {
"png": "add/adds-012.png",
"json": "add/adds-012.json",
},
"adds-013": {
"png": "add/adds-013.png",
"json": "add/adds-013.json",
},
"adds-014": {
"png": "add/adds-014.png",
"json": "add/adds-014.json",
},
"adds-015": {
"png": "add/adds-015.png",
"json": "add/adds-015.json",
},
"adds-016": {
"png": "add/adds-016.png",
"json": "add/adds-016.json",
},
"adds-017": {
"png": "add/adds-017.png",
"json": "add/adds-017.json",
},
"adds-018": {
"png": "add/adds-018.png",
"json": "add/adds-018.json",
},
"adds-019": {
"png": "add/adds-019.png",
"json": "add/adds-019.json",
},
"adds-020": {
"png": "add/adds-020.png",
"json": "add/adds-020.json",
},
};
const ListOfAdvertiseKeys = Object.keys(ListOfAdvertise);
const selectedRandomAdvertise = ListOfAdvertiseKeys[Math.floor(Math.random() * ListOfAdvertiseKeys.length)];
//const selectedRandomAdvertise = 'adds-001';
Advertise = {
[selectedRandomAdvertise]:ListOfAdvertise[selectedRandomAdvertise]
}
this.selectedRandomAdvertise = selectedRandomAdvertise;
const JS = {
/*COMPONENTS: [
"gameBackground.component",
"gameController.component",
"goalGate.component",
"scoreBoard.component",
"character.component",
"ball.component",
"bannerGameText.component",
],
SERVICES: [
"keyboard.service",
"cpu.service",
],
UI:[
"pause.component",
],*/
};
let Atlas = {
"controller": {
"png": "atlas/controller.png",
"json": "atlas/controller.json",
},
"score_board": {
"png": "atlas/score_board_v2.png",
"json": "atlas/score_board_v2.json",
},
"score-board-score-number": {
"png": "numbers/numbers-digital-screen-dark.png",
"json": "numbers/numbers-digital-screen-dark.json",
},
"score-board-timer-number": {
"png": "numbers/numbers-orange.png",
"json": "numbers/numbers-orange.json",
}
/*"score_board": {
"png": "score_board.png",
"json": "score_board.json",
},*/
};
for (let i = 0; i < 2; i++) {
const tempShirt = (i === 0 ? leftShirt : rightShirt);
const tempBody = {
["running-body-" + tempShirt]: {
"png": "character/" + tempShirt + "/running-body.png",
"json": "character/" + tempShirt + "/running-body.json",
},
["idle-body-" + tempShirt]: {
"png": "character/" + tempShirt + "/idle-body.png",
"json": "character/" + tempShirt + "/idle-body.json",
},
["jumping-body-" + tempShirt]: {
"png": "character/" + tempShirt + "/jumping-body.png",
"json": "character/" + tempShirt + "/jumping-body.json",
},
["kick-body-" + tempShirt]: {
"png": "character/" + tempShirt + "/kick-body.png",
"json": "character/" + tempShirt + "/kick-body.json",
},
["running-feet-" + tempShirt]: {
"png": "character/" + tempShirt + "/running-feet.png",
"json": "character/" + tempShirt + "/running-feet.json",
},
["idle-feet-" + tempShirt]: {
"png": "character/" + tempShirt + "/idle-feet.png",
"json": "character/" + tempShirt + "/idle-feet.json",
},
["jumping-feet-" + tempShirt]: {
"png": "character/" + tempShirt + "/jumping-feet.png",
"json": "character/" + tempShirt + "/jumping-feet.json",
},
["kick-feet-" + tempShirt]: {
"png": "character/" + tempShirt + "/kick-feet.png",
"json": "character/" + tempShirt + "/kick-feet.json",
},
};
if (i === 0 || i > 0 && rightShirt !== leftShirt) {
Atlas = Object.assign(Atlas, tempBody);
}
}
const Audio = {
"goal-01": {
"mp3": "sfx/goal-01.mp3",
"ogg": "sfx/goal-01.ogg",
},
"goal-02": {
"mp3": "sfx/goal-02.mp3",
"ogg": "sfx/goal-02.ogg",
},
"goal-03": {
"mp3": "sfx/goal-03.mp3",
"ogg": "sfx/goal-03.ogg",
},
"head-ball-type-01": {
"mp3": "sfx/head-ball-type-01.mp3",
"ogg": "sfx/head-ball-type-01.ogg",
},
"head-ball-type-02": {
"mp3": "sfx/head-ball-type-02.mp3",
"ogg": "sfx/head-ball-type-02.ogg",
},
"head-ball-type-03": {
"mp3": "sfx/head-ball-type-03.mp3",
"ogg": "sfx/head-ball-type-03.ogg",
},
"head-ball-type-04": {
"mp3": "sfx/head-ball-type-04.mp3",
"ogg": "sfx/head-ball-type-04.ogg",
},
"hitting-goal-post": {
"mp3": "sfx/hitting-goal-post.mp3",
"ogg": "sfx/hitting-goal-post.ogg",
},
"kick-ball-type-01": {
"mp3": "sfx/kick-ball-type-01.mp3",
"ogg": "sfx/kick-ball-type-01.ogg",
},
"kick-ball-type-02": {
"mp3": "sfx/kick-ball-type-02.mp3",
"ogg": "sfx/kick-ball-type-02.ogg",
},
"kick-ball-type-03": {
"mp3": "sfx/kick-ball-type-03.mp3",
"ogg": "sfx/kick-ball-type-03.ogg",
},
"kick-on-face": {
"mp3": "sfx/kick-on-face.mp3",
"ogg": "sfx/kick-on-face.ogg",
},
"whistle-foul": {
"mp3": "sfx/whistle-foul.mp3",
"ogg": "sfx/whistle-foul.ogg",
},
"whistle-full-game": {
"mp3": "sfx/whistle-full-game.mp3",
"ogg": "sfx/whistle-full-game.ogg",
},
"whistle-kick-off": {
"mp3": "sfx/whistle-kick-off.mp3",
"ogg": "sfx/whistle-kick-off.ogg",
},
"ball-stock-above-goal-gate": {
"mp3": "sfx/ball-stock-above-goal-gate.mp3",
"ogg": "sfx/ball-stock-above-goal-gate.ogg",
},
"crowd-during-match": {
"mp3": "crowds/crowd-during-match.mp3",
"ogg": "crowds/crowd-during-match.ogg",
},
};
Preloader.images(Images, this);
Preloader.script(JS, this);
Preloader.spriteSheet(SpriteSheet, this);
Preloader.atlas(Atlas, this);
Preloader.atlas(Advertise, this);
Preloader.audio(Audio, this);
new VersionTitleComponent({scene: this});
}
onProgress(value) {
this.tweens.add({
targets: this.progressBarFill,
scaleX: value,
ease: "Linear",
duration: 100,
repeat: 0,
});
}
onComplete() {
if (this.gameMode === "solo") {
this.game.emitter.emit(EVENTS.PLAY_SOUND, "preload-complete");
}
}
startGame() {
this.scene.start("Game", {
gameMode: this.gameMode,
shirts: {
left: this.config.shirts.left,
right: this.config.shirts.right,
},
heads: {
left: this.config.heads.left,
right: this.config.heads.right,
},
ball: this.config.ball,
controllerBackground: this.config.controllerBackground,
field: this.config.field,
sky: this.config.sky,
advertisement:this.selectedRandomAdvertise,
});
}
create() {
this.tweens.add({
targets: this.progressBarFill,
scaleX: 1,
ease: "Linear",
duration: 100,
repeat: 0,
});
if (this.gameMode === "multi" && !CONFIG.GAME_INFO.CONDITION_OF_TWO_PLAYER_CAN_PLAY_WITH_KEYBOARD) {
this.startGame();
} else {
this.beginningButton = new BounceButton({
scene: this,
x: this.game.centerX,
y: this.progressBarBackground.y + 110,
text: {
type: "image",
value: "beginning-text",
},
sound: {
push: "push-button",
},
background: {
value: "blue-button",
},
onPush: this.startGame.bind(this),
});
}
}
}
May need a simpler example.
Yes, this was by design - that Input events could only be handled after create had been completed. However, I see no reason not to allow them during init or preload, so this is now possible in the master branch version.