我有一个水池,在这里鱼会移动到一个“食物”,目前我的问题看起来很现实,当食物掉落时,所有的鱼都以相同的速度移动,这是一种“漂移”就像一辆汽车漂流,当它靠近食物而旋转时。我可以知道什么是错的吗?我认为这是因为我应用的阻力,但如果我不应用它,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));
}
}
}
我认为问题在于,你正在将一堆运动概念混合在一起,这并不适合。您的加速度基于距离除以500-1500之间的随机数,这是我不太了解的。如果你想要,我可以写一个简单的抵达行为,在moveToFood期间留下拖延。 –
嗨,分区号是随机产生的,这是为了给每个“鱼”一个不同的数字,通过这样做,我希望给每个“鱼”不同的移动速度。这个数字是用来产生缓动效果的,因为鱼越来越近,_vx和_vy会变得更小。现在你说了,我认为它不需要?因为我有* = _ fishDrag。是的,如果你能写一个给我看,并从中学习会很好。 – sutoL