const accelFunction = {
get vel() { return new Vec2(0, 0) },
speed: 0,
acceleration: 0.1,
maxSpeed: 4,
// drag constants
drag: 1 - 0.0241,
overSpeedDrag: 1 - 0.0291,
// pulldown constants;
overSpeed: 5,
pullDown: 0.1,
update() {
if (this.method === DRAG) { // Drag method
this.speed *= this.speed > this.maxSpeed ? this.overSpeedDrag: this.drag;
if (this.accelerate) { this.speed += this.acceleration }
} else { // Pull down method
if (this.accelerate && this.speed < this.maxSpeed) { this.speed += this.acceleration }
this.speed = this.speed > this.maxOverSpeed ? this.maxOverSpeed : this.speed;
var speedAdjust = this.speed - this.maxSpeed;
this.speed -= speedAdjust > 0 ? speedAdjust * this.pullDown : 0;
}
// move ship
this.vel.length = this.speed;
this.pos.add(this.vel);
},
}
/* rest of code unrelated to anwser */
requestAnimationFrame(start);
const ctx = canvas.getContext("2d");
const PULL_DOWN = 0;
const DRAG = 1;
var shipA, shipB;
var bgPos;
function Ship(method, control, controlBump) { // creates a Player ship
control.addEventListener("mousedown",() => API.go());
control.addEventListener("mouseup",() => API.coast());
control.addEventListener("mouseout",() => API.coast());
controlBump.addEventListener("click",() => API.bump());
const API = {
...accelFunction,
pos: new Vec2(100, 50 + method * 50),
method, // 0 drag method, 1 pulldown
draw() {
ctx.setTransform(1,0,0,1,this.pos.x - bgPos.x, this.pos.y)
ctx.strokeStyle = "#FFF";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.lineTo(20, 0);
ctx.lineTo(-20, -20);
ctx.lineTo(-20, 20);
ctx.closePath();
ctx.stroke();
ctx.fillText(this.method ? "B" : "A", -11, 3);
ctx.fillText((this.speed * 60 | 0) + "Pps", 80, 3);
if (this.accelerate) {
ctx.strokeStyle = "#FF0";
ctx.beginPath();
ctx.lineTo(-20, -10);
ctx.lineTo(-30 - Math.rand(0,10), 0);
ctx.lineTo(-20, 10);
ctx.stroke();
}
},
focus: false,
reset() {
this.focus = false;
this.vel.zero();
this.pos.init(100, 50 + this.method * 50);
this.speed = 0;
this.accelerate = false;
},
go() {
this.accelerate = true;
this.focus = true;
if (this.method === 1) { shipA.reset() }
else { shipB.reset() }
},
coast() {
this.accelerate = false;
},
bump() {
this.speed += 1;
},
};
return API;
}
function start() {
init();
requestAnimationFrame(mainLoop);
}
function mainLoop() {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,500,170);
shipA.update();
shipB.update();
bgPos.x = shipA.focus ? shipA.pos.x - 50 : shipB.pos.x - 50 ;
drawBG(bgPos);
shipA.draw();
shipB.draw();
requestAnimationFrame(mainLoop);
}
function drawBG(bgPos) {
ctx.fillStyle = "#FFF";
ctx.beginPath();
const bgX = -bgPos.x + 100000;
for (const p of background) {
x = (p.x + bgX) % 504 - 2;
ctx.rect(x, p.y, 2, 2);
}
ctx.fill();
}
const BG_COUNT = 200;
const background = [];
function init() {
ctx.font = "16px arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
bgPos = new Vec2();
shipA = Ship(PULL_DOWN, goA, bumpA);
shipB = Ship(DRAG, goB, bumpB);
var i = BG_COUNT;
while (i--) {
background.push(new Vec2(Math.rand(0, 10000), Math.rand(-1, 170)));
}
}
/* Math LIB Vec2 and math extensions */
Math.rand = (m, M) => Math.random() * (M - m) + m;
function Vec2(x = 0, y = (temp = x, x === 0 ? (x = 0 , 0) : (x = x.x, temp.y))) { this.x = x; this.y = y }
Vec2.prototype = {
init(x, y = (temp = x, x = x.x, temp.y)) { this.x = x; this.y = y; return this },
zero() { this.x = this.y = 0; return this },
add(v, res = this) { res.x = this.x + v.x; res.y = this.y + v.y; return res },
scale(val, res = this) { res.x = this.x * val; res.y = this.y * val; return res },
get length() { return this.lengthSqr ** 0.5 },
set length(l) {
const len = this.lengthSqr;
len > 0 ? this.scale(l / len ** 0.5) : (this.x = l);
},
get lengthSqr() { return this.x * this.x + this.y * this.y },
};
canvas {background: #347;}
div {
position: absolute;
top: 150px;
left: 20px;
}
span { color: white; font-family: arial }
<canvas id="canvas" width="500" height="170"></canvas>
<div>
<button id="goA">Go A</button>
<button id="bumpA">Bump A</button>
<button id="goB">Go B</button>
<button id="bumpB">Bump B</button>
<span> Methods: A = Pull down B = Drag </span>
</div>