798 lines
21 KiB
JavaScript
798 lines
21 KiB
JavaScript
// bluepixle.js
|
|
// This library is to help make using canvas tags easier
|
|
|
|
function deg2rad (deg) {
|
|
return ((Math.PI*2)/360)*deg;
|
|
}
|
|
|
|
function rad2deg (rad) {
|
|
return (1/deg2rad(1))*rad;
|
|
}
|
|
|
|
function drift(object) {
|
|
if (object instanceof container) {
|
|
object.direction = "number" == typeof object.direction ?
|
|
object.direction : Math.floor(Math.random()*360);
|
|
object.speed = "number" == typeof object.speed ? object.speed : 1;
|
|
object.move(object.direction,object.speed);
|
|
} else {
|
|
return new TypeError("must provide a container object");
|
|
}
|
|
}
|
|
|
|
function getAngle(ax,ay,bx,by) {
|
|
var deltaX = bx - ax;
|
|
var deltaY = by - ay;
|
|
return rad2deg(Math.atan2(deltaY,deltaX));
|
|
}
|
|
|
|
function reflect(inAngle,surfaceAngle) {
|
|
var normal = surfaceAngle+90;
|
|
var theta1 = normal - inAngle;
|
|
var theta2 = normal + theta1;
|
|
return theta2;
|
|
}
|
|
|
|
function bounce(object, surface, impactTime) {
|
|
object.direction = reflect(object.direction,surface.direction-90);
|
|
object.speed = object.speed;
|
|
}
|
|
|
|
function valueBetween (value,low,high) {
|
|
var Tlow = low <= high ? low : high;
|
|
var Thigh = high >= low ? high : low;
|
|
if ( (value >= Tlow) & (value <= Thigh) ) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function pointInside (x,y,top,right,bottom,left) {
|
|
if ( valueBetween(x,left,right) & valueBetween(y,top,bottom) ) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function collide(objectA,objectB,callBackFunction) {
|
|
var ASpeed = Math.abs(objectA.speed);
|
|
var BSpeed = Math.abs(objectB.speed);
|
|
var simAX = ASpeed <= BSpeed ? objectA.x : objectB.x;
|
|
var simAY = ASpeed <= BSpeed ? objectA.y : objectB.y;
|
|
var simBX = ASpeed <= BSpeed ? objectB.x : objectA.x;
|
|
var simBY = ASpeed <= BSpeed ? objectB.y : objectA.y;
|
|
var simADir = ASpeed <= BSpeed ? objectA.direction : objectB.direction;
|
|
var simBDir = ASpeed <= BSpeed ? objectB.direction : objectA.direction;
|
|
var simASpeed = ASpeed <= BSpeed ? objectA.speed : objectB.speed;
|
|
var simBSpeed = ASpeed <= BSpeed ? objectB.speed : objectA.speed;
|
|
var simAheight = ASpeed <= BSpeed ? objectA.sizeX : objectB.sizeX;
|
|
var simBheight = ASpeed <= BSpeed ? objectB.sizeX : objectA.sizeX;
|
|
var simAwidth = ASpeed <= BSpeed ? objectA.sizeY : objectB.sizeY;
|
|
var simBwidth = ASpeed <= BSpeed ? objectB.sizeY : objectA.sizeY;
|
|
var thetaA = deg2rad(simADir);
|
|
var deltaAX = Math.cos(thetaA)*simASpeed;
|
|
var deltaAY = Math.sin(thetaA)*simASpeed;
|
|
var thetaB = deg2rad(simBDir);
|
|
var deltaBX = Math.cos(thetaB)*simBSpeed;
|
|
var deltaBY = Math.sin(thetaB)*simBSpeed;
|
|
var fastest = Math.max(Math.abs(objectA.speed),Math.abs(objectB.speed));
|
|
for (var t = 0; t <= fastest; t++) {
|
|
var tFraction = t/(fastest+1);
|
|
var Atop = simAY+(tFraction * deltaAY);
|
|
var Abottom = simAY+(tFraction * deltaAY)+simAheight;
|
|
var Aleft = simAX+(tFraction * deltaAX);
|
|
var Aright = simAX+(tFraction * deltaAX)+simAwidth;
|
|
var Btop = simBY+(tFraction * deltaBY);
|
|
var Bbottom = simBY+(tFraction * deltaBY)+simBheight;
|
|
var Bleft = simBX+(tFraction * deltaBX);
|
|
var Bright = simBX+(tFraction * deltaBX)+simBwidth;
|
|
if (
|
|
pointInside(Aleft,Atop,Btop,Bright,Bbottom,Bleft) |
|
|
pointInside(Aright,Atop,Btop,Bright,Bbottom,Bleft) |
|
|
pointInside(Aleft,Abottom,Btop,Bright,Bbottom,Bleft) |
|
|
pointInside(Aright,Abottom,Btop,Bright,Bbottom,Bleft) |
|
|
pointInside(Bleft,Btop,Atop,Aright,Abottom,Aleft) |
|
|
pointInside(Bright,Btop,Atop,Aright,Abottom,Aleft) |
|
|
pointInside(Bleft,Bbottom,Atop,Aright,Abottom,Aleft) |
|
|
pointInside(Bright,Bbottom,Atop,Aright,Abottom,Aleft)
|
|
){
|
|
return callBackFunction(objectA,objectB,t);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function chase (source,target,max,minDis,acc) {
|
|
acc /= 100;
|
|
var sourceCenterX = source.x + (source.sizeX/2);
|
|
var sourceCenterY = source.y + (source.sizeY/2);
|
|
var targetCenterX = target.x + (target.sizeX/2);
|
|
var targetCenterY = target.y + (target.sizeY/2);
|
|
var deltaX = targetCenterX - sourceCenterX;
|
|
var deltaY = targetCenterY - sourceCenterY;
|
|
var theta = Math.atan2(deltaY,deltaX);
|
|
var dis = Math.sqrt(Math.pow(Math.abs(deltaX),2)+Math.pow(Math.abs(deltaY),2));
|
|
var dir = theta;
|
|
if (dis > minDis) {
|
|
dis = dis <= max ? dis : max;
|
|
source.direction = rad2deg(dir);
|
|
source.speed = (dis-minDis)*acc;
|
|
source.move(source.direction,source.speed);
|
|
}
|
|
}
|
|
|
|
function rect (ctx,xOrigin,yOrigin,width,height,fill,stroke,outlineWidth) {
|
|
// Save current defaults
|
|
var local = {};
|
|
local.fillStyle = "string" == typeof ctx.fillStyle ? ctx.fillStyle : undefined;
|
|
local.strokeStyle = "string" == ctx.strokeStyle ? ctx.strokeStyle : undefined;
|
|
local.lineWidth = "number" == ctx.lineWidth ? ctx.lineWidth : undefined;
|
|
// Check inputs
|
|
ctx.fillStyle = "string" == typeof fill ? fill : local.fillStyle;
|
|
ctx.strokeStyle = "string" == typeof stroke ? stroke : "rgba(0,0,0,0)";
|
|
ctx.lineWidth = "number" == typeof outlineWidth ? outlineWidth : 1;
|
|
ctx.fillRect(xOrigin,yOrigin,width,height);
|
|
ctx.strokeRect(xOrigin,yOrigin,width,height);
|
|
// restore context defaults
|
|
ctx.fillStyle = local.fillStyle;
|
|
ctx.strokeStyle = local.strokeStyle;
|
|
ctx.lineWidth = local.lineWidth;
|
|
}
|
|
|
|
function elip (ctx,xOrigin,yOrigin,width,height,fill,stroke,outlineWidth) {
|
|
// Save current defaults
|
|
var local = {};
|
|
local.fillStyle = ctx.fillStyle;
|
|
local.strokeStyle = ctx.strokeStyle;
|
|
local.lineWidth = ctx.lineWidth;
|
|
// Check inputs
|
|
ctx.fillStyle = "string" == typeof fill ? fill : local.fillStyle;
|
|
ctx.strokeStyle = "string" == typeof stroke ? stroke : "rgba(0,0,0,0)";
|
|
ctx.lineWidth = "number" == typeof outlineWidth ? outlineWidth : 1;
|
|
ctx.beginPath();
|
|
ctx.ellipse(xOrigin,yOrigin,width,height,0,0,360);
|
|
ctx.stroke();
|
|
ctx.fill();
|
|
// restore context defaults
|
|
ctx.fillStyle = local.fillStyle;
|
|
ctx.strokeStyle = local.strokeStyle;
|
|
ctx.lineWidth = local.lineWidth;
|
|
}
|
|
|
|
function drawPixel (ctx, x, y, r, g, b, a) {
|
|
// Always validate your input
|
|
if (false == ctx instanceof CanvasRenderingContext2D) {
|
|
return new TypeError("ctx must be a 2D rendering context for canvas.");
|
|
}
|
|
x = x <= ctx.canvas.width ? x : ctx.canvas.width;
|
|
y = y <= ctx.canvas.height ? y : ctx.canvas.height;
|
|
r = r <= 255 ? r : 255;
|
|
r = r >= 0 ? r : 0;
|
|
g = g <= 255 ? g : 255;
|
|
g = g >= 0 ? g : 0;
|
|
b = b <= 255 ? b : 255;
|
|
b = b >= 0 ? b : 0;
|
|
a = a <= 255 ? a : 255;
|
|
a = a >= 0 ? a : 0;
|
|
// Do the thing
|
|
ctx.putImageData(new ImageData(new Uint8ClampedArray([r,g,b,a]),1,1),x,y);
|
|
}
|
|
|
|
class matrix {
|
|
constructor(m,n,matrixArray) {
|
|
if (matrixArray.length != m*n) {
|
|
return new RangeError("the size of the array does not match the size of the matrix!");
|
|
} else {
|
|
this.array = [];
|
|
for (var row = 0; row < m; row++) {
|
|
this.array[row] = [];
|
|
for (var col = 0; col < n; col++) {
|
|
this.array[row][col] = matrixArray[n*row+col];
|
|
}
|
|
}
|
|
this.m = m;
|
|
this.n = n;
|
|
}
|
|
}
|
|
|
|
log() {
|
|
var string = "";
|
|
for (var row = 0; row < this.m; row++) {
|
|
string += "[";
|
|
for( var col = 0; col < this.n; col++) {
|
|
string += this.array[row][col];
|
|
string += ",";
|
|
}
|
|
string += "]";
|
|
console.log(string);
|
|
string = "";
|
|
}
|
|
}
|
|
|
|
add(matrixb) {
|
|
if (
|
|
matrixb.m == this.m &&
|
|
matrixb.n == this.n
|
|
) {
|
|
matrixb.array.forEach( function(row,rowIndex) {
|
|
row.forEach( function(col,colIndex) {
|
|
this.array[rowIndex][colIndex] += col;
|
|
});
|
|
});
|
|
} else {
|
|
throw new RangeError("cannot add matricies of different dimentions.");
|
|
}
|
|
}
|
|
|
|
scalarMult(scalar) {
|
|
var data = this.array;
|
|
data.forEach( function(row,rI) {
|
|
row.forEach( function(col,cI) {
|
|
data[rI][cI] *= scalar;
|
|
});
|
|
});
|
|
}
|
|
|
|
transpose() {
|
|
var tArray = [];
|
|
for (var row = 0; row < this.n; row++) { tArray[row] = []; }
|
|
for (var row = 0; row < this.m; row++) {
|
|
for (var col = 0; col < this.n; col++) {
|
|
tArray[col][row] = this.array[row][col];
|
|
}
|
|
}
|
|
var rawArray = [];
|
|
tArray.forEach(function (row,rI) {
|
|
row.forEach( function(col,cI) {
|
|
rawArray.push(tArray[rI][cI]);
|
|
});
|
|
});
|
|
return new matrix(this.n,this.m,rawArray);
|
|
}
|
|
|
|
multiply(matrixb) {
|
|
if (matrixb.m == this.n) {
|
|
var m = this.m;
|
|
var n = this.n;
|
|
var p = matrixb.n;
|
|
var A = this;
|
|
var B = matrixb;
|
|
var newMatrix = [];
|
|
for (var i = 0; i < m; i++) {
|
|
newMatrix[i] = [];
|
|
for (var j = 0; j < p; j++) {
|
|
var sum = 0;
|
|
for (var k = 0; k < n; k++) {
|
|
sum += A.array[i][k] * B.array[k][j];
|
|
}
|
|
newMatrix[i][j] = sum;
|
|
}
|
|
}
|
|
var rawArray = [];
|
|
newMatrix.forEach(function (row,rI) {
|
|
row.forEach( function (col,cI) {
|
|
rawArray.push(newMatrix[rI][cI]);
|
|
});
|
|
});
|
|
return new matrix(m,p,rawArray);
|
|
} else {
|
|
return undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
class point {
|
|
constructor(x,y) {
|
|
this.x = "number" == typeof x ? x : 0;
|
|
this.y = "number" == typeof y ? y : 0;
|
|
}
|
|
|
|
getCoords() {
|
|
return [this.x,this.y];
|
|
}
|
|
|
|
setCoords(x,y) {
|
|
this.x = "number" == typeof x ? x : 0;
|
|
this.y = "number" == typeof y ? y : 0;
|
|
}
|
|
|
|
setX(x) {
|
|
this.x = "number" == typeof x ? x : 0;
|
|
}
|
|
|
|
setY(y) {
|
|
this.y = "number" == typeof y ? y : 0;
|
|
}
|
|
|
|
}
|
|
class vector {
|
|
constructor(direction,magnitude) {
|
|
this.direction = "number" == typeof direction ?
|
|
0 <= direction ?
|
|
360 >= direction ? direction : 360 : 0 : 0;
|
|
this.magnitude = "number" == typeof magnitude ? magnitude : 0;
|
|
}
|
|
|
|
getXYcomponents() {
|
|
var theta = deg2rad(this.direction);
|
|
var deltaX = Math.cos(theta)*this.magnitude;
|
|
var deltaY = Math.sin(theta)*this.magnitude;
|
|
return {"dx":deltaX,"dy":deltaY};
|
|
}
|
|
|
|
adjustMag(value) {
|
|
this.magnitude += "number" == typeof value ? value : 0;
|
|
}
|
|
|
|
setMag(value) {
|
|
this.magnitude = "number" == typeof value ? value : this.magnitude;
|
|
}
|
|
|
|
adjustDir(value) {
|
|
value = 0 <= value ? 360 >= value ? value: 360 : 0;
|
|
this.direction += value;
|
|
}
|
|
|
|
setDir(value) {
|
|
this.direction = 0 <= value ? 360 >= value ? value: 360 : 0;
|
|
}
|
|
|
|
executeVector(x,y) {
|
|
var components = this.getXYcomponents();
|
|
return new point(x+components.dx,y+components.dy);
|
|
}
|
|
|
|
crossProduct(vectorB) {
|
|
if (vectorB instanceof vector) {
|
|
var V1 = this.executeVector(0,0);
|
|
var V2 = vectorB.executeVector(0,0);
|
|
return (Math.sin(V1.x) * Math.cos(V2.y))
|
|
- (Math.cos(V1.y) * Math.sin(V2.x));
|
|
} else {
|
|
throw new TypeError("object is not a vector");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class lineSeg {
|
|
constructor(x1,y1,x2,y2) {
|
|
this.pointA = new point(x1,y1);
|
|
this.pointB = new point(x2,y2);
|
|
this.center = new point((x1+x2)/2,(y1+y2)/2);
|
|
this.length = Math.sqrt(
|
|
Math.pow(Math.abs(x2-x1),2)
|
|
+Math.pow(Math.abs(y2-y1),2)
|
|
);
|
|
this.angle = getAngle(x1,y1,x2,y2);
|
|
}
|
|
|
|
adjustA(length) {
|
|
length = "number" == typeof length ? length : 0;
|
|
var vecC2A = new vector(getAngle(
|
|
this.center.x,
|
|
this.center.y,
|
|
this.pointA.x,
|
|
this.pointA.y),
|
|
this.length/2);
|
|
vecC2A.adjustMag(length);
|
|
this.pointA = vecC2A.executeVector(this.center.x,this.center.y);
|
|
this.center.setCoords(
|
|
(this.pointA.x+this.pointB.x)/2,
|
|
(this.pointA.y+this.pointB.y)/2);
|
|
this.length += length;
|
|
}
|
|
|
|
adjustB(length) {
|
|
length = "number" == typeof length ? length : 0;
|
|
var vecC2B = new vector(
|
|
getAngle(
|
|
this.center.x,
|
|
this.center.y,
|
|
this.pointB.x,
|
|
this.pointB.y),
|
|
this.length/2);
|
|
vecC2B.adjustMag(length);
|
|
this.pointB = vecC2B.executeVector(this.center.x,this.center.y);
|
|
this.center.setCoords(
|
|
(this.pointA.x+this.pointB.x)/2,
|
|
(this.pointA.y+this.pointB.y)/2);
|
|
this.length += length;
|
|
}
|
|
|
|
adjustCenter(length) {
|
|
adjustA(length/2);
|
|
adjustB(length/2);
|
|
}
|
|
|
|
rotateA(deg) {
|
|
var abVec = new vector(
|
|
getAngle(
|
|
this.pointA.x,
|
|
this.pointA.y,
|
|
this.pointB.x,
|
|
this.pointB.y),
|
|
this.length);
|
|
abVec.adjustDir(deg);
|
|
this.pointB = abVec.executeVector(this.pointA.x,this.pointA.y);
|
|
this.center.setCoords(
|
|
(this.pointA.x+this.pointB.x)/2,
|
|
(this.pointA.y+this.pointB.y)/2);
|
|
}
|
|
|
|
rotateB(deg) {
|
|
var baVec = new vector(
|
|
getAngle(
|
|
this.pointB.x,
|
|
this.pointB.y,
|
|
this.pointA.x,
|
|
this.pointA.y),
|
|
this.length);
|
|
baVec.adjustDir(deg);
|
|
this.pointA = baVec.executeVector(this.pointB.x,this.pointB.y);
|
|
this.center.setCoords(
|
|
(this.pointA.x+this.pointB.x)/2,
|
|
(this.pointA.y+this.pointB.y)/2);
|
|
}
|
|
|
|
rotateCenter(deg) {
|
|
var vecC2A = new vector(
|
|
getAngle(
|
|
this.center.x,
|
|
this.center.y,
|
|
this.pointA.x,
|
|
this.pointA.y),
|
|
this.length/2);
|
|
var vecC2B = new vector(
|
|
getAngle(
|
|
this.center.x,
|
|
this.center.y,
|
|
this.pointB.x,
|
|
this.pointB.y),
|
|
this.length/2);
|
|
vecC2A.adjust(deg);
|
|
vecC2B.adjust(deg);
|
|
this.pointA = vecC2A.executeVector(this.center.x,this.center.y);
|
|
this.pointB = vecC2B.executeVector(this.center.x,this.center.y);
|
|
}
|
|
|
|
getPerp() {
|
|
this.rotateCenter(90);
|
|
var newline = new lineSeg(
|
|
this.pointA.x,
|
|
this.pointA.y,
|
|
this.pointB.x,
|
|
this.pointB.y);
|
|
this.rotateCenter(-90);
|
|
return newline;
|
|
}
|
|
|
|
slope() {
|
|
var deltaX = this.pointB.x - this.pointA.x;
|
|
var deltaY = this.pointB.y - this.pointA.y;
|
|
return deltaY / deltaX;
|
|
}
|
|
|
|
xIntercept() {
|
|
return -this.yIntercept()/this.slope();
|
|
}
|
|
|
|
yIntercept() {
|
|
var slope = this.slope();
|
|
if (Math.abs(slope) != Infinity) {
|
|
return -(slope*this.pointA.x)+this.pointA.y;
|
|
} else {
|
|
return this.pointA.x;
|
|
}
|
|
}
|
|
|
|
intersect(line) {
|
|
if (line instanceof lineSeg) {
|
|
var x1 = this.pointA.x;
|
|
var x2 = this.pointB.x;
|
|
var x3 = line.pointA.x;
|
|
var x4 = line.pointB.x;
|
|
|
|
var y1 = this.pointA.y;
|
|
var y2 = this.pointB.y;
|
|
var y3 = line.pointA.y;
|
|
var y4 = line.pointB.y;
|
|
|
|
var deltaAX = x1 - x2;
|
|
var deltaBX = x3 - x4;
|
|
var deltaAY = y1 - y2;
|
|
var deltaBY = y3 - y4;
|
|
|
|
// I don't know wtf to call these
|
|
var ground = deltaAX*deltaBY-deltaAY*deltaBX;
|
|
var Across = x1*y2 - y1*x2;
|
|
var Bcross = x3*y4 - y3*x4;
|
|
|
|
var x = (Across*deltaBX-deltaAX*Bcross)/ground;
|
|
var y = (Across*deltaBY-deltaAY*Bcross)/ground;
|
|
|
|
if (
|
|
valueBetween(x,this.pointA.x,this.pointB.x) &&
|
|
valueBetween(x,line.pointA.x,line.pointB.x) &&
|
|
valueBetween(y,this.pointA.y,this.pointB.y) &&
|
|
valueBetween(y,line.pointA.y,line.pointB.y)) {
|
|
return new point(x,y);
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
} else {
|
|
throw new TypeError("must check against line");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class shape {
|
|
constructor(type,x,y,sizeX,sizeY,fColor,bColor,bStyle,extraObject) {
|
|
this.type = "string" == typeof type ? type : "rect";
|
|
this.x = "number" == typeof x ? x : 0;
|
|
this.y = "number" == typeof y ? y : 0;
|
|
this.sizeX = "number" == typeof sizeX ? sizeX : 1;
|
|
this.sizeY = "number" == typeof sizeY ? sizeY : 1;
|
|
this.fColor = "string" == typeof fColor ? fColor : undefined;
|
|
this.bColor = "string" == typeof bColor ? bColor : undefined;
|
|
this.bStyle = "number" == typeof bStyle ? bStyle : undefined;
|
|
this.extraObject = "object" == typeof extraObject ? extraObject : {};
|
|
|
|
if ("rect" == this.type) {
|
|
this.render = function (ctx,xPos,yPos) {
|
|
rect(
|
|
ctx,
|
|
this.x+xPos,
|
|
this.y+yPos,
|
|
this.sizeX,
|
|
this.sizeY,
|
|
this.fColor,
|
|
this.bColor,
|
|
this.bStyle);
|
|
}
|
|
} else if ("elipse" == this.type) {
|
|
this.render = function (ctx,xPos,yPos) {
|
|
var centerX = this.x+xPos+(this.sizeX/2);
|
|
var centerY = this.y+yPos+(this.sizeY/2);
|
|
elip(
|
|
ctx,
|
|
centerX,
|
|
centerY,
|
|
(this.sizeX/2),
|
|
(this.sizeY/2),
|
|
this.fColor,
|
|
this.bColor,
|
|
this.bStyle);
|
|
}
|
|
} else if ("image" == this.type) {
|
|
this.imageData =
|
|
this.extraObject.imageData instanceof ImageData ?
|
|
this.extraObject.imageData :
|
|
new ImageData(
|
|
new Uint8ClampedArray([
|
|
255,0,0,255,
|
|
0,0,0,0,
|
|
255,0,0,255,
|
|
0,0,0,0,
|
|
255,0,0,255,
|
|
0,0,0,0,
|
|
255,0,0,255,
|
|
0,0,0,0,
|
|
255,0,0,255
|
|
]),3,3);
|
|
this.image = createImageBitmap(this.imageData);
|
|
this.render = function (ctx,xPos,yPos) {
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var sizeX = this.sizeX;
|
|
var sizeY = this.sizeY;
|
|
var contextBlur = ctx.imageSmoothingEnabled;
|
|
this.image.then(function (image) {
|
|
ctx.imageSmoothingEnabled = false;
|
|
ctx.drawImage(image,x+xPos,y+yPos,sizeX,sizeY);
|
|
ctx.imageSmoothingEnabled = contextBlur;
|
|
});
|
|
}
|
|
} else {
|
|
console.log("no valid type defined for shape, defalting to 'rect'");
|
|
this.render = function (ctx,xPos,yPos) {
|
|
rect(
|
|
ctx,
|
|
this.x+xPos,
|
|
this.y+yPos,
|
|
this.sizeX,
|
|
this.sizeY,
|
|
this.fColor,
|
|
this.bColor,
|
|
this.bStyle);
|
|
}
|
|
}
|
|
}
|
|
|
|
grow (amp) {
|
|
this.sizeX+=amp;
|
|
this.sizeY+=amp;
|
|
}
|
|
}
|
|
|
|
class container {
|
|
constructor(x,y,height,width,speed,direction) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.sizeY = height;
|
|
this.sizeX = width;
|
|
this.speed = "number" == typeof speed ? speed : 0;
|
|
this.direction = "number" == typeof direction ? direction : 0;
|
|
// Vectors are the future
|
|
this.netMovementVector = new vector(
|
|
this.direction,
|
|
this.speed);
|
|
}
|
|
|
|
setShape(myShape) {
|
|
if (myShape instanceof shape) {
|
|
this.shape = myShape;
|
|
} else {
|
|
throw new TypeError("addShape Method must be given a shape object");
|
|
}
|
|
}
|
|
|
|
nestContainer() {
|
|
this.containerArray = [];
|
|
this.addShape = function (newShape) {
|
|
if (newShape instanceof shape) {
|
|
var containerIndex = this.containerArray.push(
|
|
new container(0,0,this.sizeY,this.sizeX));
|
|
this.containerArray[containerIndex-1].setShape(newShape);
|
|
return this.containerArray[containerIndex-1];
|
|
} else {
|
|
throw new TypeError("addShape Method must be given a shape object");
|
|
}
|
|
};
|
|
if (this.shape instanceof shape) { this.addShape(me.shape); }
|
|
this.shape = undefined;
|
|
this.setShape = undefined;
|
|
}
|
|
|
|
move(direction,amplitude) {
|
|
this.direction = direction;
|
|
this.speed = amplitude;
|
|
var theta = deg2rad(direction);
|
|
this.x += Math.cos(theta) * amplitude;
|
|
this.y += Math.sin(theta) * amplitude;
|
|
}
|
|
|
|
renderContainer(ctx,xPos,yPos) {
|
|
var refX = this.x + ("number" == typeof xPos ? xPos : 0);
|
|
var refY = this.y + ("number" == typeof yPos ? yPos : 0);
|
|
if ("object" == typeof this.shape) {
|
|
this.shape.render(ctx,refX,refY);
|
|
} else if ("object" == typeof this.containerArray) {
|
|
this.containerArray.forEach(
|
|
function (container) {
|
|
container.renderContainer(ctx,refX,refY);
|
|
});
|
|
} else {
|
|
console.log("Container is empty!!!");
|
|
}
|
|
}
|
|
|
|
grow(amp) {
|
|
amp = "number"== typeof amp ? amp : 1;
|
|
this.x -= amp;
|
|
this.y -= amp;
|
|
if ("object" == typeof this.shape) {
|
|
this.shape.grow(amp);
|
|
} else if ("object" == typeof this.containerArray) {
|
|
this.containerArray.forEach(
|
|
function (container) { container.grow(amp); });
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class frameBuffer {
|
|
constructor(ctx, height, width) {
|
|
this.ctx = ctx;
|
|
this.height = height;
|
|
this.width = width;
|
|
this.containerArray = [];
|
|
}
|
|
|
|
addContainer(containerObject) { //might change this to auto create containers.
|
|
if (containerObject instanceof container) {
|
|
var index = this.containerArray.push(containerObject);
|
|
return this.containerArray[ index - 1];
|
|
} else {
|
|
throw new TypeError("addContainer Method must be given a container object");
|
|
}
|
|
}
|
|
|
|
pushFrame() {
|
|
var ctx = this.ctx;
|
|
ctx.clearRect(0,0,this.width,this.height);
|
|
this.containerArray.forEach(
|
|
function (container) { container.renderContainer(ctx,0,0); });
|
|
}
|
|
|
|
}
|
|
|
|
class starfield {
|
|
constructor (buffer,boundWidth,boundHeight,centerX,centerY,starCount,starLife,starSpeed) {
|
|
//Validate things
|
|
this.centerX = centerX;
|
|
this.centerY = centerY;
|
|
this.starLife = starLife;
|
|
this.starSpeed = starSpeed;
|
|
//Math the things
|
|
this.topBound = centerY - (boundHeight/2);
|
|
this.bottomBound = centerY + (boundHeight/2);
|
|
this.leftBound = centerX - (boundWidth/2);
|
|
this.rightBound = centerX + (boundWidth/2);
|
|
this.stars = [];
|
|
this.container = buffer.addContainer(
|
|
new container(this.centerX,this.centerY,0,0,0));
|
|
this.container.nestContainer();
|
|
for (var count = 1; count <= starCount; count++) {
|
|
var star = this.container.addShape(
|
|
new shape(
|
|
"rect",
|
|
((Math.random()*boundWidth)-(boundWidth/2)),
|
|
((Math.random()*boundHeight)-(boundHeight/2)),
|
|
1,1,
|
|
"#ffffff",
|
|
"#ffffff",
|
|
1));
|
|
this.stars.push({
|
|
"container":star,
|
|
"life":this.starLife,
|
|
"speed":this.starSpeed});
|
|
}
|
|
}
|
|
|
|
forward() {
|
|
var me = this;
|
|
this.stars.forEach(function (star) {
|
|
if (
|
|
(star.life > 0) &
|
|
(star.container.shape.x > me.leftBound - me.centerX) &
|
|
(star.container.shape.x < me.rightBound - me.centerX) &
|
|
(star.container.shape.y > me.topBound - me.centerY) &
|
|
(star.container.shape.y < me.bottomBound - me.centerY)) {
|
|
var xOffset = star.container.shape.x;
|
|
var yOffset = star.container.shape.y;
|
|
star.life--;
|
|
var c = 255*((me.starLife-star.life)/me.starLife)*4;
|
|
star.container.grow(5/me.starLife);
|
|
star.container.shape.fColor = "rgb("+c+","+c+","+c+")";
|
|
star.container.shape.bColor = "rgb("+c+","+c+","+c+")";
|
|
star.speed+=me.starSpeed;
|
|
star.container.shape.x +=
|
|
star.speed*((xOffset/me.centerX)*0.5);
|
|
star.container.shape.y +=
|
|
star.speed*((yOffset/me.centerY)*0.5);
|
|
} else {
|
|
star.container.x = 0;
|
|
star.container.y = 0;
|
|
star.life = me.starLife;
|
|
star.speed = me.starSpeed;
|
|
star.container.shape.sizeX = 1;
|
|
star.container.shape.sizeY = 1;
|
|
star.container.shape.fColor = "rgb(0,0,0)";
|
|
star.container.shape.bColor = "rgb(0,0,0)";
|
|
star.container.shape.x =
|
|
(Math.random()*(me.rightBound-me.leftBound))
|
|
-(me.centerX);
|
|
star.container.shape.y =
|
|
(Math.random()*(me.bottomBound-me.topBound))
|
|
-(me.centerY);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|