Phaser 3 : Add arguments to callback functions (time event, keyboard event) - javascript

I'm developing a game on Phaser 3 and I'm currently struggling on callback use.
I have created two classes, one called "Entitee" and the other one called "objet"
class Entitee extends Phaser.Physics.Arcade.Sprite{
constructor(scene, x, y, pv, mana, speed, poise, asset){
//Private
var _pv = pv;
var _pvMax = pv;
var _mana = mana;
var _manaMax = mana;
var _speed = speed;
var _poise = poise;
var _asset = asset;
super(scene, x, y, _asset);
scene.add.existing(this);
scene.physics.world.enableBody(this);
//Public
this.hurt = function(objet){
console.log(_pv);
console.log(objet);
_pv += objet.getPvMod();
console.log(_pv);
}
}//END CONSTRUCTOR
}
class Objet {
constructor(name, price, range, cd, ammo, lag, pvMod, manaMod, poiseMod, speedMod, animAtt, animZone){
var _name = name;
var _price = price;
var _range = range;
var _cooldown = cd;
var _ammo = ammo;
var _direction;
var _lag = lag;
var _pvMod = pvMod;
var _manaMod = manaMod;
var _poiseMod = poiseMod;
var _speedMod = speedMod;
var _animAtt = animAtt;
var _animZone = animZone;
this.getName= function(){ return _name};
this.getPrice= function(){ return _price};
this.getRange= function(){ return _range};
this.getCooldown= function(){ return _cooldown};
this.getAmmo= function(){return _ammo};
this.getDirection = function(){return _direction};
this.getPvMod = function(){return _pvMod};
this.getManaMod = function(){return _manaMod};
this.getPoiseMod = function(){return _poiseMod};
this.getSpeedMod = function(){return _speedMod};
this.getAnimAtt = function(){return _animAtt};
this.getAnimZone = function(){return _animZone};
}
}
Now i'm trying to get my entitee (entity in English) hurt by an object i created, called "hammer". But i would like to be able to get it hurts by many different object.
I try to get it hurt when I press "P" and/or every 1 sec.
But I can't found how to give to the callback function the object I want the entity to get hurt with.
class Scene1 extends Phaser.Scene{
constructor() {
super("Scene1")
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> INIT
init(){
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PRELOAD
preload(){
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CREATE
create(){
this.joueur = new Entitee(this, 100, 100, 100, 10, 200, 42, "square");
this.hammer = new Objet("Hammer", 12, 12, 12, 12, 0, -10, 0, 10, "empty", "empty");
this.timer_test = this.time.addEvent({ delay: 1000, callback: this.joueur.hurt, args: [this.joueur, this.hammer], loop: true });
this.input.keyboard.on('keydown-P', this.joueur.hurt, this.joueur, this.hammer);
this.joueur.hurt(this.hammer);
}//END CREATE
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> UPDATE
update(){
}//END UPDATE
}//END SCENE
i have this.joueur.hurt(this.hammer); working.
this.timer_test = this.time.addEvent({ delay: 1000, callback: this.joueur.hurt, args: [this.joueur, this.hammer], loop: true }); send me the following error :
Entitee.js:60 Uncaught TypeError: objet.getPvMod is not a function
at Function.Entitee.hurt (Entitee.js:60)
at Clock.update (phaser.js:183771)
at EventEmitter.emit (phaser.js:1774)
at Systems.step (phaser.js:35504)
at SceneManager.update (phaser.js:77851)
at Game.step (phaser.js:139643)
at TimeStep.step (phaser.js:67227)
at step (phaser.js:67474)
And when I press "p" i get
Entitee.js:60 Uncaught TypeError: objet.getPvMod is not a function
at Entitee.hurt (Entitee.js:60)
at KeyboardPlugin.emit (phaser.js:1752)
at KeyboardPlugin.update (phaser.js:166926)
at EventEmitter.emit (phaser.js:1751)
at onKeyDown (phaser.js:71462)
I figure how to avoid callback functions but it would be so easiest if I may give to those callback the arguments I want.
I've been lurking around internet for solutions but none of it have been useful. Some people seems to use console.log() but I can't understand why and how.
Thanks for considering my issue !
Sheolis

I suppose that args should be just [this.hammer] since we don't need joueur as input to the hurt function
this.timer_test = this.time.addEvent({
delay: 1000,
callback: this.joueur.hurt,
args: [this.hammer],
loop: true });
You may also look at callbackScope at the docs.

Related

Object instance is stripped of its methods [duplicate]

This question already has answers here:
socket.io - emited objects from server lose their functions and name once received by client
(1 answer)
Socket.io passing javascript object
(2 answers)
Closed 5 years ago.
For an online board game I am making, I have defined a Tile class, whose instances I use to create a "map". The Tile class has several properties, and a method called show which displays the instance on the canvas.
All the scripts are passed on to the clients as static files via script tags in the index.html which is served by node.js. The instantiation of the Tile class worked properly before I introduced the server. Now it produces some very weird and interesting results.
The HexMap class, creates upon instantiation a 2d array of Tiles as follows:
function HexMap (width, height, image) {
this.width = width;
this.height = height;
this.contents = [];
for (let i = 0; i < this.width; i++) {
this.contents[i] = [];
for (let j = 0; j < this.height; j++)
this.contents[i].push(new Tile(i, j, size, image, "SEA"));
}
}
The code for the Tile class is this:
var Tile = function (row, column, side, image, type) {
Vector.call(this, row, column);
this.unit = null;
this.canvas = null;
this.side = side;
this.type = type;
this.startingPoint = new Vector(this.x*Math.sqrt(3)*this.side + (this.y& 1) * this.side*Math.sqrt(3)/2, this.side*1.5*this.y);
this.middlePoint = new Vector(this.startingPoint.x + Math.sqrt(3)*this.side/2, this.startingPoint.y + this.side/2);
this.getOffset = function () {
return {
"SEA" : 0,
"SHORELINE" : 60,
"PLAINS" : 120,
"FOREST_LIGHT" : 180,
"FOREST_HEAVY" : 240,
"MOUNTAINS" : 300,
"SWAMP" : 360,
"MARSH" : 420
}[this.type];
};
this.getVector = function () {
return new Vector(this.x, this.y);
};
this.show = function (context) {
if(!this.canvas){
this.canvas = makeTemplate(side, this.type, image);
}
context.drawImage(this.canvas, this.startingPoint.x - this.getOffset(), this.startingPoint.y);
};
this.getPixelX = function () {
return this.x*Math.sqrt(3)*this.side + (this.y & 1) * this.side;
};
this.getPixelY = function () {
return this.side/2 + this.side*2*this.y;
};
this.setType = function (type){
this.type = type;
};
};
Printing a Tile object in the console would normally display something like this:
Tile {x: 0, y: 0, unit: null, canvas: canvas, side: 15, …}
I tried the same thing using the server this time, and the result is this:
{x: 0, y: 1, unit: null, canvas: null, side: 15, …}
Interestingly enough, the result is indeed an object, but not a Tile object. It has all the properties a Tile object has, but has none of its methods.
The error I end up getting is this:
tile.show is not a function
The map object is created and transferred to the server via socket.io sockets. The following piece of code runs on the client (the guest).
function selectGame(id) {
var hexmap = new HexMap(rowspan, colspan, spritesheet);
hexmap.generateIsland();
socket.emit('game-select', {id: id, hexmap: hexmap});
}
The server then receives the map:
socket.on('game-select', function (data) {
//The 2 sockets corresponding to the players join the same room
io.sockets.connected[data.id].join(games[data.id].identifier);
io.sockets.connected[socket.id].join(games[socket.id].identifier);
//The start-game event is emitted for just the sockets of the same room
io.to(games[socket.id].identifier).emit('start-game', {
map: data.hexmap
});
});
Then both the clients receive it again:
socket.on('start-game', function (data) {
let el = document.getElementById("wrapper");
el.parentNode.removeChild(el);
hexmap = data.map;
contexts = setupCanvas();
displayMap(hexmap, contexts.mapContext);
});
What displayMap does is it iterates through the contents of the map, and displays each Tile using its show method.
I cannot pin down the problem no matter how hard i try... Any suggestion on how to solve this?

Multiple objects aren't getting displayed

I've been messing around with objects in Javascript and I've come across a problem. Basically I'm trying to print certain properties from objects I've created and it's not working properly.
Here's the code:
function Hotel(name, rooms, booked) {
this.name = name;
this.rooms = rooms;
this.booked = booked;
var CanadaHotel = new Hotel("CanadaIn", 50, 10);
var AmericanHotel = new Hotel("AmericanIn", 60, 3);
document.write(CanadaHotel.rooms);
document.write(AmericanHotel.booked);
None of the properties are being displayed and I don't know why.. any help is greatly appreciated.
Thank you
SyntaxError: missing } after function body
Fixed
function Hotel(name, rooms, booked) {
this.name = name;
this.rooms = rooms;
this.booked = booked;
}
var CanadaHotel = new Hotel("CanadaIn", 50, 10);
var AmericanHotel = new Hotel("AmericanIn", 60, 3);
console.log(CanadaHotel.rooms);
console.log(AmericanHotel.booked);

Using tween on class object, function definiton?

I am trying to do scene effects opening and closing scenes. But something is wrong with my self and this values. It says not defined or not working. How can ı define these functions.
Ways I tried to define
First way:
var tween = createjs.Tween.get(this.scene).to({alpha : 0}, 5000).call(menuOutCompleted(nextScreen,isNextScreenPopUp));
It is throwing "menuOutCompleted is not defined";
Second way:
var tween = createjs.Tween.get(this.scene).to({alpha : 0}, 5000).call(self.menuOutCompleted(nextScreen,isNextScreenPopUp));
It is not throwing any exception but does not do tween. It directly execute menuOutCompleted.
Third way:
var tween = createjs.Tween.get(this.scene).to({alpha : 0}, 5000).call(this.menuOutCompleted(nextScreen,isNextScreenPopUp));
It works like second way.
My js class
function CreditsScreen(SceneContainer)
{
var closePopUp_Button, background;
this.name = "CreditsScreen";
var self = this;
this.scene = new createjs.Container();
this.loadScreen = function()
{
background = new createjs.Shape();
background.graphics.beginBitmapFill(loader.getResult("coronaLogo")).drawRect(0,0,512,512);
background.x = 200;
background.y = 0;
closePopUp_Button = new createjs.Sprite(buttonData, "exitIdle");
closePopUp_Button.framerate = 30;
closePopUp_Button.x = 400;
closePopUp_Button.y = 22;
// play.addEventListener("click", handleClickPlay);
this.scene.alpha = 0;
this.scene.addChild(background);
this.scene.addChild(closePopUp_Button);
}
this.menuIn = function()
{
console.log("menuIn CreditsScreen" );
stage.addChild(this.scene);
//ptoblemetic part with self.menuInCompleted?
var tween = createjs.Tween.get(this.scene).to({y : 0, x : 0, alpha : 1}, 5000).call(self.menuInCompleted);
}
this.menuInCompleted = function()
{
console.log("menuInCompleted CreditsScreen" );
self.addButtonEventListeners();
}
this.menuOut = function(nextScreen,isNextScreenPopUp)
{
console.log("menuOut CreditsScreen" );
self.removeButtonEventListeners();
if(isNextScreenPopUp == true)
{
self.menuOutCompleted(nextScreen,isNextScreenPopUp);
}
else
{
//problematic part with menuInCompleted?
var tweenSplash = createjs.Tween.get(this.scene).to({alpha : 0}, 5000).call(menuOutCompleted(nextScreen,isNextScreenPopUp));
}
}
this.menuOutCompleted = function(nextScreen,isNextScreenPopUp)
{
console.log("menuOutCompleted CreditsScreen" );
if (isNextScreenPopUp)
{
}
else
{
stage.removeChild(this.scene);
this.scene.x = 0;
this.scene.y = 0;
this.scene.alpha = 1;
}
changeMenu(nextScreen, this.name, isNextScreenPopUp, true);
}
Ok. I solved the problem. Itis my call function. I send the parameters like menuoutcompleted(a,b) but in tween structure it must be (menuoutCompleted,[a,b]).
Now, It works :)

objects in an array alerted randomly

I have built this code using javascript that makes a few objects called monster. I then put those monsters in an array and finally am trying to call one of thous monsters to the console randomly. Unfortunately it displays in my console log as undefined. Any advice on how to get a random monster in the console log every time I refresh the page?
function Monster(type, level, mAttack, mAgility, mHP) {
this.type = type;
this.level = level;
this.mAttack = mAttack;
this.mAgility = mAgility;
this.mHP = mHP;
}
Monster.prototype.logInfo = function() {
console.log("I am a : ", this.type);
console.log("I am level : ", this.level);
console.log("I have the attack of : ", this.mAttack);
console.log("I have the agility : ", this.mAgility);
console.log("I have the health : ", this.mHP);
}
var troll = new Monster("troll", 1, 10, 10, 10);
var skeleton = new Monster("skeleton", 1, 10, 10, 10);
var slime = new Monster("slime", 1, 10, 10);
var boar = new Monster("boat", 1, 10, 10);
var monsterList = new Array();
monsterList[0] = troll;
monsterList[1] = skeleton;
monsterList[3] = slime;
monsterList[4] = boar;
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
console.log(monsterSummoner);
You create a function but never call it. Therefor monsterSummoner is never set.
// THIS IS NEVER CALLED
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
console.log(monsterSummoner);
Try this instead. Notice that now that the function is called the value is set.
var monsterSummoner;
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
}
summonRandomMonster();
console.log(monsterSummoner);
You're close... Change your last four lines as follows -
var monsterList = [troll,skeleton,slime,boar];
var summonRandomMonster = function (){
monsterSummoner = monsterList[Math.floor(Math.random() * monsterList.length)];
console.log(monsterSummoner);
}
for (var i = 0; i < 100; i++) {
summonRandomMonster();
}
There are atleast two problems in this code. The variable "monsterSummoner" is not defined, and the function "summonRandomMonster" is not called.

javascript game: why return init: init?

I'm following a tutorial on how to make a javascript game, but i'm stuck on the return part. Why are is there { }, and what is the init: init for? Any help would be appreciated. Thanks.
var JS_SNAKE = {};
JS_SNAKE.game = (function () {
var ctx;
var xPosition = 0;
var yPosition = 0;
var frameLength = 500; //new frame every 0.5 seconds
function init() {
$('body').append('<canvas id="jsSnake">');
var $canvas = $('#jsSnake');
$canvas.attr('width', 100);
$canvas.attr('height', 100);
var canvas = $canvas[0];
ctx = canvas.getContext('2d');
gameLoop();
}
function gameLoop() {
xPosition += 2;
yPosition += 4;
ctx.clearRect(0, 0, 100, 100); //clear the canvas
ctx.fillStyle = '#fe57a1';
ctx.fillRect(xPosition, yPosition, 30, 50); //a moving rect
setTimeout(gameLoop, frameLength); //do it all again
}
return {
init: init
};
})();
$(document).ready(function () {
JS_SNAKE.game.init();
});
The {} is an object literal in JavaScript. The statement
return {
init: init
}
returns an object with one property. That property's key is init and value is whatever value the variable named init has (in this case, a function).
In case that syntax is confusing, this is equivalent and might be clearer:
JS_SNAKE.game = (function () {
// snip...
function performInitialization() {
// snip...
}
// snip ...
return {
init: performInitialization
};
})();
That is something that is called a module pattern - where you enclose your "class" (or represent it, if you will) with an anonymous function.
The function returns the JS object that can be used to access "class" methods and variables, but only those that are exposed (public) - such as init.
{} is object literal - it is used here to declare an empty JS_SNAKE object - which will serve as a namespace for the following "class" declaration.

Categories

Resources