I've made no attempts at all at performance tuning yet it runs very nicely in webkit browsers and not too bad in firefox.
While playing I noticed I was able to go faster than my projectile, and I was slightly disappointed when I was unable to damage my own ship that way.
You may also notice the view zooms out as your speed increases, so you have a much wider view
Bugs I noticed: All the bullets in the world sometimes disappear at once. There's no pause button.
Mostly I love the controls, except friction on your ship is a little aggressive -- I think there should be no friction if you're below a certain speed, but maybe it's just my expectations from Star Control 2 (check out the FOSS version, Ur-quan Masters, with sudo apt-get install uqm if you're on an Ubuntu-like system). Also, the game desperately needs a hold-to-fire, or even toggle fire, button. Single-shot fire in a game like this is why there was a thriving turbo controller cottage industry in the '80s - '90s.
Yes, it's a bit hard to see but I haven't really spent any time tuning it - been too busy. Did you nitice the little blue ships that you can shoot to get a token to upgrade your guns? There's red ships that follow you that show up every 30 seconds, and blue ones that contain powerups that show up after (I think) 10k points.
The code appears to be very well-structured and readable, even though it's compiled to JavaScript. IMO, a good example for those learning to use canvas (like myself). Thanks a lot for sharing.
Chrome 28.0.1500.71 on OS X 10.8.4 (map is 54% slower)
Safari 6.0.5 on OS X 10.8.4 (map is 28% slower)
Firefox 23.0 on OS X 10.8.4 (map is 62% slower)*
Opera 12.16 on OS X 10.8.4 (map is 72% slower)
IE 10.0 on Windows 7 [via VirtualBox] (map is 42% slower)
And testing the same via a node.js benchmark it says the fastest is comprehension. https://gist.github.com/Kerrick/cff3d1212c82bc804712
* Every time I load the JSPerf page on Firefox, the first run the two tests are on par, and the second (and following) runs I get map being much slower. I have to wonder if the JS engine begins optimizing the comprehension version at some point.
I write a lot of games and game related things in JavaScript, and this is actually a major reason why I now use CoffeeScript. Nice clean comprehension syntax and better performance.
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I don't ever advise using map, but you can't setup your own for loop in coffeescript. Actually, in the code shown, map isn't used at all. Just .filter and .forEach.
Here is my version: http://jsperf.com/no-coffeescript-orig
The 'manual' is what I would write myself.
Firefox nightly produces an interesting test run: http://cl.ly/image/2s0p1Y3E2Z0C not really sure why that happens.
http://www.dotnetspeaks.com/DisplayArticle.aspx?ID=117 (random site with example)
map is the functional equivalent of what you're trying to do there, not filter.
(number * number for number in nums)
...is inefficient, and that it could've been translated into much more efficient JS than it was.The only thing that's true is that CofeeScript generates some throwaway code because of implicit returns and the "everything is an expression" rule. However, I doubt that they would cause much overhead, specially with modern JS engines optimisation capabilities.
[1]: http://mrale.ph/blog/2011/11/05/the-trap-of-the-performance-...
So, good point.
But I do wonder why we're stuck with all the cruft to let ECMAScript be backwards compatible. Couldn't we just one time introduce a few breaking changes to clean up the mistakes in the language's design?
And if you're really opposed to that, how about the same strict versus transitional semantics we use for HTML? I'd be happy to be writing code in a clean strict subset of JavaScript.
I do agree that the default return behavior is probably a bad idea. It probably came from Ruby, and I can see the appeal, but I've often created bugs by accidentally using the implicit return, then adding something to the end of a function. It's not really that big of a deal - I just as a policy always use an explicit return.
I have found I've been forced to add a dummy `return` at the end of some of my CS methods because of this. It's one of only a very few complaints I have with the language.
Furthermore, as others have noted, your post does smack of premature optimization. Without numbers, most of the claims are all pretty meaningless. Judging by number of instructions is no longer a valid metric on any platform on any level of abstraction and hasn't been since the 1980s.
Really want / need Google Closure / the latest ECMAScript stuff? ClojureScript supports these things pretty well.
Really like Ruby (or Python) but find yourself in Javascript land? Coffeescript is right for you.
There's some interesting buzz around getting Coffescript more Google Closure compliant, which is probably the better way to go (assuming your targeting front end JS, not Node).
But yes, there are certainly places where Coffeescript generates a crap-ton of code, where if you can pinpoint your Javascript runtime (like in Node's case) you could do more, better, and faster.
Yes, I do have to give some credits to putting the number x number directly into the push call
Are they really suggesting
_results.push(number * number);
is significantly faster than, say var result = number * number;
_results.push(result);
Because it's not.Though I do wonder why CoffeeScript doesn't do something like this to avoid the function call:
_results[_i] = number * number;