Created
January 27, 2013 03:06
-
-
Save calzoneman/4646026 to your computer and use it in GitHub Desktop.
Work in progress breakout clone with screen modifiers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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