HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

"Star Catcher" game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gamecatcherstar

Problem

For fun, I have been working on this game I called Star Catcher. It's a very basic game where stars are falling and you try to catch as many of them in your bucket before you miss 10. It's a real mess of code that I just threw into one file, basically. The animations seem to be working fairly smooth for me on my computer.

How can I improve the smoothness of the animations on mobile? Something I have noticed is that when I just leave the stars to fall without moving the bucket by touch dragging, it seems to be very smooth. I started with the animations using jQuery animate and using the step function to check for star, bucket collisions. I then compared adding velocity.js, transit.js and gsap's jQuery plugin to see if that would help. I also compared having a full screen canvas that the stars were painted to, bucket as is DOM and then stars and bucket both painted on canvas.

I ended up going with gsap. No canvas and checking for collisions using requestAnimationFrame, but still running into this issue of moving the bucket and the stars looking choppy only on my phone. Any ideas? Do you think converting the gsap animations from their jQuery plugin to their tweenmax or whatever would help? I've had similar issues with past projects (circlebattle.com). I did have plans to use cordova to convert -> app blah blah blah but as is the games potential for mobile is being held back. I understand that many are going to say you have to develop the app natively for it to really be responsive, but really? The game is very simple. Yes, it is a bit DOM-intensive with each star being its own element, but it seems like my phone should be able to handle this simplistic of game better. On my todo list is networking it so players can pair up and one person drop stars down and the other tries to catch them.

If you have any other ideas to improve the game in general, I am also open.

```
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window

Solution

Your code is good, but you have one massive oversight:

It's hackable.

Your code shouldn't be accessable from the Console. I would recommend using getters and setters to limit incorrect addition:

var protectedScore = 0; //abstracted away where it cannot publicly be reached

GameClass.__defineSetter__("score", function(scoreToSet){
    if (scoreToSet != protectedScore + 1){
        protectedScore -= 50; //Cheaters' Penality
        return;
    }
    protectedScore++
}


Or something similar.

Hacked Version 2

You updated your code on the website (although it still applies to the code above), so I figured I'd give it a second go:

After you patched the simple starsCaught = 1e10 hack, I had to get a little more clever.

I had two things in mind:

  • Make the bucket width 100%, so every star would hit it. (Thwarted by the bucketPos variable, but I'm sure I could work around that with the next method, if I tried)



  • Reset the starsFallen variable so that I could just simply play the game without possibility of losing.



This time, my code consisted of:

window.cheat = function(){ window.starsFallen = 0 }
setInterval(window.cheat, 500)


and when I wanted the game to end, I just used your end game function:

endOfGame(function() {
      if (starsCaught > userObj.starsCaught) {
        // mess, fadespeed, delay, displaylength, cb)
        displayMessage('congrats - new personal best!' + starsCaught + ' stars caught before 10 misses!', 'slow', 20, 3000, function() {
          showHighScores();
        });
        mySocket.emit('sendScore', {
          username: userObj.username,
          handshake: userObj.handshake,
          starsCaught: starsCaught
        });
      } else {
        displayMessage('stars caught before 10 misses...' + starsCaught, 'slow', 20, 3000, function() {
          showHighScores();
        });
      }
    });


debugger

Your code has a debugger call in the forEach loop, I would remove this from production code on your website. It's test-code at best.

starsFallen:

Like I said above, I would place limitations on the starsFallen variable that means it cannot be decremented, only incremented. Otherwise a simple interval hack is possible.

Making your variables & functions public

For games like this, it's better to have the JavaScript stored in an external file and minified/obfuscated. That would at least stop script kiddies (and probably even me)

Consider hosting the sensitive game logic on your server, and simply have the client make sockets calls like: starCaught()

setTimeout

I would consider other forms of animation tracking than setTimeout, as assigning lots and lots of time based function callbacks would seriously kill performance.

Code Snippets

var protectedScore = 0; //abstracted away where it cannot publicly be reached

GameClass.__defineSetter__("score", function(scoreToSet){
    if (scoreToSet != protectedScore + 1){
        protectedScore -= 50; //Cheaters' Penality
        return;
    }
    protectedScore++
}
window.cheat = function(){ window.starsFallen = 0 }
setInterval(window.cheat, 500)
endOfGame(function() {
      if (starsCaught > userObj.starsCaught) {
        // mess, fadespeed, delay, displaylength, cb)
        displayMessage('congrats - new personal best!<br>' + starsCaught + ' stars caught before 10 misses!', 'slow', 20, 3000, function() {
          showHighScores();
        });
        mySocket.emit('sendScore', {
          username: userObj.username,
          handshake: userObj.handshake,
          starsCaught: starsCaught
        });
      } else {
        displayMessage('stars caught before 10 misses...' + starsCaught, 'slow', 20, 3000, function() {
          showHighScores();
        });
      }
    });

Context

StackExchange Code Review Q#117455, answer score: 11

Revisions (0)

No revisions yet.