createCanvas(windowWidth, windowHeight);
colorMode(HSB, 360, 100, 100);
player = new p5.Vector();
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
background(color(HUE, 40, 50 + sin(time * speed) * 10));
translate(width / 2, height / 2);
translate(-width / 2, -height / 2);
depth = Math.min(depth + maxDepth * introSpeed, maxDepth);
maxDepth = speed + defaultMaxDepth;
let amt = 0.01 * speed + 0.012;
if (keyIsDown(LEFT_ARROW)) player.x -= amt;
if (keyIsDown(RIGHT_ARROW)) player.x += amt;
drawSpaceship(player.x, player.y + 10, 10, new p5.Vector(width / 2, height / 2), true);
maxspeed = Math.min(maxspeed, speed);
depth -= maxDepth * introSpeed * 2;
text("Speed: " + round(1000 * speed), 10, 10);
text("Highest: " + round(1000 * highestSpeed), 10, 30);
highestSpeed = Math.max(highestSpeed, speed);
maxDepth = defaultMaxDepth;
for (let i = 0; i < pathLength; i++) {
let vtRotat = vt / 200000;
let target = new p5.Vector(targetX, targetY);
if (abs(target.x - cercleX) < 10 && abs(target.y - cercleY) < 10) {
target = newTarget(target);
anglCourt = TWO_PI - abs(angl);
if (angl > 0) anglCourt = -anglCourt;
if (direct < anglCourt + (rotat * vt)) direct += rotat * vt;
if (direct >= anglCourt) direct -= rotat * vt;
if (direct === 0) rotat = 0;
angl1 = atan2(target.y - cercleY, target.x - cercleX);
cercleX += (cos(direct + angl2) * vt);
cercleY += (sin(direct + angl2) * vt);
if (angl > 0) pathR[i] += rotat;
else if (angl < 0) pathR[i] -= rotat;
return new p5.Vector(cercleX, cercleY);
newT.x += sin(o * TWO_PI) * (r * maxRayon + minRayon);
newT.y += cos(o * TWO_PI) * (r * maxRayon + minRayon);
let l = (pathLength / step - 2),
cam = new p5.Vector(-path[0].x, -path[0].y);
for (let i = l; i >= 0; i--) {
let h = int(i * step + inc),
h1 = int((i + 1) * step + inc),
s = height / 2 / (1 + depth * h),
x = (path[h].x + cam.x) / s + width / 2,
y = (path[h].y + cam.y) / s + height / 2,
s1 = height / 2 / (1 + depth * (h1)),
x1 = (path[h1].x + cam.x) / s1 + width / 2,
y1 = (path[h1].y + cam.y) / s1 + height / 2;
if (i === 0) tube(x, y, height / 2, pathR[h - inc], x1, y1, s1, pathR[h1], 100 / h1);
else tube(x, y, s, pathR[h], x1, y1, s1, pathR[h1], 100 / h1);
for (npc of npcs) npc.draw(h, new p5.Vector(x, y));
function tube(x, y, s, r, x1, y1, s1, r1, c) {
let p = TWO_PI / float(N_sides);
for (let i = 0; i < N_sides; i++) {
let clr = color(HUE, 14 + c - cs * 14, 50 + c + cs * 30);
quad(x + sin(ip + r) * s, y + cs * s, x1 + sin(ip + r1) * s1, y1 + cos(ip + r1) * s1, x1 + sin(ip1 + r1) * s1, y1 + cos(ip1 + r1) * s1, x + sin(ip1 + r) * s, y + cos(ip1 + r) * s);
for (let h = 0; h < playerLastPos.length - 1; h++) {
playerLastPos[h] = playerLastPos[h + 1];
playerLastPos[playerLastPos.length - 1] = player.x;
for (let j = 0; j < m; j++) {
for (let i = 0; i < pathLength - 1; i++) {
path[pathLength - 1] = newPath(pathLength - 1);
for (let npc of npcs) npc.update();
function drawSpaceship(x, y, L, n, p) {
while (pX < 0) pX += N_sides;
let s = height / 2 / (1 + depth * y);
let o = (int(pX) + 0.5) * (TWO_PI / N_sides) + pathR[L];
let tx = (pX % 1 - 0.5) * l;
triangle(0, 0, 0, -1, 0.2, -0.2);
triangle(0, -1, -1, 0, -0.2, -0.2);
triangle(0, 0, 0, -1, -0.2, -0.2);
triangle(0, -1, 1, 0, 0.2, -0.2);
s = 0.2 + sin(time * speed) * 0.05;
ellipse(-0.5, -0.1, s, s);
ellipse(0.5, -0.1, s, s);
if (random() < NPC_chance) npcs.push(new NPC());
this.p = new p5.Vector(random(0, 1), pathLength);
this.spd = new p5.Vector(0.002 * random(-1, 1), random(-1, -0.5));
if (h <= this.p.y && this.p.y <= h + step)
drawSpaceship(this.p.x, this.p.y, int(this.p.y), n, false);
if (0 < this.p.y && this.p.y < 16) {
if (abs(this.p.x - player.x) < 0.03) {
if (this.p.y < -1000) npcs.shift();