您的位置:首页 > 其它

Flex高级动画教程中所讲的寻找行为

2011-05-15 16:21 423 查看
----向量类
package vector.steering
{
import flash.display.Graphics;

/**
* ...
* @author DefaultUser (Tools -> Custom Arguments...)
*/
public class Vector2D
{
private var _x:Number;
private var _y:Number;

public function Vector2D(x:Number=0,y:Number=0)
{
_x = x;
_y = y;
}

public function draw(graphics:Graphics, color:uint=0):void {
graphics.lineStyle(0, color);
graphics.moveTo(0, 0);
graphics.lineTo(_x, _y);
}
/**
* 返回自己的克隆向量
* @return Vector2D
*/
public function clone():Vector2D {
return new Vector2D(_x, _y);
}
/**
* 返回 Vector2D (0,0)
* @return Vector2D
*/
public function zero():Vector2D {
_x = 0;
_y = 0;
return this;
}
/**
* 返回是否为零向量
* @return Boolean
*/
public function iszero():Boolean {
return _x == 0 && _y == 0;
}
public function set length(value:Number):void {
var a:Number = angle;
_x = Math.cos(a) * value;
_y = Math.sin(a) * value;
}
/**
* 返回向量的长度
*/
public function get length():Number {
return Math.sqrt(lengthSQ);
}
public function get lengthSQ():Number {
return _x * _x + _y * _y;
}
public function set angle(value:Number):void {
var len:Number = value;
_x = Math.cos(value) * len;
_y = Math.sin(value) * len;
}
public function get angle():Number {
return Math.atan2(_y, _x);
}
/**
* 返回垂直向量
*/
public function get perp():Vector2D {
return new Vector2D( -y, x);
}
public function set x(value:Number):void {
_x = value;
}
public function get x():Number {
return _x;
}
public function set y(value:Number):void {
_y = value;
}
public function get y():Number {
return _y;
}
/**
* 向量单位化
* @return Vector2D
*/
public function normalize():Vector2D {
if (length == 0) {
_x = 1;
return this;
}
var len:Number = length;
_x /= len;
_y /= len;

return this;
}
public function scale(value:uint):Vector2D {

return new Vector2D(_x * value, _y * value);
}
/**
* 限制向量的最大长度
* @param max
* @return Vector2D
*/
public function truncate(max:Number):Vector2D {
length = Math.min(max, length);
return this;
}
/**
* 向量反转
* @return Vector2D
*/
public function reverse():Vector2D {
_x = -_x;
_y = -_y;

return this;
}
/**
* 返回是否为单位向量
* @return Boolean
*/
public function isNormalized():Boolean {
return length == 1.0;
}
public function dotProd(v2:Vector2D):Number {
return _x * v2.x + _y * v2.y;
}
public function crossProd(v2:Vector2D):Number {
return _x * v2.y - _y * v2.x;
}
/**
* 返回两个向量的角度
* @param v1
* @param v2
* @return Number
*/
public function angleBetween(v1:Vector2D, v2:Vector2D):Number {
if (!v1.isNormalized()) v1 = v1.clone().normalize();
if (!v2.isNormalized()) v2 = v2.clone().normalize();
return Math.acos(v1.dotProd(v2));
}
/**
*
* @param v2
* @return Vector2D
*/
public function sign(v2:Vector2D):int {
return perp.dotProd(v2) < 0? -1:1;
}
/**
* 返回两个Vector2D之间的距离
* @param v2
* @return Number
*/
public function dist(v2:Vector2D):Number {
return Math.sqrt(distSQ(v2));
}
/**
* 返回向量的平方值
* @param v2
* @return Number
*/
public function distSQ(v2:Vector2D):Number {
var dx:Number = v2.x - x;
var dy:Number = v2.y - y;
return dx * dx + dy * dy;
}
/**
* 加上向量v2
* @param v2
* @return Vector2D
*/
public function add(v2:Vector2D):Vector2D {
return new Vector2D(_x + v2.x, _y + v2.y);
}
/**
* 减去向量v2
* @param v2
* @return Vector2D
*/
public function substract(v2:Vector2D):Vector2D {
return new Vector2D(_x - v2.x, _y - v2.y);
}
/**
* 乘以向量value
* @param value
* @return Vector2D
*/
public function multiply(value:Number):Vector2D {
return new Vector2D(_x * value, _y * value);
}
/**
* 除以向量value
* @param value
* @return Vector2D
*/
public function divide(value:Number):Vector2D {
return new Vector2D(_x/value,_y/value);
}
/**
* 判断两个向量是否相同
* @param v2
* @return
*/
public function equals(v2:Vector2D):Boolean {
return _x == v2.x && _y == v2.y;
}
public function toString():String {
return "[Vector2D(x:" + _x + ",y:" + _y + ")]";
}
}
}

----vehicle基类
package vector.steering
{
import flash.display.Sprite;

public class Vehicle extends Sprite
{
protected var _edgeBehavior:String = WRAP;
protected var _mass:Number = 1.0; //质量
protected var _maxSpeed:Number = 10;
protected var _position:Vector2D; //位置向量
protected var _velocity:Vector2D; //速度向量

public static const WRAP:String = "wrap";
public static const BOUNCE:String = "boounce";

public function Vehicle(){
_position = new Vector2D();
_velocity = new Vector2D();
draw();
}

protected function draw():void{
graphics.clear();
graphics.lineStyle(0);
graphics.moveTo(10, 0);
graphics.lineTo(-10, 5);
graphics.lineTo(-10, -5);
graphics.lineTo(10, 0);
}

public function update():void{
_velocity.truncate(_maxSpeed); //限制最大速度
_position = _position.add(_velocity); //添加速度向量

if(_edgeBehavior == WRAP){
wrap();
}else if(_edgeBehavior == BOUNCE){
bounce();
}

//更新机车类坐标
x = position.x;
y = position.y;

//更新转向速度
rotation = _velocity.angle * 180/Math.PI;
}

/**
* 碰到墙壁,反弹
* 直接更改相反方向的向量坐标
*/
public function bounce():void{
if(stage != null){
if(position.x > stage.stageWidth){
position.x = stage.stageWidth;
velocity.x *= -1;
}else if(position.x < 0){
position.x = 0;
velocity.x *= -1;
}

if(position.y > stage.stageHeight){
position.y = stage.stageHeight;
velocity.y *= -1;
} else if(position.y < 0) {
position.y = 0;
velocity.y *= -1;
}
}
}

public function wrap():void{
if(stage != null){
if(position.x > stage.stageWidth) position.x = 0;
if(position.x < 0) position.x = stage.stageWidth;
if(position.y > stage.stageHeight) position.y = 0;
if(position.y < 0) position.y = stage.stageHeight;
}
}

public function set edgeBehavior(value:String):void{
_edgeBehavior = value;
}

public function get edgeBehavior():String{
return _edgeBehavior;
}

public function set mass(value:Number):void{
_mass = value;
}

public function get mass():Number{
return _mass;
}

public function set maxSpeed(value:Number):void{
_maxSpeed = value;
}

public function get maxSpeed():Number{
return _maxSpeed;
}

public function set position(value:Vector2D):void{
_position = value;
x = _position.x;
y = _position.y;
}

public function get position():Vector2D{
return _position;
}

public function set velocity(value:Vector2D):void{
_velocity = value;
}

public function get velocity():Vector2D{
return _velocity;
}

override public function set x(value:Number):void{
super.x = value;
_position.x = x;
}

override public function set y(value:Number):void{
super.y = value;
_position.y = y;
}
}
}

----SteeredVehicle机车子类
package vector.steering
{
public class SteeredVehicle extends Vehicle
{
private var _maxForce:Number = 1; //旋转力
private var _steeringForce:Vector2D; //作为叠加后的转向合力

public function SteeredVehicle()
{
_steeringForce = new Vector2D();
super();
}

public function set maxForce(value:Number):void{
_maxForce = value;
}

public function get maxForce():Number{
return _maxForce;
}
/**
* 主要控制旋转力
*/
override public function update():void{
_steeringForce.truncate(_maxForce);
_steeringForce = _steeringForce.divide(_mass);
_velocity = _velocity.add(_steeringForce);
_steeringForce = new Vector2D();
super.update();
}

/**
* 寻找行为 把机车移动到指定点
*/
public function seek(target:Vector2D):void{
var desiredVelocity:Vector2D = target.substract(_position);
desiredVelocity.normalize();
desiredVelocity = desiredVelocity.multiply(_maxSpeed);
var force:Vector2D = desiredVelocity.substract(_velocity);
_steeringForce = _steeringForce.add(force);

}
}
}

---测试类
package vector.chapter1
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;

import vector.steering.SteeredVehicle;
import vector.steering.Vector2D;

public class SeekTest extends Sprite
{
private var _vehicle:SteeredVehicle;

public function SeekTest()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

_vehicle = new SteeredVehicle();
addChild(_vehicle);

addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function onEnterFrame(event:Event):void{
_vehicle.seek(new Vector2D(mouseX, mouseY));
_vehicle.update();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: