While trying to publish Pocket Pool (http://www.alejandroquarto.com/wp-content/test/pocketPool_v3.html), I had some time to play a big ammount of webgames. I was surprissed when i saw that one of the most played games at MochiAds is Bloons. This game, is the top one at mochiads ranks, and also is online for playing in a lot of game sites and portals.
First impression is that Bloons is a really simple game, and it is in fact. Also is highly addictive, and is so easy to get stuck at higher levels.
The aim of this tutorial is to introduce the main gameplay feature of Bloons to be able to create new games.
I have to say, is really easy to create a “clon”, but is not my goal, people will not play a bad copy, will play Bloons. The only thing you can do here if you want to monetize a game like Bloons, is just to add new features, gameplay improvements, powerups, etc, and the most important thing: do something creative and original with the game concept.
Starting with the game
The only things you need here, is Flash 8 at least, some experience with ActionScript 2.0, and some art assets.
In this first part, we will cover the arm moving, the shooting, and the “dart” or “arrow” behaviour. Next part will cover the bloons and collisions.
We will use just 5 movieclips. Look at the picture
The first one is the background movieclip. Is important cos, user will use it to click the mouse button. You can draw what ever you want, or just draw a transparent square. Once you have the movie, place it in the root, and put “backgroundMc” instance name in the properties inspector. (Remember to remove the quotes).
Once you have the background, let’s start with the character. In my case, a bad copy of a playmobil toy. Draw something, but be care about the arm: we need it to be another movie inside the character, cos we are going to rotate the arm.
When you get the character, place it in the root, enter to be able to create the arm movieClip and give it an instance name of “arm”. Look the following picture, don’t worry about the arrow yet.
Ok, you have the character movie, the arm movie inside the character. Now is time to create the arrow movie. We will use it to set the shoot power. All you have to do is to enter in the arm movie, and draw a white arrow like the picture adove. Transform the draw into a movielclip (arrow) and give it an instance name of “arrowMc”. You should get something like this:
The arrow mc, will contain 2 frames. First one, white if you want, will only show the arm orientation.
Add an stop() at this frame.
Second frame will contain the active arrow when setting the shooting power. We will enlarge and reduce this arrow´s size.
Note that arrow is aligned at the right, cos when we change the size, we don’t want to move it.
Last movieclip is the dart. I used a sort of mouse pointer. draw it, transform it into a moviclip, and select an identifier in the dialog box: in our example just “dart” (without quotes).
Don’t leave the dart in the stage, we are going to attach it.
Ok, you have all the art assets, and you are ready to start writing code.
The code
We will use two main places to write code.
1- _root: here we will define all the arm and shooting behaviour.
2- dart movieclip: here is the place to define the dart behabiour.
1- The root code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | initialArrowWidth = char.arm.arrowMc._width;canShoot = true;this.onEnterFrame = function() { char.arm._rotation = (Math.atan2(_root._ymouse-(char._y+char.arm._y), _root._xmouse-(char._x+char.arm._x))*180/Math.PI); if (setPower == true) { powerCount += 5; char.arm.arrowMc._width += (Math.sin(powerCount/180*Math.PI)*3); } };function shoot(angle, power) { _root.attachMovie("dart","myDart",_root.getNextHighestDepth(),{power:power, angle:angle, _x:char._x+char.arm._x+(30*Math.cos(char.arm._rotation/180*Math.PI)), _y:char._y+char.arm._y+(30*Math.sin(char.arm._rotation/180*Math.PI))}); } backgroundMc.onPress = function() { if (canShoot == true) { char.arm.arrowMc.gotoAndStop(2); setPower = true; powerCount = 0; } }; backgroundMc.onRelease = function() { if (canShoot == true && setPower == true) { canShoot = false; setPower = false; power = (-30+char.arm.arrowMc._width)/8; char.arm.arrowMc.gotoAndStop(1); angle = char.arm._rotation; shoot(angle,power); powerCount = 0; char.arm.arrowMc._width = initialArrowWidth; } }; |
First line is a variable to store the initial width of the arrow, since we are going to enlarge it, is good to know its original size for the next shoot.
Second line, is a flag to know when we can shoot. While a dart is moving, you can not shoot. Initially since there is no darts, you can (true)
Then we have an “onEnterFrame” event. We have to update constantly the arm rotation acording to the mouse pointer. First line in this event is the rotation of the arm. By using the atan2, you can get the exact angle between two points: the arm, and the mouse cursor. You only have to send both points as parameter. Good thing about this function is that you don’t have to take care about the quadrant.
After the angle definition, there is an “if” with the setPower flag. While the user is pressing the mouse button, we need to update the arrow size to give the user some feedback about the shoot power. If you don’t know, the sin or cos function are great to increase and decrease a value, cos its shape. By using a counter, we reduce and increase the arrow size with the sin function. Note that the “3″ in the code is just a parameter, if you increase that value, you will get a bigger arrow and viceversa.
That’s all in the “onEnterFrame”. Next function is the shoot. We are basically attaching a dart in the stage, using the angle and power parameter. Initial position seems a bit complex, but im just using polar coordinates to get the arrow near to the arm. We also set an initial power and angle variable inside the dart.
When the user press the mouse button on the background, if there isn’t a dart on the screen, we move the arrow to the frame 2, set the setPower var to true, and also the powerCount to 0.
When the user releases the mouse button, we should shoot the dart. We define the power from the arrow’s width, same thing with the angle, and we need to set all the flags again to their correct value. Don’t forget to move the arrow to the second frame. We are ready to call the shoot function.
2 - Ok, so far the only thing missing is the dart movement. Enter in the dart MovieClip, by clicking in the movie at the library.
This is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | _rotation = angle;gravity = 1; idUpdate = setInterval(update, 10); mc = this; function update() { xant = _x; yant = _y; _x += Math.cos(angle/180*Math.PI)*power; _y += gravity+Math.sin(angle/180*Math.PI)*power; power*=0.99 gravity *= 1.04; _rotation = Math.atan2(_y-yant, _x-xant)*180/Math.PI; if (_y>Stage.height+100) { clearInterval(idUpdate); _parent.canShoot = true; mc.removeMovieClip(); } } |
Initial lines are the initial angle setup, initial gravity acceleration, an interval function, and a reference for our movie.
The interval usage instead the enterframe, is to be able to check collisions with bloons along little intervals of time, without changing the FPS.
setInterval method calls the update() function.
Update function is the more important here. We store the last position before updating, cos we are going to use it for the dart angle. Then, we move the dart along the X and Y by using the cos and sin function. Note that we add the gravity acceleration inside the Y movement. Since we are using Polar coordinates, we can’t forget the modulus, in our case the power var. That’s why we multiply by power var in both axis.
Power needs to be reduced along time, and gravity needs to be increased. This is really a trick to avoid air resistence, this is not a real simulation.
Finally we set the dart angle by using the actual and the last position. By using the atan2 method like we did with the arm, we get the correct angle. Then we just check if the dart is out of the stage, if it is out, we remove it.
Example:
That’s all for now!
Stay tunned for the Part 2
Source code:
Cheers!
7 Responses to “Create a game like Bloons - Part 1”
Leave a Reply
You must be logged in to post a comment.

January 8th, 2008 at 11:58 am
buena idea! pero la fisica esta rara, deberia producir una parabola y esta haciendo una caida muy fuerte. prueba esto:
– inicial
gravity = 2
velY = -20
velX = 30
friccion = .95
– enterframe
velY += gravity
velX *= friccion
velY *= friccion
arrow.y += velY
arrow.x += velX
y ahi calculas la rotacion del arrow
January 8th, 2008 at 12:51 pm
Gracias Yohami por el aporte.
Coincido con vos acerca de la brusquedad de la caida. Necesita un poco más de trabajo. Voy a probar tu manera y haré el update.
Gracias por el aporte y el feedback!
January 9th, 2008 at 4:29 am
Hi there Alejandro.
Very nice and useful tutorial. I do really love it, and I’m sure I’ll be handy for me. I also do have some critisism :-)
Yohami gives you feed back, in spanish :-/ Maybe I could find it useful, so please tell users to reply in english!
Also, when you inserts your actionscript in the tutorial, I’m not able to see all of it. Maybe try to use an iframe, ’cause I can’t see it all :-(
..else very nice and long, tutorial. You explains it very fine. Maybe you should include more swf, ’cause I find a tutorial more attractive, if you show more interactive examples, instead of just pictures :-)
I’m looking forward to part 2!
January 9th, 2008 at 7:39 am
Thanks Frederik
You are right about the code, and swf, i’ll improve this WP skin to be able to work faster on tutorials without taking care about how it looks. Nice suggestions.
About English/Spanish issue, since im from Argentina and a lot of post here in the blog are writen in spanish, i can’t force the users to speak english. Anyway you are right about it could be usefull in english for a lot of people. Cos that, i will try to do the english translations on the comments if any user uses Spanish.
Here we go:
Good idea! anyway, the phisyc is odd, it should draw a parabola and is going down so fast(falling). Try this:
– inicial//initial
gravity = 2//gravity
velY = -20// velocity on Y axis
velX = 30// velocity on X axis
friccion = .95 //friction
– enterframe
velY += gravity
velX *= friccion
velY *= friccion
arrow.y += velY
arrow.x += velX
then you can calculate arrow rotation.
January 9th, 2008 at 11:24 am
Okay. I understand :-).
Also, at the frontpage, remember to make a button called “read the rest” so you dont get a long page! That is done, when you post a new post, you just press the button that I think is called More. Then it creates a tag, and beneath you write all, that you can’t see while on frontpage!
March 27th, 2008 at 3:16 pm
I don’t think more SWF’s, like frederik J suggest, wouldn’t make this turorial easier. I think the reason for those pics is that he only had one “Working” SWF and still wants to show us something.
It doesn’t add more things to a basic concept. It starts with a fully working game so it’s hard to add more than one SWF.
If you want to add more than one SWF than start with a guy that shoot arrows all at same speed - SWF, than add different velocity’s and ad the end even the friction.
But that will make the tutorial a lot slower. So I think this is a better solution.
Anyway this is a clear tutorial. I learned something about “setInterval” wich can help me with my games.
My English is not that good so I hope I didn’t made many mistakes,
Brart
March 29th, 2008 at 11:38 am
[…] I found another link (wich I liked better than Emanuele’s, but thats just opinion). And this is the link I found. You should really check it out, very […]