Jump to content

TypeScript vs JavaScript?


ScottyFillups
 Share

Recommended Posts

My experience with TypeScript couldn't be better.

I'm completely satisfied with results.

@Tom Atom

gave many excellent reasons for using it. Of course it's not a silver bullet that will assure your code will be the  best one. It's developers' duty to create correct code.

But a good tool can save you a lot of headache .

What do you want? To make a game or keep debugging JavaScript code to discover where you messed up with a variable or, with the this context ?

But in the end , it's more a matter of personal preferences, so don't take anyone advises.

Give TypeScript a try. See how you feel about it. Then try  plain JavaScript .

Create a simple games, extend some sprites to include some functionalities...

That'sthe best way for you to pick the right tool for yourself.

Link to comment
Share on other sites

On 06/12/2016 at 9:28 PM, plicatibu said:

Give TypeScript a try. See how you feel about it. Then try  plain JavaScript

Wrong way round for me, learn your language first before deciding to extend it, same can be said of using Babel (but at least here you should be using stuff that will become the language) and even jQuery.

I know a number of devs (and have interviewed even more) who learnt jQuery, not specifically JS, and, of course, their knowledge of the basics is poor which hinders them learning different libraries/frameworks (although they were pretty productive for a while back there, despite lack of basics). On the flip side, I haven't seen or heard of any case where a dev has really strong knowledge of JS and they struggle to pick up anything JS-related, and that includes TS which adds language features that would be unknown to a JS-only person.

I sound like I'm bashing TS maybe too hard, I actually prefer strongly typed languages and I'm from a C and C++ background, I just don't think it's helpful for JS and I haven't heard many success stories that aren't littered with pain using it (every proper success takes some pain though so choose your own poison), infact I haven't heard of any success stories where devs extolled TS for increasing their productivity (not true of Haxe where successes abound) but I'd have thought there would be some, its been around for long enough.

Learn your language first, then think about extending it. Your future self will thank you for this delay in using the latest new and shiny (there's a thing here, if your new and shiny is actually any good it'll still be there for you, most will have faded away so you won't be upset about having missed that trend).

Link to comment
Share on other sites

On 05/12/2016 at 7:51 PM, Tom Atom said:

It should be... reason, why you get output like this:


{game: b.Game, add: b.GameObjectFactory, make: b.GameObjectCreator, camera: b.Camera, cache: b.Cache…}

is hidden inside Phaser.StateManager. What it does is, that it calls link function on any passed "state" object. I put state into quotes, as you can pass instance of state, class name or any object. It is first processed and if you passed for example class name, then new instance is created on behalf of you (see add function of StateManager: https://github.com/photonstorm/phaser/blob/master/v2/src/core/StateManager.js#L193)

 Then, when your state object (created in any way) is set as current, StateManager calls link function on it (https://github.com/photonstorm/phaser/blob/master/v2/src/core/StateManager.js#L459). It adds lot of properties to it - all the shortcuts, that enable you later to write simply this.add, this.tweens, this.rnd, ... Btw, first few added properties are those in this listing {game: b.Game, add: b.GameObjectFactory, make: b.GameObjectCreator, camera: b.Camera, cache: b.Cache…}.

 Minimal link would be only game for referencing parent game. But then, you would loose all shortcuts and would have to write this.game.add, this.game.camera. Some people do it like this, but writing this.add or this.camera is shorter and more convenient.

I agree its convenient but its also unexpected and in the case of the original poster its caused a confusion, which I think is a totally reasonable confusion given the following code:

class MySuperGame {
  constructor() {
    this.game = new Phaser.Game( 800, 600, Phaser.AUTO, 'content', {
      preload: this.preload, 
      create: this.create 
    });
  }

  preload() {}

  create() {
    this.game.time.events.loop(1000, this.createEnemy, this);
  }  

  createEnemy() {
    // create and add enemy sprite here
  }  
}

This is just passing functions around, to be invoked by a 'master' object (in this case the new Phaser.Game) some time in the future. Given that `create` is a member of `MySuperGame` its not a huge jump to assume it will be invoked with that scope, and my point is that it is unexpected that it is not. There are cases, like event emitters, where there are well-defined expectations that scope will change (much to the chagrin of any classical dev) but this is not one of those cases.

Without good knowledge of Phaser, the output of the following bit of code is also a little unclear:

class MySuperGame extends Phaser.Game {
  constructor () {
    super(800, 600, Phaser.AUTO, 'content', {
      create: this.create
    })
  }

  create() {
    this.game.time.events.loop(1000, this.createEnemy, this);
  }  

  createEnemy() {
    // create and add enemy sprite here
  }  
}

Now what does the scope come when `create` gets invoked? I've no idea. I'd assume as MySuperGame now is an instance of Phaser.Game (as much as JS allows that) that `this.game` could be omitted in preference of `this.time.events...` but given our earlier jsfiddle play it looks like `this.game` might well exist because `MySuperGame.create` gets called in the scope of the state object that has been invisibly created for you, meaning it no longer has access to `this.createEnemy` because `this` is not `MySuperGame`, (although, I'm wrong here aren't I because the link function extends the object rather than replacing it, I just need to be careful with my own property names and I should be gucci, possibly, maybe...).

This is all fun and games but if anyone seriously enjoys this mess of OOP and scoping then I think there must be something a little odd about them! I'm being flippant and I apologise but I think this example perfectly highlights some of the pitfalls of inheritance and OOP. This short series of posts are a good read for anyone interested about why things become tricky when you write code like this.

I think @Tom Atom pattern of using `Phaser.State` to define states is a good idea, but, surely, due to that link function its redundant to do this because anything contained within Phaser.State is going to be copied over when that state is passed to the Game constructor, meaning that extending using Phaser.State is only a useful pattern because it makes explicit (nearly) what the state lifecycle functions should be called with.

Link to comment
Share on other sites

Thank you mattstyles and Tom Atom for the nice discussion. My experience with javascript is mainly a lot of jQuery code so both Typescript and more complex javascript understanding (which has recently surfaced) is limited. Coming from a C# and Java world the way one work with member variables generally works nice as a container and where the understanding of "this" is pretty well defined. Not so with JS - which has now started to dawn on me. There are lots of pages trying to explain this and I am sure its all very good once I get the hang of it with some experience.

I agree with mattstyles that my problem was simply the way I was fooled by the function pointers when passing it to the Phaser.Game but then seeing it not work the same way when I did the same to a function within Phaser (timer.events.add). I have since encountered the same issues in work related use of Typescript so I see this is just something I need to learn to do right. The ".bind(this)" behind the function makes some sense as it creates a readable piece of code that explains what has been set as the functions context. The other example using the "= () => { .. }" , although getting rid of the bind, is actually less readable for me as I sort of like functions to look alike within a "class" context.

Again thank you mattstyles and Tom Atom for showing the examples and the discussion - it has cleared up some things. And I will definitely try the extending of Game and using State as I like this way of splitting up functionality. The main reason for wanting to use Typescript is to arrange my code in some kind of "objects" so I can extend classes and give each of them behaviours that way.

A bit off topic, but are there any good tutorials how to make native builds using Phaser? I can see wanting to do at least Android, iOS and Windows builds for any Phaser game project I do. I had troubles finding a good howto on the Phaser site. I am used to working with ionic2 and there it is rather simple ("ionic build android" and even "ionic run android --device" for deploying directly). It would be good if there were similar simple CLI's  for packaging Phaser game projects to different platforms.

Link to comment
Share on other sites

Ionic commands are just a wrapper around their own build system (which was gulp, I think they wanted to change to webpack but they may have backed out of that now as it wasn't working how they wanted, in any case, its a build system that turns many JS modules into one JS bundle) and Cordova, but even if you remove Ionic the process is the same for Cordova, i.e. bundle your JS using whatever bundler you want and then run the Cordova build using that bundle. Cordova then wraps that bundle up with the JS execution (which is just a webview pointing to a local resource) and creates a bundle for your target OS.

The whole Cordova project can be a little daunting (I'm not even sure Ionic 2 is using the latest versions) and many of the modules refuse to work quite as advertised, however, the documentation is now far more approachable and if you can get your head around creating a JS bundle and then an App bundle then you should be golden. Note that if you're targeting iOS you'll need a mac (or access to a mac build machine, some services can provide that but they aren't cheap) and a developer license to actually ship anything and be prepared for the potential of a little to-and-fro with the App Store if you want to ship it there.

Although none of the Cordova examples use Phaser the process is the same, create a JS bundle then use Cordova to create an app bundle for your target OS.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...