Hi guys.
I created a small Tentacle class which follows given entity (mouse x,y in this case). It is also able to detect collision. You can see the example here
package
{
import flash.geom.Point;
import net.flashpunk.Entity;
import net.flashpunk.FP;
import net.flashpunk.utils.Draw;
import net.flashpunk.utils.Input;
import net.flashpunk.utils.Key;
/**
* ...
* @author Marko Cetinic
*/
public class Tentacle extends Entity
{
public static const TYPE:String = "tentacle";
public static const TENTICLE_COLOR:uint = 0xCDBE7A;
protected var _target:Entity;
protected var _distance:int;
protected var _maxDistance:int;
protected var _speed:int;
protected var _waveHeight:int;
protected var _maxWaveHeight:int;
protected var _waveLenght:int;
protected var _maxWaveLenght:int;
protected var _tentacleRadius:int;
/**
* Tentacle growt direction. +1 to grow out, -1 to shrink
*
* @see changeGrowthDirection()
*/
protected var _growthDirection:int=1;
protected var _tentacleArr:Array;
/**
* Helper x coordinate point
*
* @see returnSineWavePoint()
*/
private var _x:int;
/**
* Helper y coordinate point
*
* @see returnSineWavePoint()
*/
private var _y:int;
/**
* Tentacle class constructor.
*
* @param target Tearget to hit with tentacle.
* @param distance Tentacle distance.
* @param speed Tentcle creation speed.
* @param tentacleRadius Tentacle elem radius.
* @param waveHeight Amplitude or Wave height.
* @param waveLength Period or Wave length.
*
*/
public function Tentacle(target:Entity, distance:int, speed:int=2, waveHeight:int=6, waveLenght:int=20, tentacleRadius:int=5)
{
super();
this._target = target;
this._speed = speed;
this._maxDistance = distance;
this._maxDistance = _maxDistance / _speed;
this._distance = 0;
this._waveHeight = waveHeight;
this._maxWaveHeight = this._waveHeight;
this._waveLenght = waveLenght;
this._maxWaveLenght = this._waveLenght;
this._tentacleRadius = tentacleRadius;
}
/**
* Change the growth direction of tentacle
*/
public function changeGrowthDirection():void
{
this._growthDirection *= -1;
}
/**
* Check for any tenticle collison.
*
* @param entity Entity that could collide with tenticle.
* @return TRUE if enitiy collides with tenticle, else FALSE.
*/
public function checkForCollision(entity:Entity):Boolean
{
for each(var collisionElem:Entity in this._tentacleArr)
if (collisionElem.collideTypes(entity.type, collisionElem.x, collisionElem.y) != null)
{
return true;
break;
}
return false;
}
/**
* Returns sinus wave tentacle point. ( y = A * sin(B/x) + yInit ).
*
* @param speed Speed of the entity movement.
* @param waveHeight Amplitude or Wave height.
* @param waveLength Period or Wave length.
* @param waveLength Y coordinate starting position
*
* @return New sinus wave point.
*
*/
protected function returnSineWavePoint(speed:int, waveHeight:int, waveLength:int, yStartPosition:int):Point
{
this._x += speed;
this._y = (waveHeight * Math.sin(this._x / waveLength)) + yStartPosition;
var followX:int = this._target.x + this._target.halfWidth;
var followY:int = this._target.y + this._target.halfHeight;
var deltaX:int = followX - this.x;
var deltaY:int = followY - this.y;
var bearing:int = Math.atan2(deltaY, deltaX) * 180 / Math.PI;
var rotation:Number = bearing * Math.PI / 180;
var rX:int = Math.cos(rotation) * (this._x - this.x) - Math.sin(rotation) * (this._y - this.y) + this.x;
var rY:int = Math.sin(rotation) * (this._x - this.x) + Math.cos(rotation) * (this._y - this.y) + this.y;
return new Point(rX, rY);
}
override public function render():void
{
super.render();
var collisionEntity:Entity;
//remove all tenticle entites from the last render
for each(collisionEntity in _tentacleArr)
this.world.remove(collisionEntity);
_tentacleArr = new Array;
//Draw new tentacle
var sineWavePoint:Point;
for (var theta:Number = 0; theta < this._distance; theta += 1)
{
sineWavePoint = returnSineWavePoint(this._speed, this._waveHeight, this._waveLenght, this.y);
Draw.circlePlus(sineWavePoint.x, sineWavePoint.y, this._tentacleRadius, 0xC8B188, 1, true, 1);
if (theta % (this._tentacleRadius * 2) == 0)
{
collisionEntity = new Entity;
collisionEntity.x = sineWavePoint.x;
collisionEntity.y = sineWavePoint.y;
collisionEntity.setHitbox(this._tentacleRadius * 2, this._tentacleRadius * 2, this._tentacleRadius, this._tentacleRadius);
_tentacleArr.push(collisionEntity);
this.world.add(collisionEntity);
}
}
//If players X position smaller than max distance start shrinking the tentacle
if (this._distance >= this._maxDistance || this._distance < 0)
this._growthDirection *= -1;
if (this._distance < 0)
{
this._waveHeight = Math.random() * this._maxWaveHeight + this._maxWaveHeight - 3;
this._waveLenght = Math.random() * this._maxWaveLenght + this._maxWaveLenght - 2;
}
this._distance += this._growthDirection;
//helpers for returnSineWavePoint function
this._x = this.x;
this._y = this.y;
}
}
}