Declaring a Phaser game collisionHandler callback with Node(?) syntax - javascript

I'm used to vanilla JavaScript syntax for building simple Phaser games, but I've been using this Yeoman generator, which changes the syntax to something new that I'm not familiar with. I'm honestly not sure how to describe it, but basically instead of create the usual create, update, etc functions like this:
function update() {
game.physics.arcade.collide(sprite1, sprite2, collisionHandler, null, this);
}
It's defined like this:
exports.update = function(game) {
game.physics.arcade.collide(sprite1, sprite2, collisionHandler, null, this);
}
The 3rd argument collisionHandler is a custom collision handler, which if I was using the first syntax style, I'd just create it using something like this:
function collisionHandler (sprite1, sprite2) {
game.stage.backgroundColor = '#ffffff';
}
I honestly don't know how to declare it using this new syntax i.e. the second example above e.g. exports.update = function(game). I've tried various definitions similar to this for the collisionHandler() function, but they've all been wrong.
QUESTIONS
Can someone tell me the correct way to declare that collision handler in the second syntax/style?
Can someone share a great link that'll best explain this syntax?
I've got basic JavaScript coding down, but I have no experience with Node/Yeoman/etc, so I'm sure that's most of the problem :)
If you're not familiar with Phaser, here's some example code using https://phaser.io/examples/v2/arcade-physics/vertical-collision.
TIA!

Related

Javascript function is undefined only in IE11

I'm trying to use a template but just realized that the javascript doesn't work at all in IE.
It fails in several places but here is the first one:
I have this tag, immediately before my </html>:
<script>
document.addEventListener("DOMContentLoaded", function (event) {
navbarToggleSidebar();
navActivePage();
});
</script>
The exception says, "0x800a1391 - JavaScript runtime error: 'navbarToggleSidebar' is undefined occurred"
The javascript file that came with this template was minimized as uses some cracy javascript markup that I've never seen and do not understand. But when I do a find in the whole solution for navbarToggleSidebar I only find this:
JkW7: function (t, e, n) {
"use strict";
Object.defineProperty(e, "__esModule", {
value: !0
});
var i = (n("PExH"), n("juYr"), n("6wzU"), n("e9iq"), n("aWFY"));
! function (t) {
t.keys().map(t)
}(n("pax0")), Object.assign(window, {
masonryBuild: i.a,
navbarToggleSidebar: i.c,
navActivePage: i.b
})
},
I can post the whole file somewhere (just tell me where, it's too long to paste here) if that's helpful because this is clearly just a piece of a huge js thing that I don't understand at all. I like to think I'm fairly decent with js and jquery and this looks greek to me. And it all works beautifully in Chrome and FF.
Can anyone help me figure out what's going on?
Thanks!!
Well n is a callback function t is an array or a list of some kind most likely; so in order for you to figure out what is actually happening in the function you have to figure out where the function was actually invoked. It is much easier to find out what library was used and see if it is hosted anywhere in a non-minified version.
Sometimes this is done intentionally in order to protect developers from other people having an easy time engineering their solutions to programming problems.
Basically in order for anyone to figure out what the function actually does, you would have to print the entire page library, then trace through it, then when you are done after about a month you will have your answer.
Arrays, callback functions, as well as a probably system variable and object literals are used in that function.

JavaScript - how to use Setters and Getters in to create a listener

Before this gets marked as a duplicate: I have read posts all day about this so I know there are tons of similar questions on SO but none that I've seen so far go into the details that I need to understand.
Having said that, there are no good commented examples of how the process works. Could someone answer the following question with well a well-commented example so I could finally understand this ability?
I have a function that I want to call in one file but I need to make sure that another event in another file has already happened before I call it. These files have no connection (one is an angular 2 TypeScript file that starts the app and the other is a JS file that manages a hopscotch tour). I understand that I will need to use a global variable and I believe that the best solution I've read is going to involve using setters and getters. All examples I've seen of this seem to assume that it's just intuitive and leave out the part where I get to understand how it's working. Maybe it is intuitive but I'm not making the leap yet.
Global variable in TypeScript file:
global_variable = false;
Function I want to call in JavaScript file based on the listener:
function call_if_other_function_finishes() {
if (global_variable === true) { // I have the global already created
// run hopscotch tour
}
} // how do I turn this into a listener?
The function I need to have finished first in TypeScript file:
function someFunction() {
// run its code
GlobalFile.global_variable = true; // Should trigger the listener.
}
Thanks in advance!!
One solution is to just define the function as you do in your example and then run it when you need it:
function someFunction() {
// run its code
call_if_other_function_finishes() // it's globally defined anyway
}

How to add custom function to call after document.getElementById?

I'm just curious, how can I call a custom function after document.getElementById()? Something like this:
document.getElementById("element").mycustomfunction();
Technically you can do this :
Element.prototype.mycustomfunction = function() {
console.log("I don't work on IE7");
};
You can test it easily in your console on this page : type it first and then document.getElementById("notify-container").mycustomfunction();.
It works. There's not technical problem with it. But it might make it a little harder for maintainers of your applications to trace what happens, it might led to collisions with other plugins doing the same, and it doesn't really add a lot over myPlugin.doSomething(element).

Starting with RequireJS, communication between modules

I am an ActionScript 3 developer who is just making his first way in building a large-scale JavaScript app.
So I understand modules and understand that AMD is a good pattern to use. I read about RequireJS and implemented it. However, what I still don't understand is how to achieve Cross-Module communication. I understand that there should be some kind of mediator...
I read articles and posts and still couldn't understand how to implement it simply.
Here is my code, simplified:
main.js
require(["Player", "AssetsManager"], function (player, manager) {
player.loadXML();
});
Player.js
define(function () {
function parseXml(xml)
{
// NOW HERE IS THE PROBLEM -- how do I call AssetsManager from here???
AssetsManager.queueDownload($(xml).find("prop").text());
}
return {
loadXML: function () {
//FUNCTION TO LOAD THE XML HERE, WHEN LOADED CALL parseXml(xml)
}
}
});
AssetsManager.js
define(function () {
var arrDownloadQueue = [];
return {
queueDownload: function(path) {
arrDownloadQueue.push(path);
}
}
});
Any "for dummies" help will be appreciated :)
Thank you.
To load up modules from another modules that you define(), you would simply set the first parameter as an array, with your module names in it. So let's say, in your code, you wanted to load Player.js into AssetsManager.js, you would simply include the string Player in the array.
This is simply possible because define's abstract implementation is equivalent to require, only that the callback passed to define expects a value to be returned, and that it will add a "module" to a list of dependencies that you can load up.
AssetsManager.js
define(['Player'], function (player) {
//... Your code.
});
However, if I can add to it, I personally prefer the use of require inside of the callback passed to define to grab the dependency that you want to load, instead of passing parameter to the callback.
So here's my suggestion:
define(['Player'], function () {
var player = require('Player');
});
And this is because it's much more in tune with CommonJS.
And this is how main.js would look like formatted to be more CommonJS-friendly:
require(["Player", "AssetsManager"], function () {
var player = require('Player');
var manager = require('AssetsManager');
player.loadXML();
});
But the CommonJS way of doing things is just a personal preference. My rationale for it is that the order in which you input the dependency names in the array might change at any time, and i wouldn't want to have to step through both the array and the parameters list.
Another rationale of mine (though, it's just pedantic), is that I come from the world of Node.js, where modules are loaded via require().
But it's up to you.
(This would be a reply to skizeey's answer, but I don't have enough reputation for that)
Another way of solving this problem without pulling in Player's AssetManager dependency via require is to pass the AssetManager instance that main.js already has around. One way of accomplishing this might be to make Player's loadXML function accept an AssetManager parameter that then gets passed to parseXml, which then uses it. Another way might be for Player to have a variable to hold an AssetManager which gets read by parseXml. It could be set directly or a function to store an AssetManager in the variable could be used, called say, setAssetManager. This latter way has an extra consideration though - you then need to handle the case of that variable not being set before calling loadXml. This concept is generally called "dependency injection".
To be clear I'm not advising this over using AMD to load it in. I just wanted to provide you with more options; perhaps this technique may come in handier for you when solving another problem, or may help somebody else. :)

jquery tmpl in a closure

i am working on this little javascript library and following various suggestions i am wrapping my functionality in a closure for the various reasons (encapsulation of variables, hidding of code and so on). since I query a JSON webservice and display the results I also use the jquery tmpl engine.
I think I understand what closures are good for but I sure don't understand them in general. meaning I get totally lost between all those scope changes and whatnot. especially annoying is this exception I get. consider the following code (a simplified ugly version of the code in question, but it reproduces the problem)
// something would be the object that handles all the library functionality
var something = function(){
// creating a local function that goes as a parameter into the Array.filter
function isBar(data){
return data.name === "bar";
}
// the template code
var bla = "<h1>${name}<\h1><h2>${attribute.filter(isBar)[0].value}</h2>";
// precompiling the the template
$.template("test", bla);
// and returning a function that should render the template with the provided data
return {
funny: function(){
$.tmpl("test", [{"name":"Fo", "attribute":[{"name":"bar", "value":"how"}]},
{"name":"Foo", "attribute":[{"name":"fnord","value":"can"}]},
{"name":"Fooo", "attribute":[{"name":"bar","value":"this"}]},
{"name":"Foooo", "attribute":[{"name":"Bar", "value":"be"}]}
]);
}
}
}();
// calling the function
something.funny();
So when calling the something.funny() I would the following expect to happen: the function funny, being a closure gets called in its original context (e.g. the function isBar and the variable bar are defined). So when I call $.tmpl I hoped that attribute.filter(isBar) within the template would also be in this scope. but it isn't. I Chrome i get ReferenceError: isBar is not defined.
If someone would be so nice to show me the error of my ways I would be very happy.
edit oops I missed the "()".
OK, well the problem is that those references to the local variables in the closure are not really references to local variables - they're part of a string. The template code has to parse that string, so when it does that the fact that there was a function called "isBar()" in the closure from where "$.tmpl()" was called really doesn't matter; jQuery can't access them because you just can't do that in JavaScript.
You can, however, pass in an "options" third parameter to "$.tmpl()" and provide extra stuff there. I'm not 100% sure how to do it as I've only played with the template plugin a little bit, but I'll try a jsfiddle when I have a chance. I think that you'd basically do something like this:
funny: function(){
$.tmpl("test", [{"name":"Fo", "attribute":[{"name":"bar", "value":"how"}]},
{"name":"Foo", "attribute":[{"name":"fnord","value":"can"}]},
{"name":"Fooo", "attribute":[{"name":"bar","value":"this"}]},
{"name":"Foooo", "attribute":[{"name":"Bar", "value":"be"}]}
], { isBar: isBar });
}
What I'm not sure of is whether you refer to that as "${isBar()}" or "${item.isBar()}" inside the template text.

Categories

Resources