terraform/website/source/javascripts/app/Engine.Point.Puller.js

154 lines
2.8 KiB
JavaScript

(function(
Engine,
Vector
){
Engine.Point.Puller = function(id, x, y, shapeSize){
this.id = id;
this.shapeSize = shapeSize;
this.ref = new Vector(x, y);
this.pos = new Vector(
x * shapeSize.x,
y * shapeSize.y
);
this.home = this.pos.clone();
this.accel = Vector.coerce(this.accel);
this.vel = Vector.coerce(this.vel);
};
Engine.Point.Puller.prototype = {
fillStyle: null,
defaultFillstyle: '#b976ff',
chasingFillstyle: '#ff6b6b',
radius: 1,
maxSpeed: 160,
maxForce: 50,
pos: {
x: 0,
y: 0
},
accel: {
x: 0,
y: 0
},
vel: {
x: 0,
y: 0
},
aRad: 200,
safety: 0.25,
resize: function(){
this.home.x = this.pos.x = this.ref.x * this.shapeSize.x;
this.home.y = this.pos.y = this.ref.y * this.shapeSize.y;
return this;
},
update: function(engine){
var target = Vector.coerce(engine.mouse),
distanceToMouse, toHome, mag, safety;
target.x += (this.shapeSize.x - engine.width) / 2;
target.y += (this.shapeSize.y - engine.height) / 2;
distanceToMouse = this.distanceTo(target);
this.accel.mult(0);
if (distanceToMouse < this.aRad) {
this._chasing = true;
this.toChase(target);
this.fillStyle = this.chasingFillstyle;
} else {
this._chasing = false;
this.fillStyle = this.defaultFillstyle;
}
this.toChase(this.home, this.maxForce / 2);
this.vel.add(this.accel);
this.pos.add(
Vector.mult(this.vel, engine.tick)
);
toHome = Vector.sub(this.home, this.pos);
mag = toHome.mag();
safety = this.aRad * (this.safety * 3);
if (mag > this.aRad - safety) {
toHome.normalize();
toHome.mult(this.aRad - safety);
this.pos = Vector.sub(this.home, toHome);
}
target = null;
toHome = null;
return this;
},
toChase: function(target, maxForce){
var desired, steer, distance, mult, safety;
maxForce = maxForce || this.maxForce;
target = Vector.coerce(target);
desired = Vector.sub(target, this.pos);
distance = desired.mag();
desired.normalize();
safety = this.aRad * this.safety;
if (distance < safety) {
mult = Engine.map(distance, 0, safety, 0, this.maxSpeed);
} else if (distance > this.aRad - safety){
mult = Engine.map(this.aRad - distance, 0, safety, 0, this.maxSpeed);
} else {
mult = this.maxSpeed;
}
desired.mult(mult);
steer = Vector.sub(desired, this.vel);
steer.limit(maxForce);
this.accel.add(steer);
target = null;
desired = null;
steer = null;
},
draw: function(ctx, scale){
ctx.fillStyle = this.fillStyle;
ctx.fillRect(
(this.pos.x - this.radius / 2) * scale >> 0,
(this.pos.y - this.radius / 2) * scale >> 0,
this.radius * scale,
this.radius * scale
);
return this;
},
distanceTo: function(target) {
var xd = this.home.x - target.x;
var yd = this.home.y - target.y;
return Math.sqrt(xd * xd + yd * yd );
}
};
})(
window.Engine,
window.Vector
);