代码改变世界

角渡 应用

2010-03-23 13:00  宝宝合凤凰  阅读(266)  评论(0)    收藏  举报

Math Class



download a zip of this and other fla's on this page

A look at some of the basic methods of the Math class

The most commonly used methods of the Math class are probably random, floor and round, as well as the trig functions for math, science and game applications.

Random() returns a decimal number greater than or equal to 0 and less than 1, floor() truncates a decimal number and returns the integer portion, and round() rounds a decimal number to the nearest integer.

Examples of round(), random(), floor()

Find a random decimal number x greater than or equal to 0 and less than 100:
x = Math.random()*100;
Find a random integer between 10 and 15, inclusive:
x = 10 + Math.floor(Math.random()*6);
Find a random integer between a and b, inclusive:
x = a + Math.floor(Math.random()*(b-a+1));
Find the integer percentage of downloaded lm_mc bytes out of the total:
pct = Math.round((lm_mc.getBytesLoaded()/lm_mc.getBytesTotal())*100);

 

For an example of Math.random applied to a game, see the dart shooter game.

Creating a new Math method

Unlike Flash MX, in Flash MX 2004 you cannot extend built-in classes like Math by simply defining a new method of the class. Instead, you can create a new extended class which provides extra functionality and use that. For example, to create a math method that will find a random number between any two specified numbers, you can create a MathExtra class that looks like this:

class com.flashcreations.utils.MathExtra {
	
/*  randomBetween: 
	   Returns a random integer between a and b, inclusive 
*/

    public static function randomBetween(a:Number, b:Number):Number {
        return (a + Math.floor(Math.random()*(b-a+1)));
   }	
}
which defines a public (available outside the class) static (method is applied to the class itself rather than an instance of the class) method named randomBetween, which you can then use in a movie like this:
import com.flashcreations.utils.MathExtra;

var n:Number;
for (i=0; i<20; i++) {
   n = MathExtra.randomBetween(15, 25);
   trace(n);
}
The first line in the loop assigns a number returned by the randomBetween method of the MathExtra class to variable n, and the second line displays the in the Output panel. The for loop just shows a sample use of the method to generate 20 random integers between 15 and 25 inclusive.

 

Trigonometry methods of the Math class

The trig functions are an often-used part of the Math class. When an object has to move at a specified angle from a line, or a point found along a circle, or a sine wave drawn (as above), the built-in trigonometry methods of the Math class are extremely useful. The picture at left shows an angle beta (yes, it should be theta traditionally, but I prefer something I can show in html) with its constituent parts in a circle drawn in.

Angle beta can be expressed in degrees (out of 360 in a complete circle) or radians (out of 2*pi in a complete circle). An angle of 45 degrees, for example, is an angle that is defined by going 1/8 of the way around a circle, so it is 2*pi/8 = pi/4 (=0.785) radians. Here are the relationships between the other constituent parts:

y/r = sin() --> in Flash, y = r * Math.sin(beta), where beta is specified in radians

= asin(y/r) --> in Flash, beta = Math.asin(y/r), where beta is returned in radians

x/r = cos() --> in Flash, x = r * Math.cos(beta), where beta is specified in radians

= acos(x/r) --> in Flash, beta = Math.acos(x/r), where beta is returned in radians

y/x = tan() --> in Flash, y = x * Math.tan(beta), where beta is specified in radians

= atan(y/x) --> in Flash, beta = Math.atan(y/x), where beta is returned in radians

There are two equations which are necessary to convert between the radians returned (or required) by the functions above, and degrees, which is how the _rotation property is specified in Flash:

beta_degrees = beta_radians * 180/Math.PI;

beta_radians = beta_degrees * Math.PI/180;

 

Math.Atan2 for finding angle of rotation

There is an additional function provided per the ECMA-262 spec on which actionscript is based -- atan2, which is often more useful than atan in applications involving rotation by a specified amount, because it returns a positive beta for all angles between 0 and 180 degrees (even when x is negative). Thus it eliminates the need for extra code to deal with different values in different quadrants of the circle. This is the additional function:

-adjusted = atan2(y, x) -->

in Flash, beta_adj = Math.atan2(y, x), where beta_adj is returned in radians

Above is an example of using Math.atan2 to find and apply an angle of rotation. The needle is a movieclip with instance name needle_mc and a registration point at its far left. It is positioned over the center of the circle and the following code in frame 1 makes the needle follow the user's mouse:

function rotation(dx:Number, dy:Number):Number {
   return Math.atan2(dy, dx) * 180/Math.PI;
}
onMouseMove = function() {
   needle_mc._rotation = rotation(_xmouse - needle_mc._x, _ymouse-needle_mc._y);
};
Here is a modified version in which the needle tracks the mouse only when the mouse is pressed AND dragged inside the blue area (a movieclip named area_mc). In this example, I made rotation a method of my MathExtra class. The fla and as class are included in the zip file link below.

import com.flashcreations.utils.MathExtra;

onMouseDown = function() {
   // define this inside the onMouseDown function so that it will only be
   // done when the mouse is pressed
   onMouseMove = function() {
      // if the mouse is over area_mc, rotate the needle
      if (area_mc.hitTest( _xmouse, _ymouse, true)) {
         needle_mc._rotation = MathExtra.rotation(_xmouse - needle_mc._x, 
                                                  _ymouse - needle_mc._y);
      }
   };
};

onMouseUp = function() {
   // checking should only be done when mouse is pressed
   delete onMouseMove;
};

Tweened Rotation with the Tween Class (Flash MX 2004)

Using the Tween class (syntax here), you can make a dial rotate to a spot the user clicks on. The code below is Martin Wood's modification to a basic rotation tween which ensures that the dial will always spin in the direction the makes the smallest angle between the current position and the newly selected position (in other words, in the way one would expect it to behave). Make a movieclip with instance name circle, make sure it has a center registration point and put this code in frame 1:

import mx.transitions.Tween;
import mx.transitions.easing.*;

function rotation(dx:Number, dy:Number):Number {
   return Math.atan2(dy, dx) * 180/Math.PI;
}
circle.onRelease = function() {
   var newAngle:Number = rotation(_xmouse-this._x, _ymouse-this._y);

   var dist:Number = Math.abs(newAngle - this._rotation);
   this._rotation %= 360;
    
   if(dist > 180)     {
      if(newAngle > this._rotation) {
         newAngle -= 360;
      } else {
         newAngle += 360;
      }
   }
   new Tween(this, "_rotation", Strong.easeOut, this._rotation, newAngle, 1, true);
 };

http://www.flash-creations.com/notes/asclass_math.php