What's is "this" refer to in Phaser 3? - javascript

I'm new to Javascript and want to make simple games with Phaser 3, and I found that Javascript seems to be a little different from other OOP languages like C++ or Java. I checked out the tutorial in the official website and some other tutorial page, most of the code is like:
var config = {
...
scene: {
preload: preload,
create: create,
update: update
}
}
var game = new Phaser.Game(config)
function preload(){
this.load.img(...)
}
My question is what is the ‍"this" in the preload() indicate to? Is it means the "game" we defined before?
And how to check the object's class in console? typeof() only tells "object".

this is an instance of Phaser.Scene and not Phaser.Game.
The other answers are incorrect. The code is running the browser.
To see the docs for a Scene you can look here

In the code you have this is a pointer to your game instance which is why you can call Phaser methods to load assets, adjust the camera, etc.
In your config you are setting which function is called during the preload step in the game. When Phaser runs it calls your function (which just happens to be named preload too) and sets the scope of this to the game instance.

Related

Blazor server side problem share javascript code

I'm developing my project with Blazor Server-side.
While I develop, I used javascript code to implement things that hard to implement by C#.
However, I'm facing something weird situation. (I guess it is problem for javascript)
Suppose there are 2 users(A, B). When 'A' user do some action that call javascript code, if 'B' user into same page, 'A' users action affects to 'B' user.
I implemented web page that have 3d scene with threejs. As I explained above, when User 'A' move some object with mouse event(mousemove, mousedown..), if User 'B' accesses the same page, 3d objects of B are moved to the location where User 'A' moved.
Originally, when user access to web page I developed, 3d objects's position should be 0,0,0.
My Guess
I don't use prototype or class(use variable and functions globally. I'm new to javascript.. )
Javascript runs on server-side(share resources??, If then, how can I solve it)
I'm guessing the javascript would be problem, but if you have any other opinions, would you please share?
Edited
I've solved this problem using DotNetObjectReference.Create(this);
C#
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//send created instance to javascript
var dotNetObjRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeVoidAsync("SetObjectRef", dotNetObjRef);
}
await base.OnAfterRenderAsync(firstRender);
}
[JSInvokable]
public async Task enableSomething(bool bEnable)
{
var something = bEnable;
}
//== before edit
//[JSInvokable]
//public static async Task enableSomethingStatic(bool bEnable)
//{
// var something = bEnable;
//}
Javascript
var objectRef;
function SetObjectRef(ref) {
objectRef = ref;
}
//call c# function
objectRef.invokeMethodAsync("enableSomething", true);
It was problem of 'static' method as I guessed.
If you declare C# method called from javascript as 'static' and this method changes something of UI variable, this method can affect another users.
So I create instance of current page and send it javascript and when I need to call C# methods from javascript, I call methods using created instance.
Is there any problem or issue, please share it.
Sorry for my bad English.
JavaScript runs client side only. I don't see how two windows, let alone two users, would share data.
Almost for sure, the problem is that you are injecting a singleton service-- which means the server will use one instance for all users.
If so, you have two choices:
(1) add logic to your singleton service to incorporate users. (For example, a dictionary with UserID/Property name for key, and a column for Value)
(2) go to Startup.cs and change the suspect singleton service to .AddScoped(), which will create a new instance for each user.
For right now, I think the latter solution will solve your problem immediately. However, don't underestimate the value of Singletons-- they'll be very useful for other things.

unity webgl and browser javascript communication

So i have this problem with communicating between browser and unity webgl,
basically what i want to do is generate objects in unity's scene with javascript code from the view the webgl is being played. In other words, view will have javascript code to create game objects after the scene loaded, not sure if this is possible yet.
i've read the unity documentation but i haven't found an example of how to implement the code shown there or if it's what i'm looking for.
https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html this is what i have been reading, specially the code visibility part, but since i've never worked with frontend that much i'm a bit clueless.
What you can do is to send messages to Unity inside your Javascript code but you'll let Unity do the dirty work about instantiating objects.
This is an example that I just made:
First you create a C# script that spawns your object/prefab, like this:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MyObjectSpawner : MonoBehaviour {
public Transform Prefab;
public void Spawn(string data) {
var instance = Instantiate(Prefab);
// do what you like with your instantiated object and the data from the javascript here
}
}
Now you create an object inside the scene and attach this script to it. Keep attention about the name you give to the Game Object you just created, this will be important in the next step. For now, let's say we named it "MyGameObject".
The last step is your javascript inside the game page container. For this example, I've created a button and when it's clicked, the spawnUnityObject() method is called. Like this:
HTML:
<button type="button" onclick="spawnUnityObject()">Press me</button>
Javascript:
function spawnUnityObject() {
// game object in the scene, method name, method parameter
SendMessage('MyGameObject', 'Spawn', 'Super string');
}
The result will be: when you click the "Press me" button inside the html, the game will spawn an object and you can use the "Super string" as a data inside the Spawn() method.
I hope this helps you. Let me know if you need more details.

how to target a MovieClip with createjs

Im trying to export an group photo animation that works fine in flash but not when exported in html5 canvas.
The trick is "simple" : each photo is a button and when you roll your mouse over the picture of someone, his jobtitle appears.
Ican't make it happen with createjs !
I have a MovieClip instance on my stage named "jobs_cont" whose timeline has different keyframes and labels for everyone's jobtitles.
The thing is i'm not successfull with targeting "jobs_cont" and using gotoAndPlay a specific frame or label in its timeline when a button is hovered.
the "alert instruction" alone is recognised but not the "jobs_cont.gotoAndPlay":
var frequency = 3;
stage.enableMouseOver(frequency);
this.mybutton.addEventListener("mouseover", fl_MouseOverHandler);
function fl_MouseOverHandler(){
this.jobs_cont.gotoAndPlay("mylabel");
alert("hovered by mouse");
// end of your personalized code
}
I think i must miss something targeting "jobs_cont" in createjs but i'm newbie in javascript and can't figure it out despite my day of researches.
If someone could give a hint.
Thank you.
You are dealing with scope issues. If you define a function on your timeline using the above syntax, the function doesn't have a scope, so this becomes Window.
You can change the function syntax to be defined on the current object:
this.fl_MouseOverHandler = function(){
this.jobs_cont.gotoAndPlay("mylabel");
alert("hovered by mouse");
// end of your personalized code
}
Lastly, JavaScript doesn't automatically provide function scope for event listeners (yet!) so you have to scope the function yourself. If you have a version 0.7.0 or later of EaselJS, you can use the on method instead of addEventListener (docs). Note that you have to use this.fl_MouseOverHandler as well.
this.mybutton.on("mouseover", this.fl_MouseOverHandler, this);
You can also scope the function using a utility method such as Function.prototype.bind() (docs):
this.mybutton.addEventListener("mouseover", this.fl_MouseOverHandler.bind(this));
Hope that helps!

Javascript function just not working for canvas game

I'm creating a canvas game (the concept is a side scrolling endless games). I'm trying to make power-ups so I have a main game JS file along with a powerup.js among others. At the moment I'm concentrating on my invincibility power up. I've created some simple code which in theory should work:
In the powerup.js
function powerUpInvincibility() {
invincible = true;
//window.setInterval(powerUpInvincibilityReset, this.powerUpTime[0]);
}
function powerUpInvincibilityReset() {
jet1.invincible = false;
}
I set the invincible variable in the main js but they are all linked, I've got code in all the JS files working but even when I call the powerUpInvincibility function in Chrome's Console the variable doesn't change.
I've tried making it a variable for the jet and the powerup but that doesn't work either and I've checked for any spelling mistakes several times.
I'm lost, any suggestions?
Ok sorry everyone! The actual problem was that one of my powerUp functions tried to access a this variable when it wasn't a powerUp.prototype function. Thanks for the answers!

Use of prototype for single instance functions in JavaScript

For performance optimization I'm using a single JavaScript file to handle all the pages of the website I'm working on.
The basic structure I'm using is as followed:
(function($) {
// Shared functions ...
// A function for every page
function Page1() {
}
Page1.prototype = {
init: function() {
//...
},
//more functions
};
// more pages
$(document).ready(function() {
if ($('#page1uniqueidentifier').length) {
var page1 = new Page1();
page1.init();
}
// more pages
}
}) (jQuery);
I'm not an experienced JavaScript programmer so I've been searching a lot about best practices and different ways of structuring my code and I've ended up choosing this one but I'm not really sure about it and I have a few questions:
Is it worth it to use prototype if I'm never gonna have more than a single instance of a page? I think I understand how prototype works and that I'm not gaining any performance there. But I'm using it just as a best practice because in the case different instances would exist, these functions would be the same in every instance.
Is there a better way to structure the code?
Should I put the call of the init function inside the constructor and then only call new Page1()?
function Page1() {
this.init();
}
if ($('#page1uniqueidentifier').length) {
new Page1();
}
For performance optimization I'm using a single JavaScript file to
handle all the pages of the website I'm working on
That makes no sense. You should separate code into files, and then run all your js files thru a minimizer/concatenator to package it up.
Anyway, to answer your questions,
if you are only going to have 1, then prototype won't buy you anything. However, if you are going to use more than 1, would you go back and change it? Plus, using prototype wont hurt you either, so you might as well do it for learning.
You should create the files that make sense according to the functionality implemented. I would separate your object definition into its own file, for example, so when you look at that file, all you see is the code for that object.
If you have a constructor function, you don't really need init, do you?

Categories