86 lines
1.8 KiB
JavaScript
86 lines
1.8 KiB
JavaScript
|
class State {
|
||
|
|
||
|
constructor(x, y, color) {
|
||
|
this.x = x;
|
||
|
this.y = y;
|
||
|
this.color = color;
|
||
|
this.text = '';
|
||
|
}
|
||
|
|
||
|
draw() {
|
||
|
ctx.fillStyle = this.color;
|
||
|
ctx.strokeStyle = '#000';
|
||
|
|
||
|
ctx.beginPath();
|
||
|
|
||
|
ctx.arc(this.x, this.y, radius, 0, 360);
|
||
|
ctx.fill();
|
||
|
ctx.stroke();
|
||
|
|
||
|
ctx.closePath();
|
||
|
}
|
||
|
|
||
|
jumpTo(x, y) {
|
||
|
this.x = Math.min(Math.max(x, 0), width);
|
||
|
this.y = Math.min(Math.max(y, 0), height);
|
||
|
}
|
||
|
|
||
|
moveTo(x, y) {
|
||
|
x = Math.min(Math.max(0, x), width);
|
||
|
y = Math.min(Math.max(0, y), height);
|
||
|
|
||
|
this.goal = {
|
||
|
x, y
|
||
|
};
|
||
|
|
||
|
const angle = this.direction(x, y);
|
||
|
|
||
|
this.v = {
|
||
|
x: settings.speed * Math.cos(angle),
|
||
|
y: settings.speed * Math.sin(angle)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
moveToStep() {
|
||
|
this.x += this.v.x;
|
||
|
this.y += this.v.y;
|
||
|
|
||
|
if ((this.v.x > 0 && this.goal.x <= this.x) || (this.v.x < 0 && this.goal.x >= this.x)) {
|
||
|
this.x = this.goal.x;
|
||
|
this.v.x = 0;
|
||
|
}
|
||
|
|
||
|
if((this.v.y > 0 && this.goal.y <= this.y) || (this.v.y < 0 && this.goal.y >= this.y)) {
|
||
|
this.y = this.goal.y;
|
||
|
this.v.y = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
intersection(state) {
|
||
|
return -Math.hypot(this.x - state.x, this.y - state.y) + radius * 2;
|
||
|
}
|
||
|
|
||
|
intersects(state) {
|
||
|
return this.intersection(state) > 0;
|
||
|
}
|
||
|
|
||
|
directionTo(state) {
|
||
|
return this.direction(state.x, state.y);
|
||
|
}
|
||
|
|
||
|
direction(x, y) {
|
||
|
return Math.atan2(this.y - y, this.x - x);
|
||
|
}
|
||
|
|
||
|
closestPointOnCircle(x, y) {
|
||
|
const dx = x - this.x;
|
||
|
const dy = y - this.y;
|
||
|
const scale = Math.sqrt(dx ^ 2 + dy ^ 2);
|
||
|
return {
|
||
|
x: this.x + dx * radius / scale,
|
||
|
y: this.y + dy * radius / scale,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
}
|