|
|
|||||
Регистрация: Apr 2009
Сообщений: 104
|
движение классом Vector2D
Есть класс Vector2d.
/*************************************************************************************************************** Vector2D Class For Actionscript 2.0 --------------------------------------------------------------------------------------------------------------- method listing: state-altering methods: Vector2D(x, y) - create vector and set the components to x and y Vector2D(v) - create vector and set the components to the components of vector v set(x, y) - set the components to x and y set(v) - set the components to the components of vector v plus(v1 ... vn) - add the components of the given vectors to the components of the vector minus(v1 ... vn) - subtract the components of given vectors from the components of the vector times(x, y) - multiply the components of vector by x and y times(scalar) - multiply the components of vector by number scalar times(v) - multiply the components of vector by the components of vector v invert() - invert (or reverse) the vector project(v) - set the vector to be the projection of the vector onto vector v reflect(v) - reflect the vector over vector v rotate(a) - rotate the vector by angle a in degrees swap(v) - swap the components of the vector and vector v (note: also alters vector v) state-safe methods: getLeftNormal() - return a new vector which is left hand normal to the vector getRightNormal() - return a new vector which is right hand normal to the vector cross(v) - return the magnitude of the cross product of the vector and vector v dot(v) - return the dot product of the vector and vector v angleBetween(v) - return the angle between the vector and vector v angleBetweenCos(v) - return the cosine of the angle between the vector and vector v angleBetweenSin(v) - return the sine of the angle between the vector and vector v comparison methods: isEqualTo(v) - test for equality between the vector and vector v isNormalTo(v) - test for normality between the vector and vector v utility methods: display(mc, color) - draw vector in given movieclip using a given color private methods: fixNumber() - convert all inputs to a number of fixed precision toString() - override of built in method to provide meaningful output property listing: x - virtual property representing the current x component of the vector (get/set) y - virtual property representing the current y component of the vector (get/set) angle - virtual property representing the current degree angle of the vector (get/set) magnitude - virtual property representing the current magnitude of the vector (get/set) Feel free to use this code as you wish, Have Fun! Please send bug reports && ( gripes || praise ) to nick[at]zambetti[dot]com ***************************************************************************************************************/ class Vector2D { // instance properties private var xValue:Number = 0; private var yValue:Number = 0; private var type:String = "Vector2D"; // // description: constructor for Vector2D // parameters: x:Number, y:Number || v:Vector2D // returns: reference to the new instance function Vector2D() { this.xValue = 0; this.yValue = 0; this.type = "Vector2D"; if (2 == arguments.length) { // x and y were passed this.xValue = this.fixNumber(arguments[0]); this.yValue = this.fixNumber(arguments[1]); } else if (1 == arguments.length) { if ("Vector2D" === arguments[0].type) { // an existing vector was passed this.xValue = arguments[0].x; this.yValue = arguments[0].y; } } } // // description: sets the properties of the vector // parameters: x:Number, y:Number || v:Vector2D // returns: reference to the vector public function set():Vector2D { this.xValue = 0; this.yValue = 0; this.type = "Vector2D"; if (2 == arguments.length) { // x and y were passed this.xValue = this.fixNumber(arguments[0]); this.yValue = this.fixNumber(arguments[1]); } else if (1 == arguments.length) { if ("Vector2D" === arguments[0].type) { // an existing vector was passed this.xValue = arguments[0].x; this.yValue = arguments[0].y; } } return this; } // // description: adds given vectors to the vector // parameters: v1:Vector2D ... vn;Vector2D // returns: reference to the vector public function plus():Vector2D { for (var i = 0; i<arguments.length; ++i) { if ("Vector2D" === arguments[i].type) { this.xValue += arguments[i].xValue; this.yValue += arguments[i].yValue; } } this.xValue = this.fixNumber(this.xValue); this.yValue = this.fixNumber(this.yValue); return this; } // // description: subtracts given vectors from the vector // parameters: v1:Vector2D ... vn:Vector2D // returns: reference to the vector public function minus():Vector2D { for (var i = 0; i<arguments.length; ++i) { if ("Vector2D" === arguments[i].type) { this.xValue -= arguments[i].xValue; this.yValue -= arguments[i].yValue; } } this.xValue = this.fixNumber(this.xValue); this.yValue = this.fixNumber(this.yValue); return this; } // // description: multiplies the components by the x and y args or by the given vector // parameters: x:number, y:number || scalar:number || v:Vector2D // returns: reference to the vector public function times():Vector2D { if (1 == arguments.length) { if ("Vector2D" === arguments[0].type) { this.xValue *= arguments[0].xValue; this.yValue *= arguments[0].yValue; } else { if (isNaN(Number(arguments[0]))) { this.xValue = this.yValue=0; } else { this.xValue *= Number(arguments[0]); this.yValue *= Number(arguments[0]); } } } else if (2 == arguments.length) { isNaN(Number(arguments[0])) ? this.xValue=0 : this.xValue *= Number(arguments[0]); isNaN(Number(arguments[1])) ? this.yValue=0 : this.yValue *= Number(arguments[1]); } this.xValue = this.fixNumber(this.xValue); this.yValue = this.fixNumber(this.yValue); return this; } // // description: rotates the vector by the given angle (in degrees) // parameters: rotationAngle:Number // returns: reference to the vector public function rotate(rotationAngle:Number):Vector2D { if (isNaN(Number(rotationAngle))) { return this; } var currentMagnitude:Number = Math.sqrt(Math.pow(this.xValue, 2)+Math.pow(this.yValue, 2)); var newAngleRadians:Number = ((Math.atan2(this.yValue, this.xValue)*(180/Math.PI))+Number(rotationAngle))*(Math.PI/180); this.xValue = this.fixNumber(currentMagnitude*Math.cos(newAngleRadians)); this.yValue = this.fixNumber(currentMagnitude*Math.sin(newAngleRadians)); return this; } // // description: inverts the vector // parameters: none // returns: reference to the vector public function invert():Vector2D { this.xValue *= -1; this.yValue *= -1; return this; } // // description: projects the vector onto vector v // parameters: v:Vector2D // returns: reference to the vector public function project(v:Vector2D):Vector2D { if ("Vector2D" === v.type) { var scalar:Number = this.dot(v)/Math.pow(v.magnitude, 2); this.set(v); this.times(scalar); } return this; } // // description: relects the vector over vector v // parameters: v:Vector2D // returns: reference to the vector public function reflect(v:Vector2D):Vector2D { if ("Vector2D" === v.type) { var vAfterHorizReflect:Vector2D = new Vector2D(v.yValue, -v.xValue); var rotationAngle:Number = 2*this.angleBetween(v); if (0>=this.angleBetweenCos(vAfterHorizReflect)) { rotationAngle *= -1; } this.rotate(rotationAngle); } return this; } // // description: calculates the dot product of the vector and vector v // parameters: v:Vector2D // returns: number public function dot(v:Vector2D):Number { if ("Vector2D" === v.type) { return this.fixNumber((this.xValue*v.xValue)+(this.yValue*v.yValue)); } return 0; } // // description: calculates the cross product of the vector and vector v // parameters: v:Vector2D // returns: number (representing the magnitude of the theoretical vector result) public function cross(v:Vector2D):Number { if ("Vector2D" === v.type) { return Math.abs(this.fixNumber((this.xValue*v.yValue)-(this.yValue*v.xValue))); } return 0; } // // description: calculates the the angle between the vector and vector v in degrees // parameters: v:Vector2D // returns: number public function angleBetween(v:Vector2D):Number { if ("Vector2D" === v.type) { return this.fixNumber(Math.acos(this.dot(v)/(this.magnitude*v.magnitude))*(180/Math.PI)); } return 0; } // // description: calculates the sine of the angle between the vector and vector v // parameters: v:Vector2D // returns: number public function angleBetweenSin(v:Vector2D):Number { if ("Vector2D" === v.type) { return this.fixNumber(this.cross(v)/(this.magnitude*v.magnitude)); } return 0; } // // description: calculates the cosine of the angle between the vector and vector v // parameters: v:Vector2D // returns: number public function angleBetweenCos(v:Vector2D):Number { if ("Vector2D" === v.type) { return this.fixNumber(this.dot(v)/(this.magnitude*v.magnitude)); } return 0; } // // description: exchanges data of the vector and the given vector // parameters: v:Vector2D // returns: reference to the vector public function swap(v:Vector2D):Vector2D { if ("Vector2D" === v.type) { var tempX:Number = this.xValue; var tempY:Number = this.yValue; this.xValue = v.xValue; this.yValue = v.yValue; v.xValue = tempX; v.yValue = tempY; } return this; } // // description: creates a new vector which is normal (clockwise) to the vector // parameters: none // returns: reference to the newly created vector public function getRightNormal():Vector2D { return new Vector2D(this.yValue, -this.xValue); } // // description: creates a new vector which is normal (anti-clockwise) to the vector // parameters: none // returns: reference to the newly created vector public function getLeftNormal():Vector2D { return new Vector2D(-this.yValue, this.xValue); } // // description: tests if two vectors are normal to each other // parameters: v:Vector2D // returns: boolean indicating normality public function isNormalTo(v:Vector2D):Boolean { if ("Vector2D" === v.type) { return (this.dot(v) === 0); } else { return false; } } // // description: tests if two vectors are equal to each other // parameters: v:Vector2D // returns: boolean indicating equality public function isEqualTo(v:Vector2D):Boolean { if ("Vector2D" === v.type) { if ((this.xValue === v.xValue) && (this.yValue === v.yValue)) { return true; } } return false; } // // description: retrieves the current x value of the vector // parameters: none // returns: current value of x public function get x():Number { return this.xValue; } // // description: sets x value of the vector // parameters: newX:Number // returns: value of x BEFORE precision fix public function set x(newX:Number):Number { this.xValue = this.fixNumber(newX); } // // description: retrieves the current y value of the vector // parameters: none // returns: current value of y public function get y():Number { return this.yValue; } // // description: sets y value of the vector // parameters: newY:Number // returns: value of y BEFORE precision fix public function set y(newY:Number):Number { this.yValue = this.fixNumber(newY); } // // description: calculates the angle of the vector // parameters: none // returns: number representing angle in degrees public function get angle():Number { return this.fixNumber(Math.atan2(this.yValue, this.xValue)*(180/Math.PI)); //return this.fixNumber(((Math.atan2(this.yValue, this.xValue)*(180/Math.PI))+360)%360); } // // description: sets the angle of the vector to the given angle (in degrees) // parameters: newAngle:Number // returns: number representing angle in degrees BEFORE precision fix public function set angle(newAngle:Number):Number { var angleRadians:Number = 0; if (!isNaN(Number(newAngle))) { angleRadians = Number(newAngle)*(Math.PI/180); } var currentMagnitude:Number = Math.sqrt(Math.pow(this.xValue, 2)+Math.pow(this.yValue, 2)); this.xValue = this.fixNumber(currentMagnitude*Math.cos(angleRadians)); this.yValue = this.fixNumber(currentMagnitude*Math.sin(angleRadians)); } // // description: returns the magnitude of the vector (aka: length) // parameters: none // returns: 0 <= number public function get magnitude():Number { return this.fixNumber(Math.sqrt(Math.pow(this.xValue, 2)+Math.pow(this.yValue, 2))); } // // description: sets the magnitude (aka: length) to the given scalar // parameters: newMagnitude:Number // returns: magnitude after set operation public function set magnitude(newMagnitude:Number):Number { if (isNaN(Number(newMagnitude))) { this.xValue = this.yValue=0; } var currentMagnitude:Number = Math.sqrt(Math.pow(this.xValue, 2)+Math.pow(this.yValue, 2)); if (0<currentMagnitude) { this.times(Number(newMagnitude)/currentMagnitude); } else { this.yValue = 0; this.xValue = this.fixNumber(newMagnitude); } } // // description: draws a vector in a given mc using a given color // parameters: mc|movieClipReference color|hexNumber // returns: nothing public function display(mc:Object, color:Number) { if ("movieclip" === typeof mc) { mc.lineStyle(0, color, 100); mc.moveTo(0, 0); mc.lineTo(this.xValue, this.yValue); } return; } // // description: converts all numeric inputs to a number of fixed precision // parameters: numberValue:Number // returns: number rounded to a fixed precision private function fixNumber(numberValue:Number):Number { return isNaN(Number(numberValue)) ? 0 : Math.round(Number(numberValue)*100000)/100000; } // // description: override of toString() that produces meaningful output // parameters: none // returns: string private function toString():String { return "["+this.xValue+","+this.yValue+"]"; } } |
|
|||||
Регистрация: Apr 2009
Сообщений: 104
|
Hauts, спасибо. Дальше всё понятно.
|
|
|||||
блогер
Регистрация: Feb 2008
Адрес: Россия, Новосибирск, Академгородок
Сообщений: 2,112
Записей в блоге: 1
|
Да не за что
Если что-то с физикой делаете, то имеет смысл обернуть мою конструкцию в отдельный класс с методом update() (например) и свойствами clip (ссылка на мувиклип) и vector (вектор движения), а в основном обработчике на onEnterFrame "пробегаться" по массиву таких классов и вызывать update() для обновления положения. Я к тому, чтобы не плодить кучу onEnterFrame`ов у клипов, чьё движение должно быть зависимо от компонентов соответствующих им векторов, а к тому, чтобы собрать их в массив и в одном onEnterFrame`е обновлять все.
__________________
hauts.ru |
|
|||||
Регистрация: Apr 2009
Сообщений: 104
|
Было бы отлично. Но как Вы поняли, что я в ООП пока только что-то понимаю. А сам сделать еще не могу. Было бы наверно нагло просить показать опять же какой-нибудь простенький пример.
|
|
|||||
блогер
Регистрация: Feb 2008
Адрес: Россия, Новосибирск, Академгородок
Сообщений: 2,112
Записей в блоге: 1
|
Да нет, почему ж нагло? Вполне закономерный вопрос.
Класс для элемента: import Vector2D; class MyPhysElement { public var mc:MovieClip; public var vector:Vector2D; public function MyPhysElement(mc:MovieClip){ this.mc = mc; this.vector = new Vector2D(); } public function update(){ this.mc._x += this.vector.x; this.mc._y += this.vector.y; } } Ну а в основном коде примерно такое: var elements = []; for(var k = 0 ; k < 100; k ++){ var newElement = new MyPhysElement( this.attachMovie( "my_clip", "my_clip_" + k, k ) ); newElement.vector.x = Math.random() * 20 - 10; newElement.vector.y = Math.random() * 20 - 10; elements.push( newElement ); } function updateElements(){ for(var i in elements){ elements[i].update(); } } this.onEnterFrame = updateElements;
__________________
hauts.ru |
|
|||||
Регистрация: Apr 2009
Сообщений: 104
|
Отлично. Есть над чем поработать.
|
Часовой пояс GMT +4, время: 10:33. |
|
« Предыдущая тема | Следующая тема » |
|
|