Create a flash draw game like Line Rider or others - part 4
Filed Under Flash •
March 31st update: part 5 released
Here we go with the 4th part. Read steps 1, 2 and 3 and you're ready to go.
In the last example in step 3 we had our bouncing ball but some of you noticed that sometimes the ball appears to be "stuck" in the ground, making some fake bounces.
Let's understand why.
In the next movie, I created another movieclip instanced as "last_hit".
Let's see what happens.
-
onClipEvent (load) {
-
yspeed = 0;
-
xspeed = 0;
-
gravity = 0.2;
-
radius = 5;
-
friction = 0.90;
-
precision = 360;
-
bounces = 0;
-
}
-
onClipEvent (enterFrame) {
-
if (_root.go == true) {
-
collisions = 0;
-
sum_x = 0;
-
sum_y = 0;
-
yspeed = yspeed+gravity;
-
for (x=1; x<precision; x++) {
-
spot_x = _x+radius*Math.sin(x*360/precision);
-
spot_y = _y-radius*Math.cos(x*360/precision);
-
if (_root.terrain.hitTest(spot_x, spot_y, true)) {
-
collisions++;
-
sum_x += spot_x;
-
sum_y += spot_y;
-
}
-
}
-
if (collisions>0) {
-
_root.last_hit._x = _x;
-
_root.last_hit._y = _y;
-
bounces++;
-
_root.collisions.text = "Bounces: "+bounces;
-
ball_dir = Math.atan(yspeed/(xspeed*-1))/(Math.PI/180);
-
if ((xspeed*-1)<0) {
-
ball_dir += 180;
-
}
-
if ((xspeed*-1)>=0 && yspeed<0) {
-
ball_dir += 360;
-
}
-
spot_x = sum_x/collisions;
-
spot_y = sum_y/collisions;
-
x_cat = spot_x-_x;
-
y_cat = spot_y-_y;
-
ball_coll = Math.atan(y_cat/x_cat)/(Math.PI/180);
-
if (x_cat<0) {
-
ball_coll += 180;
-
}
-
if (x_cat>=0 && y_cat<0) {
-
ball_coll += 360;
-
}
-
ground_rotation = ball_coll-90;
-
if (ground_rotation<0) {
-
ground_rotation += 180;
-
}
-
bounce_angle = 180-ball_dir-2*(ground_rotation);
-
if (bounce_angle<0) {
-
bounce_angle += 360;
-
}
-
speed = Math.sqrt((yspeed*yspeed)+(xspeed*xspeed));
-
xspeed = speed*Math.cos(bounce_angle*Math.PI/180)*friction;
-
yspeed = (speed*Math.sin(bounce_angle*Math.PI/180))*-1*friction;
-
}
-
_y = _y+yspeed;
-
_x = _x+xspeed;
-
}
-
}
On lines 26-27 I assign to last_hit _x and _y the position where we checked the collision between the ball and the ground
As you can see, sometimes the black ball (last_hit) seems to "sink" in the ground, and that's when an error may occur. If the ball sinks, and after the first bouncing frame is still inside the ground, the script will believe the ball encountered another wall and make it bounce again. Look at this picture:

If the ball sinks too much into the ground, line in position 2, during the bounce may collide again with the ground causing a fake bounce.
There are several ways to fix this issue, we could check the collision again and verify if there is a fake bounce.
Remember, though, that we are already doing a quite CPU expansive task, so determining twice (or more) in a frame all fake bounces may cause the game to slow down too much.
I found a way that roughly approximates the right way to avoid fake bounces and that works well, specially if you consider we are creating a game and not an accurate simulation.
I just "remember" the last _x and _y position where there wasn't any collision and set the collision point at that point.
The physics works in the same way, but the bounce won't start from the ground but from the last spot the ball was sighted before it touched the wall.
-
onClipEvent (load) {
-
yspeed = 0;
-
xspeed = 0;
-
gravity = 0.2;
-
radius = 5;
-
friction = 0.90;
-
precision = 360;
-
bounces = 0;
-
}
-
onClipEvent (enterFrame) {
-
if (_root.go == true) {
-
collisions = 0;
-
sum_x = 0;
-
sum_y = 0;
-
yspeed = yspeed+gravity;
-
for (x=1; x<precision; x++) {
-
spot_x = _x+radius*Math.sin(x*360/precision);
-
spot_y = _y-radius*Math.cos(x*360/precision);
-
if (_root.terrain.hitTest(spot_x, spot_y, true)) {
-
collisions++;
-
sum_x += spot_x;
-
sum_y += spot_y;
-
}
-
}
-
if (collisions>0) {
-
_root.last_hit._x = old_x;
-
_root.last_hit._y = old_y;
-
bounces++;
-
_root.collisions.text = "Bounces: "+bounces;
-
ball_dir = Math.atan(yspeed/(xspeed*-1))/(Math.PI/180);
-
if ((xspeed*-1)<0) {
-
ball_dir += 180;
-
}
-
if ((xspeed*-1)>=0 && yspeed<0) {
-
ball_dir += 360;
-
}
-
spot_x = sum_x/collisions;
-
spot_y = sum_y/collisions;
-
x_cat = spot_x-_x;
-
y_cat = spot_y-_y;
-
ball_coll = Math.atan(y_cat/x_cat)/(Math.PI/180);
-
if (x_cat<0) {
-
ball_coll += 180;
-
}
-
if (x_cat>=0 && y_cat<0) {
-
ball_coll += 360;
-
}
-
ground_rotation = ball_coll-90;
-
if (ground_rotation<0) {
-
ground_rotation += 180;
-
}
-
bounce_angle = 180-ball_dir-2*(ground_rotation);
-
if (bounce_angle<0) {
-
bounce_angle += 360;
-
}
-
speed = Math.sqrt((yspeed*yspeed)+(xspeed*xspeed));
-
xspeed = speed*Math.cos(bounce_angle*Math.PI/180)*friction;
-
yspeed = (speed*Math.sin(bounce_angle*Math.PI/180))*-1*friction;
-
_x = old_x;
-
_y = old_y;
-
}
-
else{
-
old_x = _x;
-
old_y = _y;
-
}
-
_y = _y+yspeed;
-
_x = _x+xspeed;
-
}
-
}
Lines 62-65 assign the actual _x and _y position to a couple of variables called old_x and old_y in case the ball didn't hit the terrain, while lines 59-60 set the _x and _y ball position to old_x and old_y. Now the ball is not on the ground so we cannot have any fake bounce.
You will notice sometimes there are about 2 or 3 pixels of error, but this can be tolerated in a game where fun is more important than simulation.
Ok, let's resume the drawing
This is a draw game but it's since part 1 we aren't drawing. To put all together, I created a GO! button that will release the ball and added the drawing capability.
To do this, I changed the actions in frame 1
-
go = false;
-
createEmptyMovieClip("terrain", 1);
-
terrain.lineStyle(10, 0xdd00dd, 100);
-
imdrawing = false;
-
onMouseDown = function () {
-
if (imdrawing == false) {
-
terrain.moveTo(_xmouse, _ymouse);
-
imdrawing = true;
-
}
-
if (imdrawing == true) {
-
onEnterFrame = function () {
-
terrain.lineTo(_xmouse, _ymouse);
-
};
-
}
-
};
-
onMouseUp = function () {
-
onEnterFrame = function () {
-
imdrawing = false;
-
};
-
};
To start drawing as seen in tutorial 1, and put this actionscript in the button
-
on (release) {
-
go = true;
-
}
to release the ball.
Now I want to stop drawing when the "GO!" button is pressed (it would be too easy if you could draw once in game, you have to foresee the ball bounces!), and I want a "RESET!" button to start drawing again.
To reset the stage, simply add a rest button with this actionscript:
-
on (release) {
-
_root.ball._x = 27;
-
_root.ball._y = 47;
-
_root.ball.xspeed = 0;
-
_root.ball.yspeed = 0;
-
_root.go = false;
-
_root.terrain.clear();
-
_root.terrain.lineStyle(10, 0xdd00dd, 100);
-
}
Lines 2-3: Reset ball position
Lines 4-5: Reset ball speed
Line 6: The go variable is set to false (the ball is not moving)
Lines 7-8: Clear the stage and start drawing again
Finally, I want to stop drawing when the ball is running... and of course I want...
The exit
I created another movieclip instanced as exit
First, let's see how to prevent the player from drawing once the ball is going.
The actions on frame 1 are:
-
go = false;
-
createEmptyMovieClip("terrain", 1);
-
terrain.lineStyle(10, 0xdd00dd, 100);
-
imdrawing = false;
-
onMouseDown = function () {
-
if (!go) {
-
if (imdrawing == false) {
-
terrain.moveTo(_xmouse, _ymouse);
-
imdrawing = true;
-
}
-
if (imdrawing == true) {
-
onEnterFrame = function () {
-
terrain.lineTo(_xmouse, _ymouse);
-
};
-
}
-
}
-
};
-
onMouseUp = function () {
-
onEnterFrame = function () {
-
imdrawing = false;
-
};
-
};
Line 6 Simply checks the go variable and let the player draw only if go is false
About the exit, the ball actionscript will be:
-
onClipEvent (load) {
-
yspeed = 0;
-
xspeed = 0;
-
gravity = 0.2;
-
radius = 5;
-
friction = 0.90;
-
precision = 360;
-
bounces = 0;
-
}
-
onClipEvent (enterFrame) {
-
if (_root.go == true) {
-
if (_root.exit.hitTest(_x, _y, true)) {
-
xspeed = 0;
-
yspeed = 0;
-
} else {
-
collisions = 0;
-
sum_x = 0;
-
sum_y = 0;
-
yspeed = yspeed+gravity;
-
for (x=1; x<precision; x++) {
-
spot_x = _x+radius*Math.sin(x*360/precision);
-
spot_y = _y-radius*Math.cos(x*360/precision);
-
if (_root.terrain.hitTest(spot_x, spot_y, true)) {
-
collisions++;
-
sum_x += spot_x;
-
sum_y += spot_y;
-
}
-
}
-
if (collisions>0) {
-
_root.last_hit._x = old_x;
-
_root.last_hit._y = old_y;
-
bounces++;
-
_root.collisions.text = "Bounces: "+bounces;
-
ball_dir = Math.atan(yspeed/(xspeed*-1))/(Math.PI/180);
-
if ((xspeed*-1)<0) {
-
ball_dir += 180;
-
}
-
if ((xspeed*-1)>=0 && yspeed<0) {
-
ball_dir += 360;
-
}
-
spot_x = sum_x/collisions;
-
spot_y = sum_y/collisions;
-
x_cat = spot_x-_x;
-
y_cat = spot_y-_y;
-
ball_coll = Math.atan(y_cat/x_cat)/(Math.PI/180);
-
if (x_cat<0) {
-
ball_coll += 180;
-
}
-
if (x_cat>=0 && y_cat<0) {
-
ball_coll += 360;
-
}
-
ground_rotation = ball_coll-90;
-
if (ground_rotation<0) {
-
ground_rotation += 180;
-
}
-
bounce_angle = 180-ball_dir-2*(ground_rotation);
-
if (bounce_angle<0) {
-
bounce_angle += 360;
-
}
-
speed = Math.sqrt((yspeed*yspeed)+(xspeed*xspeed));
-
xspeed = speed*Math.cos(bounce_angle*Math.PI/180)*friction;
-
yspeed = (speed*Math.sin(bounce_angle*Math.PI/180))*-1*friction;
-
_x = old_x;
-
_y = old_y;
-
} else {
-
old_x = _x;
-
old_y = _y;
-
}
-
_y = _y+yspeed;
-
_x = _x+xspeed;
-
}
-
}
-
}
Lines 12-14 stop the ball if it touches the exit.
Now you should be ready to create your first ball drawing game... why don't you send me your works? I will publish on this site.
The tutorial is not over of course... we still have to see how to advance levels, how to change the ball with a car or a guy, and so on.
Meanwhile, download source codes and give me feedback, then proceed to part 5
Other Resources: casino game
Tell me what do you think about this post. I'll write better and better entries.
They can be easily customized to meet the unique requirements of your project.
68 Responses to “Create a flash draw game like Line Rider or others - part 4”

(7 votes, average: 4.86 out of 5)
Is it just me, or are the movies not loading?
But anyway, nice tut man! Can’t wait for the rest!
Just a quickie to note that I love the tutorials and can’t wait to see more from you. Thanks a lot for putting the time into these - they’re most appreciated.
ACE, what will we be learning to do inthe next tutorial?
why do some of the tutorials not work in other versions of flash
Those ‘2 or 3 pixels of error’ are quite pronounced in my version if I increase the size of the ball and the radius associated with it. I’ve noticed it is worse when the collision detection takes place on the left hand side of the ball with steep line slopes. Flat lines and ones that go up and to the right seem to work alright. Any suggestions? Thank you!
Hey man nice tut cant wait for the next
hey,whats the actionscript to make to ball move when Go is clicked?
in reply to byitdude:
code for the button(’GO’) is
on(release) {
go=true;
}
put this code in the button u make.
**************************************
my problem:
with me, everything is alright except the reset button when I press the button the ball stops where it is & when the GO button is again pressed it falls with the power it had before the RESET was pressed. PLEASE HELP
Hurry up and post part 5 as fast as you can, i just cant wait
oh and by the way the game still needs alot of work, the ball wont roll, it just bounces
Hey, in one of these, can you maybe show us how to make it so that if the character or ball hits the grounds too hard, it resets? I would like that for a future game of mine.
i fink the games sucks
lol it works fine but maybe a moving shadow and when u have like 5 bounces and hit reset it errases ur lines and stuff but it still has 5 bounces
you know the ball can ride the line and not bounce if you put the ball like a car and have it fase the angle of the line you det det de
hi can some on help me when the ball touches the box how can you make it go onto another frame if some one can help iot will be much appreciated
eblup what hapnes when you change angle?? and its de de u dee
isa i dont “fink” these games suck
can u guys post another game but do it more spectific and post the easy game and short..? thank you help me plz
my problem is i dont know how to do the wall. plz post for me another simple game and short or u guys can teach me how to do the wall ore bountri plz help thank you
Once again, great tut! 2 Problems:
1: The ball never stops moving.
2: This is supposed to be a linerider game, not a ball bouncing game…;-)
Keep up the good work!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MARTIN:
hi can some on help me when the ball touches the box how can you make it go onto another frame if some one can help iot will be much appreciated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
just put in collision with exit:
gotoAndStop(2)
2 refering to what frame :-)
so what you say jordanleffl all you have to do is put gotoAndStop(2) on the exit and that is it
Yes Martin. Where you have your hit test for the exit, simply add “gotoAndStop(’frame_number’)”. But… If you are testing if the ball hits in the exits actions, then you need “_root.gotoAndStop(’frame number’)”. So, root on the exit, no root on the frame. Makes sense?
i am a begginer at flash and can someone give me the hit test i need you all have been helpful thanks
please check out my website
WOW! I Love this! I mad a quick little game out of this…
http://img221.imageshack.us/my.php?image=linebouncerdp0.swf
I cant wait for part five!
hey i love the tutorials, but was wondering how do you make the object roll or slide on the line instead of bounce?
hey, this is just great. I’m goona use some of what I learned here in a project for my college. keep it up, I’ll be checking!!!
regards,
ty very much i made a pretty cool game because of this tut.
In Adobe Flash Or Macromedia ????
how do u stop the ball from flying off the screen without having to draw a box while in game?
BAHAHAHAHH someone stole your tutorial completely and made it into a game.. here
thats so funny! they didnt even change the line color.. or get rid of the bouce counter.. or the circle where the ball had been
How do you get rid of the part that shows the last bounce and the bounces count?
I have an idea but I always encounter many errors!
I’ve also made an artillery game and it works! I’m really pleased and the tutorials are amazing!
Much thanks! ^^
For some reason, My game lags a lot. When i try to draw, sometimes the line doesn’t show up.
Can someone help me?
Oh and by the way, I’m using Flash MX educational.
in reply to darth turtle:
check the frame rate of the movie.To do that just press CTRL J
and change the FPS(frames per second)
**Error** Line 1: Clip events are permitted only for movie clip instances
onClipEvent (load) {
**Error** Line 10: Clip events are permitted only for movie clip instances
onClipEvent (enterFrame) {
in reply to Eth:
I think you have copied action script given for the ball to the frame.
~~~~~~~~~~~~~~~~~~~~~~~~~~
For everybody:
To rotate the ball just add
“_rotation = xspeed;” below the
“_x = _x xspeed;” in the ball AS
Yeah, actually how DO you get rid of the ball count? lol
Finally, drawn line collisions. I don’t know if you realize that this is probably one of a very few places that has a tutorial about this. Screw vector based tile grids for collisions. Now I can finally have very dynamic point to point coordinates for walls, etc.. instead of the complex tiles and endless modularity. Good job being awesome.
Thanks again for your great tutorial! But I’d like to see how one can make the ball ROLL down a line without bouncing… How can it be done? Thanks
Hi! Thanks for your tutorials, they’re the best, I’m sooo excited making my little ball game hehe ^^ but I’m facing one trouble when I want to make a thing for two balls, and one of them start to float in space.. really strange. Do I have to change the variable names or something? Thanks again!
Actually got that one allready, and voila! my game’s finished! :) If you (or someone else)’d like to download it, it’s here: http://rapidshare.com/files/47444843/_Pelota_.exe
//it’s in spanish :)
We got a thousand and nine Bounces
Hey, this is a great tut! But how do you make it slide down the line and not bouce? All so, how do you make it so you can rub a bit of the line out?
Also, one more question… how do you make it so that you can move over to the next screen with with a hand? Like the real Linerider, where you click the hand and you can move the frame a bit down. Thanks very much, and very good tut!
I l