У меня есть пруд с водой, в котором рыбы переходят в «корм», в настоящее время у меня возникли проблемы с тем, чтобы он выглядел реалистично, когда еда сбрасывается, все рыбы движутся к ней с одинаковой скоростью, и своего рода «дрейф», как дрейфующий автомобиль, когда он приближается к еде и поворачивается к ней. Могу ли я знать, что не так? я думаю, что это из-за силы сопротивления, которую я применил, но если я не буду применять ее, vx и vy будут складываться в больших количествах.
ссылка ниже содержит файл .swf, я также добавил функции, необходимые для перемещения рыбы.
http://www.swfcabin.com/open/1310970656
package
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.filters.DropShadowFilter;
import flash.events.TouchEvent;
import flash.media.Sound;
import flash.text.TextField;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Point;
/**
* ...
* @author Z
* Fish class, makes fishes behaviors, find food.
*/
public class Fish extends MovieClip
{
//food var
private var foodTarget:Food;
public var foodDroppedArray:Array = new Array();
public var foodDistArray:Array = new Array();
private var foodInPond :int = 0;
private var foodLocationDegrees:Number;
//fish variables
private var _fishSwimMax:Number = 3;
private var _fishDrag:Number = 0.95;
private var _fishSwimSpeed:Number;
private var _destinationX:int;
private var _destinationY:int;
private var _minX:Number = 0;
private var _minY:Number = 0;
private var _maxX:Number = 1024;
private var _maxY:Number = 768;
private var _vx:Number = 0;
private var _vy:Number = 0;
private var _dx:Number = 0;
private var _dy:Number = 0;
private var foodropSound:foodSound = new foodSound();
//global
public var otherFishes:Array = new Array();
public var hit :MovieClip;
private var foodRipple:Rippler;
private var _bg:Background;
private var number:Number;
private var _easeSpeed:Number;
public function Fish()
{
foodropSound = new foodSound();
getRandomDestination();
//fish starting settins
this.x = _maxX/2;//Math.random();
this.y = _maxY/2;//Math.random();
_fishSwimSpeed = Math.ceil(Math.random() * 1000) +500;
trace("fish speed "+_fishSwimSpeed);
//set up shadow
setUpShadow();
//adding listener
this.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event):void
{
updateCollision();
//getDistance(this.x - i.x, this.y - i.y)
if(foodDroppedArray.length > 0)
{
moveToFood(getSmallestVal(foodDroppedArray));
trace("moving to smallest distance of all food");
return;
}else
{
swimAround();
}
}
/***
* Fish to move to food with easing.
* */
public function moveToFood(targetFood:Food):void
{
_vx += (targetFood.x - this.x)/_fishSwimSpeed;
_vy += (targetFood.y - this.y) / _fishSwimSpeed;
//food calculations, distance, angle etc
var a:Number = targetFood.x - x;
var b:Number = targetFood.y - y;
var ang:Number = Math.atan2(b, a);
//rotation to food
var foodLoc:Number = (ang * 180 / Math.PI);
var foodFinalLoc:Number = foodLoc - rotation;
if (foodFinalLoc > 180) foodFinalLoc -= 360;
else if (foodFinalLoc < -180) foodFinalLoc += 360;
rotation += foodFinalLoc / 10;
//acceleratin to food
//moving towards food.
_vx *= _fishDrag;
_vy *= _fishDrag;
this.x += _vx;
this.y += _vy;
//removing food when both hit boxes hit
if (hit.hitTestObject(targetFood.hit))
{
foodropSound.play();
foodDroppedArray.splice(foodDroppedArray.indexOf(targetFood), 1);
targetFood.removeSelf();
}
}
/**
* Calculate Position
*/
public function swimAround():void
{
//move to a random destionation point.
_dx = this.x - _destinationX;
_dy = this.y - _destinationY;
// when the fish is near to the distance by * a new dest will be generated.
if (getDistance(_dx, _dy) < 200)
{
getRandomDestination();
}else {
_vx += (_destinationX - this.x) / _fishSwimSpeed;
_vy += (_destinationY - this.y) / _fishSwimSpeed;
//calculation of distance to use for calculation of angle to face to
var a:Number = _destinationX - x;
var b:Number = _destinationY - y;
var ang:Number = Math.atan2(b, a);
//location to face to through the angle calculation.
var targetLoc:Number = (ang * 180 / Math.PI);
var finalRoc:Number = targetLoc - rotation;
if (finalRoc > 180) finalRoc -= 360;
else if (finalRoc < -180) finalRoc += 360;
rotation += finalRoc / 15;
//apply drag then move.
_vx *= _fishDrag;
_vy *= _fishDrag;
this.x += _vx;
this.y += _vy;
}
}
public function foodDropped(foodArray:Array):void
{
foodDroppedArray = foodArray;
trace("food have been dropped and lenghth is "+foodDroppedArray.length);
}
/**
*Get smallest value of food distance in this array
*/
private function getSmallestVal(a:Array):Food
{
//we assume first food is the smallest distance between fish
var n : Food = a[0];
if (a.length == 1)
{
return a[0];
}
else {
for each(var i : Food in a)
{
if (getDistance(this.x - i.x , this.y - i.y) < getDistance(this.x - n.x , this.y - n.y))
{
n = i;
}
}
return n;
}
}
/**
* Get random food
*/
private function getRandomFood():Food
{
var i: int = foodDroppedArray.length;
var n : Number = Math.ceil(i * Math.random()) - 1;
trace(" in random food "+n );
return foodDroppedArray[n];
}
/**
* Calculates a random destination based on stage size
*/
private function getRandomDestination():void
{
_destinationX = (Math.random()* _maxX);
_destinationY = (Math.random() * _maxY);
}
public function getDistance(delta_x:Number, delta_y:Number):Number
{
return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
}
}
}