patternjavascriptModerate
"Star Catcher" game
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
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
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:
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
I had two things in mind:
This time, my code consisted of:
and when I wanted the game to end, I just used your end game function:
Your code has a
Like I said above, I would place limitations on the
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:
I would consider other forms of animation tracking than
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
bucketPosvariable, but I'm sure I could work around that with the next method, if I tried)
- Reset the
starsFallenvariable 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();
});
}
});debuggerYour 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()setTimeoutI 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.