My very first Chrome experiment
I've never worked with the new <canvas> element of HTML5 so I played with it and created a really really simple game at the weekend. Normally, I don't share such experiments, but maybe you can find something useful in it.
Let's start with the basic rules of the game. You control a red circle with your mouse on a yellow court and have to catch a red rectangle. This is quite simple, but you must not hit one of the gray circles. The number of gray balls increases with every new catch. By a simple click you can inverse the direction of all balls - which is sometimes helpful if you urged in the top left corner for example.
If you're just interested in playing the game and use already one of the modern browsers like Firefox 3.6, Opera 10.6 or Chrome click to play the game.
For all others who are interested in the mathematical background of this game should continue reading. Moving the balls should be clear, so I focus on the hittest, which is not so trivial in JavaScript. My first idea to detect a hit with another point was checking the distance of these two points. This can be done by using the sum of both radii as the smallest possible distance between two circles. Geometrically this can be conceive by the following:
This is quite simple by using the Pythagoras to determine the distance. But the problem with Pythagoras is, that we need 2 powers and one square root in the equation, which will slow down the whole thing if there are 100 flying balls and 50 calculations per second.
A much better idea would be to approximate it for the first step. So I sketched a hair cross in my mind over the scene like this:
Okay, let's dig a little deeper. I decided to make the flying balls half size of the big ball attached to the mouse, which allows us to safe one addition, because we can use the coordinate directly instead of using the right border offset (as the small ball fits in the first half of the big circle):
Now we can describe the matching condition with
(m.x <= b.x-5 <= m.x+10 OR m.x-10 <= b.x+5 <= m.x+10)
which can be better expressed by
(m.x+5 <= b.x <= m.x+15 OR m.x-15 <= b.x <= m.x+5)
Now it's possible to simplify the expression to
(b.x <= m.x+15 AND m.x <= b.x+15)
which is our final check if we hit a point at the x-axis. If the condition is true for any point, we can use the slow distance formula to make a more precise decision:
(m.x-b.x)*(m.x-b.x)+(m.y-b.y)*(m.y-b.y) == (m.radius+b.radius)*(m.radius+b.radius)
As I used PHP as macro language, everything on the right hand side is substitutable and remains constant in the resulting JavaScript source. I used PHP for every offset calculation to reduce the number of operations on the client. At the end of my work, I also removed some unnecessary functions to avoid function calls.
Update of 06.03.2008:
- New scoring model: the faster you play, the more point's you'll get
- Fixed bug that you loose immediately. It's only possible to loose if you move against a new created barrier which is also directed to you. But this is your fault.
- Fixed bug that you can cheat by pausing movements
BTW: My record is a score of 145; beat this ;-)
You might also be interested in the following
- Calculate the intersection points of two Circles
- Creating an Advent Calendar with HTML5 and CSS3
- People near you with MySQL
- Generate client-side PNG files using JavaScript
Sorry, comments are closed for this article. Contact me if you want to leave a note.
18 Comments on „My very first Chrome experiment”
Sagar,
it's deliberated that you can rest behind the dashed lines or use the area to trick the grey balls.
The software I publish on my blog and github is well tested and even weekend projects are build with diligence.
Robert
Hey, very impressive bro. I wanna take lessons from you.
But I found out a silly loop hole in the game. As it was your weekend experiment, its trivial even to mention it. But..
You can actually go out of the frame and need not worry about the small black balls then sneak in to get the prey safely.
In this way you can score around 350 points.
Thanks for sharing this.
It is a good way to practice mouse (or trackpad) dexterity.
(I am teaching internet to elders.)
Awesome game. I really like the idea.. played some flash games like this. But you've taken the idea to the next level.. good job..
I got high score 180
First, this is an amazing introduction to the Canvas element! I'm trying to learn how to use them, so do you think you could post a commented version of the code? I would really appreciate it. Are you planning on doing anything else with the canvas? Very fun and surprisingly addictive game, btw. :)
Daniel,
thanks for your correction. I meant Chrome 4, but Opera 10.6 is also fitting.
Robert
*nineties
Now I'm making typos!
Slight typo.
You mean Opera 10.6 not 4. That version is from the nighties long before html5.
Lol
Awesome game. I really like the idea.. played some flash games like this. But you've taken the idea to the next level.. good job..
This is one of the best 'computer' games I have ever seen. Its simplicity and cleanness is amazing, as well as the way in which is grows with you.
Hey,
very nice game. Good job. There is just one possible exploit: if you click very often the directions are changed very fast. The result is that the balls do not move very much. This offers a way to move around them quite easily.
Very funny!
Sou Brasileiro e adorei o Game extremamente viciante =D
Nice game. There is one little optimisation you're doing and that you forgot to talk about: you're checking collision only when the mouse moves. However this is also a kinda cheat to the game... because if you feel stuck simply stop moving the mouse and all the gray balls will just pass over you without killing you.
Win! 310 =D
http://img130.imageshack.us/img130/1169/xarg.png
very addictive...
Score of 200. =D
Heheh, high score 180!
Great game! The instant-death-upon-touching-a-square thing is a bit frustrating, but this is one of the most fun games I've played on a browser. Great work!
Hi Rusell,
yes I check the position of the new ball with the following code:
do {
x = Math.random() * 315;
y = Math.random() * 315;
} while(prey.x <= x + 10 && x <= prey.x + 30 && prey.y <= y + 10 && y <= prey.y + 30);
But sometimes I also had the problem that I lost immediately. I'll check this part of the code again.
Do you check that newly placed small balls and squares are placed a reasonable distance away from the large ball? Sometimes I will lose immediately when I touch the square.