Adding a Phaser sprite using a javascript ES6 class - javascript

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,
]
}

Related

Can I fire Phaser 3 events from DOM?

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>

How can I use mediapipe face detection for static image in javascript?

mediapipe's face detection predict every frame but I want to predict every 10 seconds
Can I adjust predict time?
Or Can I use static image?
Or recommend other face detection library please
I tried it like this
To adjust predict time, I use setInterval but mediapipe predict every frame
To use static image, I use image but mediapipe don't operate
I need to face-image because it is tensorflow js model's input
How can I solve this?
please recommend solution or other face detection library in javascript
function CropFace(results) {
document.body.classList.add('loaded');
fpsControl.tick();
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (results.detections.length > 0) {
drawRectangle(
ctx, results.detections[0].boundingBox,
{color: 'white', lineWidth: 1, fillColor: '#00000000'});
// drawLandmarks(ctx, results.detections[0].landmarks, {
// color: 'red',
// radius: 5,
// });
}
ctx.drawImage(results.image, 0, 0, canvas.width, canvas.height);
}
const faceDetection = new FaceDetection(
{locateFile: (file) => {
// console.log(file)
return `https://cdn.jsdelivr.net/npm/#mediapipe/face_detection#0.0/${file}`;
}
}
);
// setInterval(faceDetection.onResults(CropFace), 10000);
faceDetection.onResults(CropFace)
// asnyc function input_image() {
// await faceDetection.send({image: image});
//}
const camera = new Camera(video, {
onFrame: async () => {
await faceDetection.send({image: video});
},
width: 224,
height: 224
}
);
camera.start();
new ControlPanel(controlsElement1, {
selfieMode: true,
minDetectionConfidence: 0.5,
})
.add([
new StaticText({title: 'MediaPipe Face Detection'}),
fpsControl,
new Toggle({title: 'Selfie Mode', field: 'selfieMode'}),
new Slider({
title: 'Min Detection Confidence',
field: 'minDetectionConfidence',
range: [0, 1],
step: 0.01
}),
])
.on(options => {
video.classList.toggle('selfie', options.selfieMode);
faceDetection.setOptions(options);
}
);
{ image } in faceDetection.send can be HTMLVideoElement, HTMLImageElement or HTMLCanvasElement
so in your case, create canvas, draw frame on it and call faceDetection.send manually as you want using your canvas as input.

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.

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>

How do I implement zingchart into angular2

I have an existing project that I want to implement zingcharts on.
I have tried 3 different tutorials mainly from " https://blog.zingchart.com/2016/07/19/zingchart-and-angular-2-charts-back-at-it-again/ "blog.
However I can not get that working in my project.
So I decided I will try and implement it the most basic way first and later on try better ways. This is what I did but it does not shop up yet.
Being new to angular2 I am not quite sure if this will work.
I went to the ZingChart website and tried to implement this basic example ->https://www.zingchart.com/docs/getting-started/your-first-chart/
So I built 2 files chart.ts and chart.component.html and implemented the
"<script src="https://cdn.zingchart.com/zingchart.min.js"></script>"
in the index.html
//chart.ts
import { Component } from '#angular/core';
#Component({
selector: 'rt-chart',
templateUrl: './chart.component.html'
})
export class Chart
{
}
//chart.component.html
<!--Chart Placement[2]-->
<div id="chartDiv"></div>
<script>
var chartData = {
type: "bar", // Specify your chart type here.
title: {
text: "My First Chart" // Adds a title to your chart
},
legend: {}, // Creates an interactive legend
series: [ // Insert your series data here.
{ values: [35, 42, 67, 89]},
{ values: [28, 40, 39, 36]}
]
};
zingchart.render({ // Render Method[3]
id: "chartDiv",
data: chartData,
height: 400,
width: 600
});
</script>
I called it in my already working website as
It does not show up. What am I doing wrong? Is there something I am missing.
Angular2 is quite new to me.
Thanks
With latest angular2 version (#2.2.3) you can leverage special ZingChart directive like this:
zing-chart.directive.ts
declare var zingchart: any;
#Directive({
selector : 'zing-chart'
})
export class ZingChartDirective implements AfterViewInit, OnDestroy {
#Input()
chart : ZingChartModel;
#HostBinding('id')
get something() {
return this.chart.id;
}
constructor(private zone: NgZone) {}
ngAfterViewInit() {
this.zone.runOutsideAngular(() => {
zingchart.render({
id : this.chart.id,
data : this.chart.data,
width : this.chart.width,
height: this.chart.height
});
});
}
ngOnDestroy() {
zingchart.exec(this.chart.id, 'destroy');
}
}
where ZingChartModel is just a model of your chart:
zing-chart.model.ts
export class ZingChartModel {
id: String;
data: Object;
height: any;
width: any;
constructor(config: Object) {
this.id = config['id'];
this.data = config['data'];
this.height = config['height'] || 300;
this.width = config['width'] || 600;
}
}
Here's completed Plunker Example

Categories

Resources