You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
9.6 KiB

2 years ago
var strokePadding = 3;
function Level(level){
this.startingPoint = Math.random();
var table = tableSwitch(level, this);
this.cols = table.cols;
this.rows = table.rows;
this.setDefault = function(){
this.isStarted = false;
this.isPaused = false;
this.isWon = false;
this.isLost = false;
this.levelNum = level;
this.recordTime = getRecordTime(level);
this.totalBricksDestroyed = getTotalBricksDestroyed(level);
this.currentTime = 0;
this.brickPadding = (wWidth * 0.0125 + wHeight * 0.0125) / 2;
this.brickWidth = (wWidth - this.brickPadding * (this.cols + 1)) / this.cols;
this.brickHeight = (wHeight * 0.75 - this.brickPadding * (this.rows + 1)) / this.rows;
this.bricks = [];
this.balls = [];
this.toBeErased = [];
this.items = [];
this.itemFrequency = floor(levelCount / this.levelNum) * 2;
var p = new Paddle();
p.v = 10;
p.width = wWidth * 0.15;
p.x = (wWidth - p.width) / 2;
p.y = wHeight * 0.95;
p.height = wHeight * 0.025;
var b = new Ball();
b.radius = (wWidth * 0.02 + wHeight * 0.02) / 2;
b.x = p.x + this.startingPoint * p.width;
b.y = p.y - b.radius - strokePadding;
var velocityVector = {mag: (wWidth * 0.01 + wHeight * 0.01) / 3, x: 0, y: 0};
b.v = velocityVector;
b.v.x = b.calcVelocityX(p, 0);
b.v.y = -b.calcVelocityY();
this.paddle = p;
this.balls.push(b);
for (var c = 1; c <= this.cols; c++){
for (var r = 1; r <= this.rows; r++){
var b = new Brick();
b.x = this.brickPadding + (c - 1) * (this.brickWidth + this.brickPadding);
b.y = this.brickPadding + (r - 1) * (this.brickHeight + this.brickPadding);
b.width = this.brickWidth;
b.height = this.brickHeight;
b.state = designSwitch(level, c, r);
this.bricks.push(b);
}
}
//Border Top
bt = new Frameborder(0, -50, wWidth, 50);
//Border Bottom
bb = new Frameborder(0, wHeight, wWidth, 50);
//Border Left
bl = new Frameborder(-50, 0, 50, wHeight);
//Border Right
br = new Frameborder(wWidth, 0, 50, wHeight);
this.frameBorders = [bt, bb, bl, br];
}
this.setDefault();
//Draw everything and check and react to collisions and events
this.drawShapes = function(){
if (this.isWon || this.isLost) return;
//Background gets cleared and bg color is gray
clear();
background(100);
//Bricks have black stroke and rounded corners
stroke(0);
strokeWeight(strokePadding * 2);
strokeJoin(ROUND);
//Counter to check if game is won
var brickCounter = 0;
//Draw bricks
for (var b of this.bricks){
//If there are bricks "living" counter goes up and game keeps running
if (b.state > 0) brickCounter++;
//Select brick color based on his state
var fillColor = colorSwitch(b.state);
if (!fillColor) continue;
else fill(fillColor);
//Drawing
rect(b.x, b.y, b.width, b.height);
}
//If no brick is "living" game is won
if (brickCounter == 0) this.gameWon(); //Deactivate in TestMode
//Draw downfalling items
for (var i of this.items){
var sw = i.radius * 0.2;
fill(0);
stroke(0);
strokeWeight(0);
ellipse(i.x, i.y, i.radius * 2, i.radius * 2);
strokeWeight(sw);
var rectX = i.x - i.radius * sin(5 * PI / 8) + sw;
var rectY = i.y + i.radius * cos(5 * PI / 8) + sw;
var rectW = i.radius * 2 * sin(5 * PI / 8) - sw * 2;
var rectH = i.radius * 2 * abs(cos(5 * PI / 8)) - sw * 2;
var lineLength = i.radius * 0.5;
switch(i.item){
case FastBall:
fill("#00FF00");
strokeWeight(0);
ellipse(i.x, i.y, i.radius * 1.25, i.radius * 1.25);
break;
case FastPaddle:
fill("#00FF00");
strokeWeight(0);
rect(rectX, rectY, rectW, rectH);
break;
case SlowBall:
fill("#FF0000");
strokeWeight(0);
ellipse(i.x, i.y, i.radius * 1.25, i.radius * 1.25);
break;
case SlowPaddle:
fill("#FF0000");
strokeWeight(0);
rect(rectX, rectY, rectW, rectH);
break;
case CreateBall:
strokeWeight(sw * 2);
stroke("#00FF00");
line(i.x - lineLength, i.y, i.x + lineLength, i.y);
line(i.x, i.y - lineLength, i.x, i.y + lineLength);
break;
case UpgradeBricks:
strokeWeight(sw * 2);
stroke("#FF0000");
line(i.x - lineLength, i.y, i.x + lineLength, i.y);
line(i.x, i.y - lineLength, i.x, i.y + lineLength);
break;
}
}
//Balls and paddleboard are black
fill(0);
stroke(0);
strokeWeight(strokePadding * 2);
var p = this.paddle;
//Draw paddleboard
rect(p.x, p.y, p.width, p.height);
//Ball doesnt need rounded corners
strokeWeight(0);
//Draw every ball
for (var b of this.balls) ellipse(b.x, b.y, b.radius * 2, b.radius * 2);
//Break if game isnt running
if (this.isPaused || !this.isStarted) return;
//Check collision and other situations of balls
for(var ball1 of this.balls){
//Check if ball flew away
if (ball1.isLost()) this.toBeErased.push(ball1);
//Check collision with frameborders
for (var fb of this.frameBorders){
var collision = collisionDetection(ball1, fb);
if (collision.isTouching) performCollision(ball1, fb, collision);
}
//Check collision with paddleboard
var collision = collisionDetection(ball1, p);
if (collision.isTouching) performCollision(ball1, p, collision);
//Check collision with bricks
for (var brick of this.bricks){
if (brick.state == 0) continue;
var collision = collisionDetection(ball1, brick);
if (collision.isTouching){
performCollision(ball1, brick, collision);
if (brick.state > 0) brick.state--;
if (floor(random(this.itemFrequency + 1)) % this.itemFrequency == 0 && brick.state == 0) this.createItem(brick);
if (brick.state == 0) this.totalBricksDestroyed++;
setTotalBricksDestroyed(level, this.totalBricksDestroyed);
}
}
//Check collision with other balls
for (var ball2 of this.balls){
if (ball1 == ball2) continue;
var collision = collisionDetection(ball1, ball2);
if (collision.isTouching) performCollision(ball1, ball2, collision);
}
//Check if velocites go to NaN due to mistakes
if (isNaN(ball1.v.x) || isNaN(ball1.v.y)){
ball1.x = p.x + p.width / 2;
ball1.y = p.y - ball1.radius - strokePadding * 2;
ball1.v.x = 0;
ball1.v.y = ball1.v.mag;
}
}
//Checkings for items
for (var item of this.items){
var index = this.items.indexOf(item);
//Check collision with paddleboard
var collision = collisionDetection(item, p);
if (collision.isTouching){
this.items.splice(index, 1);
switch (item.item){
case FastBall:
for (var b of this.balls) for (var v in b.v) b.v[v] *= 1.25;
break;
case FastPaddle:
p.v *= 1.25;
break;
case SlowBall:
for (var b of this.balls) for (var v in b.v) b.v[v] *= 0.75;
break;
case SlowPaddle:
p.v *= 0.75;
break;
case CreateBall:
var p = this.paddle;
var radius = (wWidth * 0.02 + wHeight * 0.02) / 2 * random(0.75, 1.25);
var x = p.x + p.width / 2;
var y = p.y - (radius + strokePadding);
var v = (wWidth * 0.01 + wHeight * 0.01) / 3;
var vx = 0;
var vy = v;
this.createBall(x, y, radius, v, vx, vy);
break;
case UpgradeBricks:
for (var b of this.bricks) if (b.state > 0 && b.state < stateCount - 1) b.state++;
break;
}
}
if (item.y - item.radius > wHeight){
this.items.splice(index, 1);
break;
}
}
//Erase all balls out of screen
for (var ball of this.toBeErased){
var index = this.balls.indexOf(ball);
this.balls.splice(index, 1);
}
this.toBeErased = [];
//Game is lost of no balls are in there
if (this.balls.length == 0) this.gameLost();
//Break if game isnt running once more because previous checkings could've caused a paused game
if (!this.isStarted || this.isPaused) return;
//Finally move objects forward
for (var b of this.balls) b.move();
for (var i of this.items) i.move();
p.move();
}
this.createItem = function(b){
var item = floor(random(itemCount)) + 1;
var bx = b.x;
var by = b.y;
var bw = b.width;
var bh = b.height;
var x = bx + bw / 2;
var y = by + bh / 2;
var radius = (wHeight + wWidth) / 2 * 0.02;
this.items.push(new Item(x, y, radius, random(1, 6), item));
}
this.createBall = function(x, y, r, v, vx, vy){
var b = new Ball();
b.x = x;
b.y = y;
b.radius = r;
b.v = {mag: v, x: vx, y: vy};
this.balls.push(b);
}
this.gameLost = function(){
this.isPaused = true;
this.isLost = true;
if (!infoIsOpen) openInfo();
}
this.gameWon = function(){
this.isPaused = true;
this.isWon = true;
if (this.levelNum - 1 == levelReached){
levelReached++;
setCookie("levelReached", String(levelReached), 10);
checkLevelButtons(this.levelNum);
}
if (this.currentTime < getRecordTime(this.levelNum)){
setRecordTime(this.levelNum, this.currentTime);
}
if (!infoIsOpen) openInfo();
}
this.restart = function(){this.setDefault();}
this.pause = function(paused){
if (this.isWon || this.isLost) return;
if (paused){
pauseAnimation(true);
this.isPaused = true;
} else {
pauseAnimation(false);
this.isPaused = false;
if (infoIsOpen) closeInfo();
}
}
this.start = function(){
this.isStarted = true;
if (infoIsOpen) closeInfo();
}
this.lastTime = new Date().getTime();
this.renderTime = function(){
var d = new Date().getTime();
var passed = d - this.lastTime;
this.lastTime = d;
if (!this.isPaused && this.isStarted){
this.currentTime += passed;
setTotalTimePlayed(getTotalTimePlayed() + passed);
}
var timeString = toTimeString(this.currentTime);
$("#timeDiv span").html(timeString);
}
}