Can I fire Phaser 3 events from DOM? - javascript

I'm trying to fire a Phaser 3 event from DOM like I read on this example I found on internet:
"The game instance is accessible when you create the game, with something like
const game = new Phaser.Game(config);
And you can access everything from your desired scene from this instance
const scene = game.scene.keys.sceneName
And do something like
textareaElement.addEventListener("change", function(event) {
const text = textareaElement.value;
scene.updateGameTextFromTextarea(text);
});
This is my project config:
const config = {
// Phaser.AUTO, intenta usar WebGL y si el navegador no lo tiene, usa canva.
type: Phaser.AUTO,
parent: 'game-container',
width: 650,
height: 522,
scene: [MainScene],
scale: {
mode: Phaser.Scale.FIT
},
dom: {
createContainer: true
},
physics: {
default: 'arcade',
arcade: {
// debug: true,
// gravity: { y: 350 }
}
}
}
// Inicializacion del objeto
game = new Phaser.Game(config)`
I actually can access to game from console, but canĀ“t fire events.
const scene = game.scene.keys.MainScene
scene.greeting()
get:
Uncaught TypeError: Cannot read properties of undefined (reading 'greeting')
at :1:7
Code:
https://github.com/Neffer2/bull-rompecabezas.git

There are two issues:
The first issue is, that the name of the scene is gameScene not MainScene , this is the value from the constructor.
The second issue is the Scene/Game Instance is not populated right away, you would have to wait abit. I simulated this in the demo with the setTimeout, or you can also click the Button to call the same function from the scene.
Here a short Demo:
document.body.style = 'margin:0;';
class MainScene extends Phaser.Scene {
constructor(){
super('gameScene');
}
test(){
console.info('Hello From Scene');
}
}
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 100 },
debug: true
}
},
scene: [ MainScene ],
banner: false
};
var game = new Phaser.Game(config);
setTimeout( () => game.scene.keys.gameScene.test(), 1000); // Wait for generation
document.querySelector('button').addEventListener('click', () => game.scene.keys.gameScene.test())
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
<button id="button"> Fire from the DOM </button><br>

Related

How to use contextBridge in React-Electron?

I'm trying to connect with preload and frame.tsx
But, It isn't working.
frame.tsx
function handleButtonClick(id: string) {
window.electron.send("requestWindowChange", "data") // Error part
if(id === 'maximize') {
setIsMaximize(!isMaximize)
}
}
I simply add it. and...
preload.ts
import {contextBridge, ipcRenderer} from 'electron'
contextBridge.exposeInMainWorld('electron', {
send: (channel:string, data) => {
let normalChannels = ['requestWindowChange']
if (normalChannels.includes(channel)) {
ipcRenderer.send(channel, data)
}
},
receive: (channel:string, func) => {
let normalChannels = ['responseWindowChange']
if (normalChannels.includes(channel)) {
ipcRenderer.on(channel, (_event, data) => func(data))
}
}
})
Also, I'm already making 'preload.ts' to 'preload.js' by using 'tsc' command.
Finally, here is the electron.ts
mainWindow = new BrowserWindow({
height: 720,
width: 1280,
minHeight: 300,
minWidth: 450,
frame: false,
show: false,
center: true,
fullscreen: false,
kiosk: !isDev,
resizable: true,
webPreferences: {
preload: path.join(__dirname, "preload.js")
}
})
I only copy necessary part.
If you need more code, please comment here.
I really don't know why It isn't working.
Here is Error Message.
any Property 'electron' does not exist on type 'Window & typeof
globalThis'. Did you mean 'Electron'?ts(2551)
I'm trying searching and asking for a week, finally I find it.
Just add this at frame.tsx.
declare global {
interface Window {
api? : any
}
}
What a simple it is...

Phaser pointer events not working in WebView (Xamarin Forms) C#

I have create a simple animation screen using phaser and its rendering perfect and invoking all pointer events like pointerover, pointerout, pointerup and pointerdown on button btn as expected for browser. But when I render same game using WebView its rendering screen but its not invoking any pointer events. To confirm JavaScript is working I have tested by adding eventlistner on window and it was working.
var config = {
type: Phaser.CANVAS,
width: 650,
height: 900,
canvas: document.getElementById('myCustomCanvas'),
scale: {
mode: Phaser.Scale.FIT,
width: 750,
height: 1334,
parent: 'game'
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }
}
},
scene : {
preload: function(){game.preload(this, 'asset_url');},
create: function(){game.create(this);},
update: function(){game.update(this);},
}
};
function game(config) {
this.start = function(config)
{
this.phaserGame = new Phaser.Game(config);
};
this.create = function()
{
var btn = this.scene.add.sprite(375, 665, 'btn');
btn.setInteractive()
.on('pointerover', () => {
console.log('pointerover');
})
.on('pointerout', () => {
console.log('pointerout');
})
.on('pointerdown', () => {
console.log('pointerdown');
})
.on('pointerup', () => {
console.log('pointerup');
});
};
}
I am using Xamarin Forms WebView to render game in mobile. My setting for WebView is as follow.
var webView = CreateNativeControl();
webView.SetWebViewClient(new HTMLGameWebClient(this));
webView.Settings.LightTouchEnabled = true;
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DomStorageEnabled = true;
webView.Settings.MediaPlaybackRequiresUserGesture = false;
SetNativeControl(webView);
I also have conditional CSS which is used only if canvas is rendering in mobile.
canvas {
width: 100vw !important;
height: unset;
}
Thanks in advance for any helps or suggestions.

How to fix application-window resizing error for a BrowserView in electronjs?

so I'm writing on a electron application at the moment.
To make my application a bit smoother I created a BrowserWindow and loaded just the menubar and the background.
After that I added a BrowserView to show the acutal content.
Code for my BrowserWindow:
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
show: false,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile(path.join(__dirname, 'views/index.pug'));
win.on('closed', () => {
win = null;
})
win.once('ready-to-show', () => {
win.show();
})
}
Code for my BrowserView:
function createViews() {
contentView = new BrowserView({ webPreferences: { nodeIntegration: true } });
win.addBrowserView(contentView);
contentView.setBounds({ x: 0, y: 23, width: win.getBounds().width, height: win.getBounds().height - 23 });
contentView.setAutoResize({ width: true, height: true });
contentView.webContents.loadFile(path.join(__dirname, 'views/imageGallery.pug'));
}
(If there is a spoiler function to hide the code: I'm sorry, I didn't find any)
Once I create the window it works like intended, also the normal resize via mouse-drag works perfectly.
Now my problem is, as soon as I maximize or unmaximize my window with the functions win.maximize() and win.unmaximize() my BrowserView gets resized. But the resize doesn't fit the BrowserWindow anymore. The content of the BrowserView is being cutted on the right side.
Window after being maximized:
Window after being unmaximized:
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({ useContentSize: true });
const view = new BrowserView();
mainWindow.setBrowserView(view);
view.setBounds({ x: 0, y: 0, width: 800, height: 600 });
view.setAutoResize({ width: true, height: true });
view.webContents.loadURL("https://youtube.com");
}

Timer not working inside function in Phaser 3

I have a spawn function which performs some task. Before the function returns, I would like to delay some another function call.
I tried using time.addEvent but with no luck as it does not seem to work within the spawn function. However the timer works perfectly inside the create function.
My code so far:
create(){
newMethod = spawn.bind(this);
newMethod();
}
function spawn(){
//do stuff
timer = this.time.addEvent({
delay: 3000,
callback: functionDelay,
loop: false
});
}
function functionDelay(){
console.log("Works!");
}
var delayText;
var delayedEvent;
class myScene extends Phaser.Scene {
constructor (config)
{
super(config);
}
preload ()
{
this.load.image('dude', 'sprites/phaser-dude.png')
}
create ()
{
delayText = this.add.text(50, 50);
delayedEvent = this.time.delayedCall(3000, this.spawn, [], this);
}
spawn()
{
var sprite = this.add.sprite(300, 50, 'dude')
}
update()
{
delayText.setText('Event.progress: ' + delayedEvent.getProgress().toString().substr(0, 4));
}
}
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
loader: {
baseURL: 'https://cdn.jsdelivr.net/gh/samme/phaser-examples-assets#v2.0.0/assets/',
crossOrigin: 'anonymous'
},
width: 800,
height: 600
};
var game = new Phaser.Game(config);
game.scene.add('myScene', myScene, true);
<script src="//cdn.jsdelivr.net/npm/phaser#3.17.0/dist/phaser.min.js"></script>

Adding a Phaser sprite using a javascript ES6 class

I have the following minimal code, using Phaser.js 3.11.0 and Javascript ES6:
class Ship extends Phaser.Physics.Arcade.Image {
constructor(scene, x, y) {
super(scene, x, y, 'ship');
}
}
class Scene extends Phaser.Scene {
preload() {
this.load.image('ship', require('../assets/ship.png'));
}
create() {
this.ship1 = this.physics.add.existing(new Ship(this, 50, 70));
this.ship2 = this.physics.add.image(150, 70, 'ship');
}
}
new Phaser.Game({
type: Phaser.AUTO,
width: 200,
height: 150,
scene: Scene,
physics: {
default: 'arcade',
arcade: {
debug: true,
},
},
});
Using this.physics.add.existing(new Ship(this, 50, 70)) doesn't work: the sprite is not displayed, even if the debug bounding box is shown, with the right size.
Here is the rendered output:
If I don't use physics, the sprite displays correctly:
class Ship extends Phaser.GameObjects.Image {
...
}
class Scene extends Phaser.Scene {
...
create() {
this.ship1 = this.add.existing(new Ship(this, 50, 70));
...
}
}
What am I missing?
I was able to fix the problem by changing the create() method:
create() {
this.ship1 = this.add.existing(new Ship(this, 50, 70));
this.physics.world.enable([ this.ship1 ]);
}
Indeed, you can read in the API documentation, about the Phaser.Physics.Arcade.World#enable() method:
Calling factory methods encapsulates the creation of a Game Object and
the creation of its body at the same time. If you are creating custom
classes then you can pass them to this method to have their bodies
created.
Why don't you call the Arcade physics in the config main.js?ie:
const config = {
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: [
BootScene,
LevelScene,
]
}

Categories

Resources