Skip to content

Instantly share code, notes, and snippets.

@calzoneman
Created January 27, 2013 03:06
Show Gist options
  • Save calzoneman/4646026 to your computer and use it in GitHub Desktop.
Save calzoneman/4646026 to your computer and use it in GitHub Desktop.
Work in progress breakout clone with screen modifiers
const BRICK_WIDTH = 15;
const BRICK_HEIGHT = 4;
var Brick = function(image) {
this.width = BRICK_WIDTH;
this.height = BRICK_HEIGHT;
this.image = image;
}
Brick.prototype = {
draw: function(ctx, x, y) {
ctx.drawImage(this.image, x, y);
}
};
const MAX_BALL_SPEED = 2;
const HIT_BOOST = 0.05;
var Ball = function(level, x, y) {
this.x = x;
this.y = y;
this.vx = 0.3;
this.vy = -1;
this.level = level;
this.image = new Image(); this.image.src = "ball.png";
this.width = 2;
this.height = 2;
};
Ball.prototype = {
draw: function(ctx) {
ctx.drawImage(this.image, this.x - 1, this.y - 1);
},
checkCollideLevel: function() {
return this.vertLevelCollision() || this.horizLevelCollision();
},
clampSpeed: function() {
var curspeed = Math.sqrt(this.vx*this.vx + this.vy*this.vy);
var ang = Math.atan2(this.vy, this.vx);
if(curspeed > MAX_BALL_SPEED)
curspeed = MAX_BALL_SPEED
this.vx = curspeed * Math.cos(ang);
this.vy = curspeed * Math.sin(ang);
},
addSpeed: function(speed) {
var curspeed = Math.sqrt(this.vx*this.vx + this.vy*this.vy);
var ang = Math.atan2(this.vy, this.vx);
curspeed += speed;
if(curspeed > MAX_BALL_SPEED)
curspeed = MAX_BALL_SPEED
this.vx = curspeed * Math.cos(ang);
this.vy = curspeed * Math.sin(ang);
},
horizLevelCollision: function() {
var x = (this.x + this.vx) - this.level.renderX;
var y = this.y - this.level.renderY;
x = Math.floor(x / (BRICK_WIDTH + 1));
y = Math.floor(y / (BRICK_HEIGHT + 1));
var hit = this.level.hit(x, y);
if(!hit)
return false;
this.vx = -this.vx;
if(this.vx > 0)
this.vx += HIT_BOOST;
else
this.vx -= HIT_BOOST;
this.clampSpeed();
},
vertLevelCollision: function() {
var x = this.x - this.level.renderX;
var y = (this.y + this.vy) - this.level.renderY;
x = Math.floor(x / (BRICK_WIDTH + 1));
y = Math.floor(y / (BRICK_HEIGHT + 1));
var hit = this.level.hit(x, y);
if(!hit)
return false;
this.vy = -this.vy;
if(this.vy > 0)
this.vy += HIT_BOOST;
else
this.vy -= HIT_BOOST;
this.clampSpeed();
}
};
var Paddle = function(x, y) {
this.width = 20;
this.height = 4;
this.x = x;
this.y = y;
this.vx = 0;
this.image = new Image(); this.image.src = "paddle.png";
};
Paddle.prototype = {
draw: function(ctx) {
ctx.drawImage(this.image, this.x, this.y);
}
};
var Pattern = function(str) {
this.str = str;
this.r = new Image(); this.r.src = "bred.png";
this.y = new Image(); this.y.src = "byellow.png";
this.g = new Image(); this.g.src = "bgreen.png";
this.c = new Image(); this.c.src = "bcyan.png";
this.b = new Image(); this.b.src = "bblue.png";
this.m = new Image(); this.m.src = "bmagenta.png";
};
var Level = function(width, height, sw, sh) {
this.width = width;
this.height = height;
this.bricks = new Array(width * height);
this.renderX = (sw - width * (BRICK_WIDTH + 1)) / 2;
this.renderY = 10;
for(var i = 0; i < width * height; i++) {
this.bricks[i] = new Brick("#ff0000");
}
}
Level.prototype = {
generate: function(pattern) {
for(var i = 0; i < this.width * this.height; i++) {
if(pattern.str[i] == 'x')
this.bricks[i] = null;
else
this.bricks[i] = new Brick(pattern[pattern.str[i]]);
}
},
hit: function(x, y) {
if(x < 0 || y < 0 || x >= this.width || y >= this.height)
return false;
if(this.bricks[y * this.width + x] == null)
return false;
this.bricks[y * this.width + x] = null;
return true;
},
draw: function(ctx) {
for(var i = 0; i < this.width; i++) {
for(var j = 0; j < this.height; j++) {
if(this.bricks[j * this.width + i] == null)
continue;
var x = this.renderX + (BRICK_WIDTH + 1) * i;
var y = this.renderY + (BRICK_HEIGHT + 1) * j;
this.bricks[j * this.width + i].draw(ctx, x, y);
}
}
}
}
var Game = function() {
this.modifiers = {
spin: false,
rotated: false,
horizsplit: false,
vertsplit: false
};
this.level = new Level(10, 5, width, height);
var pat = new Pattern("rrrrrrrrrrrygyggygyrrxxxxxxxxrrmbbmmbbmrrrrrrrrrrr");
this.level.generate(pat);
this.ball = new Ball(this.level, width / 2, height / 2);
this.ball.vx = Math.random() / 8;
this.ball.vy = 0.8;
balltimer = 3 * 60;
this.paddle = new Paddle(25, height - 10);
}
Game.prototype = {
tick: function() {
if(balltimer > 0)
balltimer--;
else
this.updateBall();
this.updatePaddle();
},
render: function(ctx) {
this.level.draw(ctx);
this.paddle.draw(ctx);
this.ball.draw(ctx);
},
updateBall: function() {
var levelhit = this.ball.checkCollideLevel();
if(levelhit)
return;
this.ball.x += this.ball.vx;
this.ball.y += this.ball.vy;
if(this.ball.y + this.ball.height > this.paddle.y &&
this.ball.y + this.ball.height < this.paddle.y + this.paddle.height) {
if(this.ball.x + this.ball.width > this.paddle.x) {
if(this.ball.x < this.paddle.x + this.paddle.width) {
//this.ball.vx += this.paddle.vx * 0.25;
//this.ball.clampSpeed();
this.ball.vy = -this.ball.vy;
}
}
}
if(this.ball.x + this.ball.width > this.paddle.x && this.ball.x < this.paddle.x + this.paddle.width) {
if(this.ball.y + this.ball.height > this.paddle.y) {
if(this.ball.y < this.paddle.y + this.paddle.width) {
this.ball.vy = -this.ball.vy;
}
}
}
if(this.ball.x < 3) {
this.ball.vx = -this.ball.vx;
this.ball.x = 3;
}
if(this.ball.x >= width - 3) {
this.ball.vx = -this.ball.vx;
this.ball.x = width - 4;
}
if(this.ball.y < 3) {
this.ball.vy = -this.ball.vy;
this.ball.y = 3;
}
if(this.ball.y >= height) {
this.ball.x = width / 2;
this.ball.y = height / 2;
this.ball.vx = Math.random() / 8;
this.ball.vy = 0.8;
balltimer = 3 * 60;
}
},
updatePaddle: function() {
this.paddle.x += this.paddle.vx;
if(this.paddle.x < 3) {
this.paddle.vx = 0;
this.paddle.x = 3;
}
if(this.paddle.x + this.paddle.width >= width - 3) {
this.paddle.vx = 0;
this.paddle.x = width - 3 - this.paddle.width;
}
},
clearMods: function() {
for(var key in this.modifiers) {
if(key == "spin" && this.modifiers[key]) {
scale *= SQRT_2;
offx = 0;
offy = 0;
}
this.modifiers[key] = false;
}
},
addModifier: function(mod) {
var active = this.modifiers[mod];
this.modifiers[mod] = true;
if(mod == "spin" && !active) {
spinAng = 0.0;
scale /= SQRT_2;
calcSpinOffset();
}
if(mod == "rotated") {
rotAng += PI_OVER_2;
}
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment