Math.DEGREE_IN_RAD = 0.0174532925199433;
Movieclip.prototype.drawCircle = function(r, x, y) {
var rx = r+x, ry = r+y, xr = x-r, yr = y-r;
var r07 = r*0.7071, r04 = r*0.4142;
this.moveTo(rx, y);
this.curveTo(rx, r04+y, r07+x, r07+y);
this.curveTo(r04+x, ry, x, ry);
this.curveTo(x-r04, ry, x-r07, r07+y);
this.curveTo(xr, r04+y, xr, y);
this.curveTo(xr, y-r04, x-r07, y-r07);
this.curveTo(x-r04, yr, x, yr);
this.curveTo(r04+x, yr, r07+x, y-r07);
this.curveTo(rx, y-r04, rx, y);
};
function Critter() {
this.init();
}
Critter.prototype = new MovieClip();
o = Critter.prototype;
o.init = function() {
this.radius = 4;
this.clr = 0x000000;
this.rate = 10; // bestimmt wie schnell sich die Bewegungsrichtung ändert
this.steeringCircleRadius = 10 // bestimmt wie groß die Änderung maximal ist
this.steeringCircleDistance = 80; // bestimmt die Auswirkung der Änderung
this.force = 10; // bestimmt wie schnell das Teil hier ist
this.distanceForCollisionCheck = this.force * 4; //wie weit vorraus soll gecheckt werden
//für das verhalten unwichtig, dient nur zur Anzeige
// der letzten Kollisionspunkte
this.collisionCount = 0;
this.maxPointsOfCollisionstoDraw = 10;
this.steeringVector = {};
this.targetVector = {};
//Umgebung-->sollte via set gesetzt werden
this.environment = _root.environment;
//neuer Richtungsvektor
var x = Math.random() * Stage.width;
var y = Math.random() * Stage.height;
x *= (Math.random() > 0.5) ? -1 : 1;
y *= (Math.random() > 0.5) ? -1 : 1;
//normalisieren
var l = Math.sqrt((x * x) + (y * y));
x *= 1 / l;
y *= 1 / l;
//auf Kreis projezieren
x *= this.steeringCircleRadius;
y *= this.steeringCircleRadius;
x += this.steeringCircleDistance
//Steuerungsvektor festlegen
this.steeringVector.x = x;
this.steeringVector.y = y;
//und action...
this.onEnterFrame = this.think;
}
o.think = function() {
//var t = getTimer();
if(this.collisionCount > this.maxPointsOfCollisionsToDraw) {
_root.clear();
updateAfterEvent();
this.collisionCount = 0;
}
this.newTarget();
if(this.detectPossibleCollision()) {
this.collisionCount++;
this.rotateToCleanTarget(this.getCurrentRotationInRad());
}
this.seek();
this.paint();
//trace(getTimer() - t);
}
o.paint = function() {
this.clear();
//Kreis auf den der Steuerrungsvektor projeziert wird zeichen
this.lineStyle(1,0x000000);
this.drawCircle(this.steeringCircleRadius,this.steeringCircleDistance, 0);
//kleinen Punkt zeichnen
this.beginFill(this.clr);
this.drawCircle(this.radius, 0, 0);
this.endFill();
//den Steuerungsvektor zeichnen
this.moveTo(0,0)
this.lineStyle(1,0xFF0000);
this.lineTo(this.steeringVector.x, this.steeringVector.y)
}
o.newTarget = function() {
//neuer Richtunsvektor
var x = Math.random() * Stage.width;
var y = Math.random() * Stage.height;
x *= (Math.random() > 0.5) ? -1 : 1;
y *= (Math.random() > 0.5) ? -1 : 1;
//wenn Länge größer als maximal erlaubte Änderung, skalieren
var l = Math.sqrt((x * x) + (y * y));
if(l > this.rate) {
x *= 1 / l;
y *= 1 / l;
x *= this.rate;
y *= this.rate;
}
//den alten hinzu addieren
x += this.steeringVector.x;
y += this.steeringVector.y;
//wieder auf den Kreis projezieren
x -= this.steeringCircleDistance;
l = Math.sqrt((x * x) + (y * y));
x *= 1 / l;
y *= 1 / l;
x *= this.steeringCircleRadius;
y *= this.steeringCircleRadius;
x += this.steeringCircleDistance;
//neuer Steuerungsvektor
this.steeringVector.x = x;
this.steeringVector.y = y;
//in Weltkoordinaten umrechnen
var p = {x: x, y: y};
this.localToGlobal(p);
this.targetVector.x = Math.round(p.x);
this.targetVector.y = Math.round(p.y);
}
o.seek = function() {
//Winkel zum Ziel in rad
var rad = this.getCurrentRotationInRad();
//rotation anpassen
this._rotation = (rad * 180) / Math.PI;
//position updaten
this._x += this.getAppliedForce() * Math.cos(rad);
this._y += this.getAppliedForce() * Math.sin(rad);
//wrap around
this._x %= Stage.width;
this._y %= Stage.height;
if(this._x < 0) {
this._x = Stage.width;
}
if(this._y < 0) {
this._y = Stage.height;
}
}
o.detectPossibleCollision = function() {
//neue Position bestimmen
var pt = this.getPossiblePointOfCollision(this.getCurrentRotationInRad());
//schauen ob diese innerhalb eines Hindernisses liegt
if(this.environment.hitTest(pt.x,pt.y, true)){
this.drawPointOfCollision(pt.x, pt.y);
return true;
}
return false;
}
o.rotateToCleanTarget = function(rad) {
//um jeweils 2 Grad pro Aufruf drehen
rad += Math.DEGREE_IN_RAD * 2
var pt = this.getPossiblePointOfCollision(rad);
if(this.environment.hitTest(pt.x, pt.y, true)) {
this.drawWrongDecision(pt.x, pt.y)
this.rotateToCleanTarget(rad)
} else {
this.targetVector.x = pt.x;
this.targetVector.y = pt.y;
}
}
o.drawPointOfCollision = function(x, y) {
_root.lineStyle(1,0xFF0000);
_root.drawCircle(this.radius,x, y);
}
o.drawWrongDecision = function(x, y) {
_root.moveTo(this._x, this._y);
_root.lineStyle(1,0x0000FF);
_root.lineTo(x, y);
}
o.getCurrentRotationInRad = function() {
var dx = this.targetVector.x - this._x;
var dy = this.targetVector.y - this._y;
return Math.atan2(dy, dx);
}
o.getPossibleTarget = function(rad) {
var nx = this._x + (this.getAppliedForce() * Math.cos(rad));
var ny = this._y + (this.getAppliedForce() * Math.sin(rad));
return {x: nx, y: ny};
}
o.getPossiblePointOfCollision = function(rad) {
var nx = this._x + (this.distanceForCollisionCheck * Math.cos(rad));
var ny = this._y + (this.distanceForCollisionCheck * Math.sin(rad));
return {x: nx, y: ny};
}
o.getAppliedForce = function() {
//distanz zum Ziel
var d = this.getDistanceToTarget();
var possibleForce = Math.round(d / 2);
return (possibleForce > this.force) ? this.force : possibleForce;
}
o.getDistanceToTarget = function() {
var dx = this.targetVector.x - this._x;
var dy = this.targetVector.y - this._y;
return Math.sqrt((dx * dx) + (dy * dy));
}
delete o;
Object.registerClass("critter",Critter);
c = _root.attachMovie("critter", "c", 1);
c._x = 200;
c._y = 200;
stop();