Throw a ball with a sling physics Flash tutorial

August 16th update: 2nd part released by Kevin Ward

Here it comes the first tutorial about some strange ways to use ball physics in a game, as said in the rules of Jay is Games competition. We have to create something original and physics related at the same time.

We'll learn how to throw a ball with a sling.

In order to throw a ball with a sling, you need a ball and a sling. We can define a sling as an elastic connecting two points.

So I am going to create the ball and the points in Flash in this way:

Sling physics

Then, in the first frame, this is the actionscript:

ACTIONSCRIPT:
  1. attachMovie("sling", "sling_1", _root.getNextHighestDepth(), {_x:20, _y:200});
  2. attachMovie("sling", "sling_2", _root.getNextHighestDepth(), {_x:480, _y:200});
  3. attachMovie("ball", "ball", _root.getNextHighestDepth(), {_x:250, _y:100});
  4. _root.createEmptyMovieClip("elastic", _root.getNextHighestDepth());
  5. ball.onPress = function() {
  6.     startDrag(this);
  7. };
  8. ball.onRelease = function() {
  9.     stopDrag();
  10. };

Line 1: Placing the first of the two sling nodes in the stage

Line 2: Placing the second sling

Line 3: Placing the ball

Line 4: Creating the empty movieclip where we will draw the elastic

Lines 5-7: Routine to drag the ball

Lines 8-10: Routine to release the ball. You already saw this code in the Creation of the engine behind “Nodes” game with Flash tutorial.

And in only ten lines we have a draggable ball and a sling without elastic. Time to have an aspirin and make the elastic. Or somethins similar, of course...

Let's define the basics: we want the elastic to bend if the ball is moved below sling points.

ACTIONSCRIPT:
  1. attachMovie("sling", "sling_1", _root.getNextHighestDepth(), {_x:20, _y:200});
  2. attachMovie("sling", "sling_2", _root.getNextHighestDepth(), {_x:480, _y:200});
  3. attachMovie("ball", "ball", _root.getNextHighestDepth(), {_x:250, _y:100});
  4. _root.createEmptyMovieClip("elastic", _root.getNextHighestDepth());
  5. ball.onPress = function() {
  6.     startDrag(this);
  7. };
  8. ball.onRelease = function() {
  9.     stopDrag();
  10. };
  11. elastic.onEnterFrame = function() {
  12.     this.clear();
  13.     this.lineStyle(2, 0x009900);
  14.     this.moveTo(sling_1._x, sling_1._y);
  15.     if (ball._y>182) {
  16.         dist_x = ball._x-sling_1._x;
  17.         dist_y = ball._y-sling_1._y;
  18.         distance_from_sling = Math.sqrt(dist_x*dist_x+dist_y*dist_y);
  19.         elastic_length = Math.sqrt(distance_from_sling*distance_from_sling-18*18);
  20.         angle = Math.atan2(dist_y, dist_x)+Math.asin(18/distance_from_sling);
  21.         this.lineTo(sling_1._x+elastic_length*Math.cos(angle), sling_1._y+elastic_length*Math.sin(angle));
  22.     } else {
  23.         this.lineTo(sling_2._x, sling_2._y);
  24.     }
  25.     this.moveTo(sling_2._x, sling_2._y);
  26.     if (ball._y>182) {
  27.         dist_x = ball._x-sling_2._x;
  28.         dist_y = ball._y-sling_2._y;
  29.         distance_from_sling = Math.sqrt(dist_x*dist_x+dist_y*dist_y);
  30.         elastic_length = Math.sqrt(distance_from_sling*distance_from_sling-18*18);
  31.         angle = Math.atan2(dist_y, dist_x)+Math.asin(18/distance_from_sling)*-1;
  32.         this.lineTo(sling_2._x+elastic_length*Math.cos(angle), sling_2._y+elastic_length*Math.sin(angle));
  33.     } else {
  34.         this.lineTo(sling_2._x, sling_2._y);
  35.     }
  36. };

Line 11: Beginning of the script to be executed at every frame for the elastic object

Line 12: Clearing the movieclip

Line 13: Setting the line style to a green, two pixel thick line

Line 14: Placing the pen on the center of the first sling. If you aren't familiar with draw commands, read Create a flash draw game like Line Rider or others - part 1 tutorial.

Line 15: Determining if the ball bends the elastic. That 182 means nodes _y position (200) minus ball radius (18), that means that the ball is below sling points

Lines 16-18: Calculating the distance between the center of the ball and the center of the left sling point, using the Pythagorean theorem.

Line 19: Having the distance, using the Pythagorean theorem again to calculate the length of the elasitc, that will touch the ball forming an angle of 90 degrees with the radius. You'll understand why after reading the next line.

Line 20: Determining the angle between the ball and the left sling point as seen a million times with trigonometry. Refer to Create a flash draw game like Line Rider or others - part 3 tutorial for some trigonometry hints.

But in this case you will notice it's not the well-known code Math.atan2(dist_y, dist_x) but there is another Math.asin(18/distance_from_sling). What is it?

Math.asin(x) returns the arc sine for the number specified in the parameter x, in radians. The arc sine is the inverse of the sine. I have to add the angle due to the arc sine to find a spot along ball circumference where a line long distance_from_sling pixels connects the circumference to the center of the left sling.

One picture will mess your head more than a thousand words:

Sling

That's why we used the Pythagorean theorem to calculate the elastic length and why we involved tha arcsin function.

Line 21: Drawing a line as long as elastic_length with an angle inclination using trigonometry.

Line 23: If the ball is not bending the elastic, just draw a straight line from one sling point to another

Lines 25-35: Same thing for the right sling point

And now we have our elastic bending.

Of course it's a fake because the elastic does not roll around the ball, but it's just a game...

You may say there are some lines and controls I can delete, since (as example) being the two sling nodes at the same _y position is not necessary to perform the check twice, but I need to keep them separated at the moment because I plan to make the sling points draggable.

We will need to determine the angle and force of fire, and we'll see it in another tutorial (coming very soon of course! the competition has begun!), but I think you should have an hint with the next movie, where I simply connected the two "elastic" ends with the center of the ball.

As you can see in the movie (and in the previous picture), the angle between one part of the elastic and the radius going to it is always 90 degress. And that arc that is forming, that seems to grow as much as you draw the ball... do you have the solution? Write it as a comment and you'll have a post dedicated to your discovery.

Meanwhile, take all the flas and give me FB (feedback)

August 16th update: 2nd part released by Kevin Ward

Improve the blog rating this post
Tell me what do you think about this post. I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

10 Responses to “Throw a ball with a sling physics Flash tutorial”

  1. Adam Owen on August 13th, 2007 5:27 pm

    Another awesome tutorial!

    I’ve always wondered how this was done after playing the slingstar game on teagames. Their rope bends round the ball but I think your solution looks fine as it is.

    Looking forward to seeing how to fling the ball!

    Thanks!

  2. Dean on August 14th, 2007 3:34 pm

    The download link is broken.

  3. Emanuele Feronato on August 14th, 2007 5:55 pm

    Fixed

    Thank you.

  4. squareCircleZ » More game math on August 15th, 2007 4:02 am

    [...] One guy has started on his competition entry entitled Throw a ball with a sling. The article includes a tutorial on how he is incorporating mathematics into his game. [...]

  5. Izy on August 15th, 2007 3:17 pm

    This one’s really cool.

    I think I have it figured out.

    var ball:MovieClip = _root.attachMovie(”ball”, “ball”, 2, {_x:275, _y:100});
    var elastic:MovieClip = _root.createEmptyMovieClip(”elastic”, 1);
    var point1:MovieClip = _root.attachMovie(”sling”, “point1″, 3, {_x:100, _y:200});
    var point2:MovieClip = _root.attachMovie(”sling”, “point2″, 4, {_x:450, _y:200});

    var gravity = 0.1;

    var angle1:Number = 0;

    var angle2:Number = 0;

    var radius:Number = 13.0; // Or whatever half the width of your ball is.

    var released:Boolean = true;

    var forced:Boolean = false;

    var acc:Object = {x:0,y:0};
    var vel:Object = {x:0,y:0};

    _root.onMouseDown = function() {

    ball._x = _root._xmouse;
    ball._y = _root._ymouse;
    ball.startDrag();
    _root.released = false;
    vel.x = 0;
    vel.y = 0;
    }

    _root.onMouseUp = function() {

    ball.stopDrag();
    _root.released = true;

    }

    ball.onPress = function() {

    ball.startDrag();
    _root.released = false;
    vel.x = 0;
    vel.y = 0;
    }

    ball.onRelease = function() {

    ball.stopDrag();
    _root.released = true;

    }

    _root.onEnterFrame = function() {

    elastic.clear();
    elastic.lineStyle(5, 0×00EE00);

    if (released) {

    ball._x = vel.x;
    ball._y = vel.y;

    }

    if (ball._y >= 187) {

    forced = true;

    var x1:Number = ball._x-point1._x;
    var y1:Number = ball._y-point1._y;

    var x2:Number = point2._x-ball._x;
    var y2:Number = point2._y-ball._y;

    var distance1:Number = Math.sqrt(x1*x1 y1*y1);
    var distance2:Number = Math.sqrt(x2*x2 y2*y2);

    _root.angle1 = Math.atan2(y1,x1);
    _root.angle2 = Math.atan2(y2,x2);

    var xOffset:Number = Math.cos(angle1 Math.PI/2)*radius;
    var yOffset:Number = Math.sin(angle1 Math.PI/2)*radius;

    var xOffset2:Number = Math.cos(angle2 Math.PI/2)*radius;
    var yOffset2:Number = Math.sin(angle2 Math.PI/2)*radius;

    elastic.moveTo(point1._x, point1._y);
    elastic.lineTo(ball._x xOffset, ball._y yOffset);

    elastic.moveTo(point2._x, point2._y);
    elastic.lineTo(ball._x xOffset2, ball._y yOffset2);

    }
    else {

    forced = false;
    elastic.moveTo(point1._x, point1._y);
    elastic.lineTo(point2._x, point2._y);

    }
    acc.x = 0;
    acc.y = 0;
    acc.y = gravity;

    if (released && forced) {

    acc.x = distance1*Math.sin(angle2)/1000;
    acc.y = -distance1*Math.cos(angle1)/1000;

    acc.x = distance2*Math.sin(angle1)/1000;
    acc.y = -distance2*Math.cos(angle2)/1000;

    }

    if (released) {

    vel.x = acc.x;
    vel.y = acc.y;

    }

    }

  6. Izy on August 15th, 2007 5:55 pm

    It looks like it doesn’t print the plus sign. I guess I’ll have it to e-mail you.

  7. Throw a ball with a sling physics Flash tutorial: Part 2 by Kevin Ward at Emanuele Feronato on August 16th, 2007 10:40 am

    [...] Only 2 days. That’s how much time Kevin Ward needed to solve and publish the solution of the problem posted in Throw a ball with a sling physics Flash tutorial. [...]

  8. cod on August 18th, 2007 3:04 pm

    im having some problems please help me :D
    in the first script 1.
    attachMovie(”sling”, “sling_1″, _root.getNextHighestDepth(), {_x:20, _y:200});
    2.
    attachMovie(”sling”, “sling_2″, _root.getNextHighestDepth(), {_x:480, _y:200});
    3.
    attachMovie(”ball”, “ball”, _root.getNextHighestDepth(), {_x:250, _y:100});
    4.
    _root.createEmptyMovieClip(”elastic”, _root.getNextHighestDepth());
    5.
    ball.onPress = function() {
    6.
    startDrag(this);
    7.
    };
    8.
    ball.onRelease = function() {
    9.
    stopDrag();
    10.
    };

    its not working there is supposed to be 2 slings right but there is nothing but one and when i check the script it says script has no errors

    please help me im a newbie to flashbut i know the basics

  9. Frederik J on August 19th, 2007 10:02 am

    Yo need to go to your library. Right click on the slings, and press linkage. The you enable “Export for Actionscript”. Make sure you do it at both of them.

  10. This_Guy_is_a_Newbie_in_Flash on September 12th, 2007 4:02 am

    thank u very much

    btw how can u make it launch when u let go of the
    mouse button

    again THANK U

Leave a Reply