Parallax-Bicycle/HillSet.js

97 lines
2.9 KiB
JavaScript

"use strict";
class HillSet
{
constructor(inSize, inHeightRange, inColour, inSpeed)
{
if(typeof inSize != "object") inSize = new Vector(2048, 1024);
if(typeof inHeightRange != "number") inHeightRange = 0.4;
if(typeof inColour != "string") inColour = "green";
if(typeof inSpeed != "number") inSpeed = 30;
this.pos = new Vector(0, 0);
this.startPos = this.pos.clone();
this.size = inSize;
this.colour = inColour;
this.speed = inSpeed; // in pixels per second
this.heightRangeMultiplier = inHeightRange;
this.heightRange = this.heightRangeMultiplier * this.size.y;
this.controlPointInterval = 128; // Must devide exactly into pos.size.x
this.generate();
}
generate()
{
this.controlPoints = [];
for (let x = 0, i = 0; x <= this.size.x; x += this.controlPointInterval, i++)
{
this.controlPoints.push(new Vector(
x + (i !== 0 ? random(25) : 0),
random(this.heightRange) + ((random(2) == 0) ? ((this.size.y - this.heightRange) * random(0.5, 1, true)) : 0)
));
}
// Make everything as seamless as possible
this.hillLine = new SmoothLine();
this.hillLine.add(this.controlPoints[this.controlPoints.length - 3].clone().subtract(new Vector(this.size.x * 2, 0)));
this.hillLine.add(this.controlPoints[this.controlPoints.length - 2].clone().subtract(new Vector(this.size.x * 2, 0)));
// TODO: Add a few points before this to make th smooth line join up upon reset correctly
var prevPoints = [];
for(let point of this.controlPoints)
prevPoints.push(point.clone().subtract(new Vector(this.size.x, 0)));
prevPoints.pop(); // Remove the last point because it's essentially the same as the first regular point
this.hillLine.add(prevPoints); // The points to the left
this.hillLine.add(this.controlPoints); // Add the regular points
}
/**
* Updates the hillset ready for the next frame.
* @param {number} dt The number of seconds since the last frame.
*/
update(dt)
{
this.pos.x += this.speed * dt;
if(this.pos.x >= this.size.x)
// console.log("Reset");
this.pos.x = 0;
}
render(context)
{
context.save();
context.translate(this.pos.x, this.pos.y);
/*context.fillStyle = "red";
context.beginPath();
context.ellipse(0, 0, 10, 10, 0, 0, Math.PI * 2, false);
context.fill();*/
context.beginPath();
context.moveTo(0, this.size.y);
context.lineTo(-this.size.x, this.size.y);
/*for(let point of this.controlPoints)
{
context.lineTo(point.x, point.y);
}*/
this.hillLine.line(context, 16);
context.lineTo(this.size.x, this.size.y);
context.closePath();
context.fillStyle = this.colour;
context.fill();
context.restore();
}
toString()
{
return `HillSet @ ${this.pos} (${this.size}), Control Points x${this.controlPoints.length}: ${this.controlPoints.join(", ")}`;
}
}