xxxxxxxxxx
191
/* todo
refactor this hideous mess of code into just a list of vectors
where each vector has a range and (delta) speed it can move at (x-axis only)
*/
var target;
var targetsTarget;
var TARGET_SPEED = 1;
var hero;
var heroIntercept;
var HERO_SPEED = 2;
const DEBUG = 1;
const ratio = 1 / 2; // ratio of hero to target speed
var dtt = 0.55;
var dttt = 0.55;
var dth = 0.55;
function setup() {
createCanvas(400, 400);
target = createVector(200, 50);
targetsTarget = createVector(-50, 100);
hero = createVector(200, 300);
heroIntercept = createVector(hero.x, hero.y); // just aim at yourself first.
}
function drawStuff() {
// the target
circle(target.x, target.y, 5);
if (DEBUG) {
point(targetsTarget.x, targetsTarget.y);
}
// the hero
circle(hero.x, hero.y, 7);
}
function updateStuff() {
// update hero;
hero.x += dth;
if (hero.x < 50 || hero.x > 350) {
dth = -dth;
}
// update the potential intercept of the hero with binary search
heroIntercept = findIntercept(hero, target, targetsTarget);
// update target;
target.x -= dtt * ratio;
if (target.x < 50 || target.x > 350) {
dtt = -dtt;
}
// update the targets target;
// this is easier and more like the thing im trying to mimic
// than rotating the targets speed vector or something.
targetsTarget.x -= dttt / ratio;
if (targetsTarget.x < -50 || targetsTarget.x > 450) {
dttt = -dttt;
}
}
// function bestIntercept(hero, target, targetsTarget) {
// var targetVector = p5.Vector.sub(targetsTarget, target);
// for (var turn = 1; turn < 200; turn++) {
// var targetMovement = targetVector.copy().setMag(turn * TARGET_SPEED);
// var target_pos = p5.Vector.add(target, targetMovement);
// // total distance to travel minus the distance we can already travel during these turns
// var turns_to_travel = (hero.dist(target_pos) - (HERO_SPEED * turn)) / HERO_SPEED;
// // target moved whilst we traveled
// targetMovement.setMag(turns_to_travel*TARGET_SPEED)
// var new_target_pos = p5.Vector.add(target_pos, targetMovement)
// var catchup_distance = target_pos.dist(new_target_pos);
// var time_to_catchup = (catchup_distance/HERO_SPEED) +
// }
// }
function vline(v1, v2) {
line(v1.x, v1.y, v2.x, v2.y);
}
function findIntercept(hero, target, targetsTarget) {
var target_heading = p5.Vector.sub(targetsTarget, target);
target_heading.setMag(TARGET_SPEED);
// var [x0, y0] = [target.x+(target_heading.x*-1000),target.y+(target_heading.y*-1000)]
// var [x1, y1] = [target.x+(target_heading.x*1000),target.y+(target_heading.y*1000)]
var fb = p5.Vector.add(target, p5.Vector.mult(target_heading, -1000));
var ff = p5.Vector.add(target, p5.Vector.mult(target_heading, 1000));
// target movement line
push();
stroke(0, 100, 0, 25);
vline(ff, fb);
pop();
var next_pos = p5.Vector.add(target, target_heading);
// next pos is so close to actual pos, it isnt visible like this
// circle(next_pos.x, next_pos.y, 2)
var eta = hero.dist(next_pos) / HERO_SPEED;
target_heading.setMag(eta * TARGET_SPEED);
var actual_pos = p5.Vector.add(target, target_heading);
var extra_distance = next_pos.dist(actual_pos);
var extra_time = extra_distance / HERO_SPEED;
// show where the target would be
push();
stroke(255, 0, 0, 25);
vline(hero, target);
stroke(255, 0, 0, 50);
vline(actual_pos, target);
translate(actual_pos.x, actual_pos.y);
line(-2, 2, 2, -2);
line(-2, -2, 2, 2);
pop();
var best_time = 100000;
var best;
for (var i = 1; i < 250; i += 10) {
i += 1;
target_heading.setMag(TARGET_SPEED * i);
const hero_target = p5.Vector.add(target, target_heading);
const time = (hero.dist(hero_target) - HERO_SPEED * i) / HERO_SPEED;
// target moves whilst hero spends time to get to the target
target_heading.setMag(time * TARGET_SPEED);
// new pos = prev pos + movement whilst hero was walking
const actual_pos = p5.Vector.add(hero_target, target_heading);
const extra_distance = hero_target.dist(actual_pos);
const extra_time = (extra_distance * 2) / HERO_SPEED;
if (time + extra_time < best_time) {
push();
rectMode(CENTER);
translate(hero_target.x, hero_target.y);
rect(0, 0, 2, 2);
pop();
best = hero_target;
}
best_time = min(best_time, time + extra_time);
}
print(`${best_time} was the best time`);
push();
rectMode(CENTER);
translate(best.x, best.y);
rect(0, 0, 5, 5);
pop();
}
// target_heading.setMag(TARGET_SPEED*eta)
// hero_target.add(target_heading)
// vline(hero_target, hero);
// push()
// translate(hero_target.x, hero_target.y);
// line(-2,2,2,-2);
// line(-2,-2,2,2);
// pop();
function draw() {
background(220);
updateStuff();
drawStuff();
}