/* constants.js */ var Constant = {/*{{{*/ Ball: { WIDTH : 10, HEIGHT : 10, Velocity: { X: 5, Y: -5, INCREMENT: 0.5, MULTIPLIER: -1.01, }, }, Brick: { NUM_W : 10, NUM_H : 6, WIDTH : 50, HEIGHT : 20, PADDING : 2, COLOR_COLUMNS : false, }, Color: { RED : [0xCC, 0x11, 0x11], GREEN : [0x11, 0xCC, 0x11], BLUE : [0x11, 0x11, 0xCC], WHITE : [0xEE, 0xEE, 0xEE], BLACK : [0x11, 0x11, 0x11], YELLOW : [0xEE, 0xCC, 0x11], }, Enum: { ColorComponent: { R : 0, G : 1, B : 2, }, GameEnd: { GOOD : 0, BAD : 1, }, Geometry: { X : 0, Y : 1, W : 2, H : 3, }, Key: { LEFT : 37, RIGHT : 39, }, }, Paddle: { WIDTH : 100, HEIGHT : 20, SPEED : 10, }, Setting: { FPS : 60, }, Stage: { WIDTH : 500, HEIGHT : 500, }, };/*}}}*/ /* mobmanager.js */ var MobManager = (function(){/*{{{*/ var bricks, paddle, ball, brickRowColors; function pub_init(){ var i, j, k, sw = Constant.Stage.WIDTH, sh = Constant.Stage.HEIGHT, numBrickW = Constant.Brick.NUM_W, numBrickH = Constant.Brick.NUM_H, brickW = Constant.Brick.WIDTH, brickH = Constant.Brick.HEIGHT, paddleW = Constant.Paddle.WIDTH, paddleH = Constant.Paddle.HEIGHT, ballW = Constant.Ball.WIDTH, ballH = Constant.Ball.HEIGHT, paddleX = sw / 2 - paddleW / 2, paddleY = sh - paddleH, ballX = sw / 2 - ballW / 2, ballY = paddleY - ballH * 2; bricks = []; paddle = new Paddle(paddleX, paddleY); ball = new Ball(ballX, ballY); with(Constant.Color){ brickRowColors = [ BLACK, RED, BLUE, GREEN, YELLOW, WHITE, ]; } for(i = 0; i < numBrickH; i++){ k = i; for(j = 0; j < numBrickW; j++){ if(Constant.Brick.COLOR_COLUMNS) k = j % numBrickH; bricks.push(new Brick(j * brickW, i * brickH, brickRowColors[k])); } } } function pub_pollBricks(){ return bricks; } function pub_pollPaddle(){ return paddle; } function pub_run(){ var i, goodEnd = Constant.Enum.GameEnd.GOOD; for(i = 0; i < bricks.length; i++){ bricks[i].run(); } paddle.run(); ball.run(); if(bricks.length < 1){ Game.end(goodEnd); } } return { init: pub_init, pollBricks: pub_pollBricks, pollPaddle: pub_pollPaddle, run: pub_run, } })();/*}}}*/ /* draw.js */ var Draw = (function(){/*{{{*/ var width, height, canvas, ctx; var pub_color = { red: [0xCC, 0x11, 0x11], green: [0x11, 0xCC, 0x11], blue: [0x11, 0x11, 0xCC], white: [0xEE, 0xEE, 0xEE], black: [0x11, 0x11, 0x11], }; function pub_init(_width, _height){ width = _width; height = _height; canvas = document.getElementById("canvas"); canvas.width = width; canvas.height = height; ctx = canvas.getContext("2d"); ctx.font = "52px bold monospace"; } function pub_text(_text, _x, _y){ ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(_text, _x, _y); } function pub_rect(x, y, w, h){ ctx.fillRect(x, y, w, h); } function pub_clear(){ ctx.clearRect(0, 0, width, height); } function pub_setColor(color){ var cc = Constant.Enum.ColorComponent; ctx.fillStyle = "rgb(" + color[cc.R] + "," + color[cc.G] + "," + color[cc.B] + ")"; } return { color: pub_color, init: pub_init, text: pub_text, rect: pub_rect, clear: pub_clear, setColor: pub_setColor, }; })();/*}}}*/ /* input.js */ var Input = (function(){/*{{{*/ var keys = [], canvas = document.getElementById("canvas"); function getKeys(evt){ keys[evt.keyCode] = evt.type == "keydown"; return false; } function pub_init(){ canvas.onkeydown = canvas.onkeyup = getKeys; canvas.tabIndex = 0; } function pub_keyIsDown(key){ return keys[key] ? 1 : 0; } return { init: pub_init, keyIsDown: pub_keyIsDown, }; })();/*}}}*/ /* paddle.js */ function Paddle(_x, _y){/*{{{*/ var x = _x, y = _y, w = Constant.Paddle.WIDTH, h = Constant.Paddle.HEIGHT, color = Constant.Color.BLACK, speed = Constant.Paddle.SPEED; function draw(){ Draw.setColor(color); Draw.rect(x, y, w, h); } function collisionLeftWall(){ return x <= 0; } function collisionRightWall(){ var sw = Constant.Stage.WIDTH; return x + w >= sw; } function doInput(){ var key = Constant.Enum.Key; if(Input.keyIsDown(key.LEFT)){ if(!collisionLeftWall()){ x -= speed; } } else if(Input.keyIsDown(key.RIGHT)){ if(!collisionRightWall()){ x += speed; } } } function pub_getGeometryLeft(){ var halfW = w / 2; return [x, y, halfW, h]; } function pub_getGeometryRight(){ var halfW = w / 2; return [x + halfW, y, halfW, h]; } function pub_run(){ doInput(); draw(); } this.run = pub_run; this.getGeometryLeft = pub_getGeometryLeft; this.getGeometryRight = pub_getGeometryRight; }/*}}}*/ /* ball.js */ function Ball(_x, _y){/*{{{*/ var x = _x, y = _y, vx = Constant.Ball.Velocity.X, vy = Constant.Ball.Velocity.Y, w = Constant.Ball.WIDTH, h = Constant.Ball.HEIGHT, color = Constant.Color.BLACK; function draw(){ Draw.setColor(color); Draw.rect(x, y, w, h); } function collisionLeftWall(){ return x <= 0; } function collisionRightWall(){ var sw = Constant.Stage.WIDTH; return x + w >= sw; } function collisionTopWall(){ return y <= 0; } function collisionBottomWall(){ var sh = Constant.Stage.HEIGHT; return y >= sh; } function collisionPixel(geomA, geomB){ var g = Constant.Enum.Geometry; return !( geomA[g.X] + geomA[g.W] <= geomB[g.X] || geomB[g.X] + geomB[g.W] <= geomA[g.X] || geomA[g.Y] + geomA[g.H] <= geomB[g.Y] || geomB[g.Y] + geomB[g.H] <= geomA[g.Y] ); } function collisionBrick(){ var i, geomSelf = [x, y, w, h], geomBrick, bricks = MobManager.pollBricks(); for(i = 0; i < bricks.length; i++){ geomBrick = bricks[i].getGeometry(); if(collisionPixel(geomSelf, geomBrick)){ bricks.splice(i, 1); return 1; } } return 0; } function collisionPaddleLeft(){ var geomSelf = [x, y, w, h], geomPaddle = MobManager.pollPaddle().getGeometryLeft(); return collisionPixel(geomSelf, geomPaddle); } function collisionPaddleRight(){ var geomSelf = [x, y, w, h], geomPaddle = MobManager.pollPaddle().getGeometryRight(); return collisionPixel(geomSelf, geomPaddle); } function collisionPaddle(){ return collisionPaddleLeft() || collisionPaddleRight(); } function checkCollisions(){ var multiplier = Constant.Ball.Velocity.MULTIPLIER, increment = Constant.Ball.Velocity.INCREMENT, badEnd = Constant.Enum.GameEnd.BAD; if(collisionLeftWall() || collisionRightWall()) vx *= multiplier; if(collisionTopWall() || collisionBrick()) vy *= multiplier; if(collisionPaddle() && vy > 0){ vy *= multiplier; } if(collisionPaddleLeft()) vx -= increment; if(collisionPaddleRight()) vx += increment; if(collisionBottomWall()) Game.end(badEnd); } function pub_run(){ x += vx; y += vy; checkCollisions(); draw(); } this.run = pub_run; }/*}}}*/ /* brick.js */ function Brick(_x, _y, _color){/*{{{*/ var x = _x, y = _y, w = Constant.Brick.WIDTH, h = Constant.Brick.HEIGHT, padding = Constant.Brick.PADDING, color = _color; function draw(){ Draw.setColor(color); Draw.rect(x, y, w - padding, h - padding); } function pub_getGeometry(){ return [x, y, w, h]; } function pub_run(){ draw(); } this.run = pub_run; this.getGeometry = pub_getGeometry; }/*}}}*/ /* game.js */ var Game = (function(){/*{{{*/ var mainLoop; function loop(){ Draw.clear(); MobManager.run(); } function pub_main(){ var sw = Constant.Stage.WIDTH, sh = Constant.Stage.HEIGHT, fps = Constant.Setting.FPS; Draw.init(sw, sh); Input.init(); MobManager.init(); mainLoop = setInterval(loop, 1000 / fps); } function pub_end(endType){ new GameOver(endType).show(); clearInterval(mainLoop); } return { main: pub_main, end: pub_end, }; })();/*}}}*/ /* gameover.js */ function GameOver(_endType){/*{{{*/ var endType = _endType; function pub_show(){ var hw = Constant.Stage.WIDTH / 2, hh = Constant.Stage.HEIGHT / 2, goodEnd = Constant.Enum.GameEnd.GOOD; Draw.clear(); if(endType == goodEnd){ Draw.text("You Win", hw, hh); } else { Draw.text("Game Over", hw, hh); } } this.show = pub_show; }/*}}}*/ window.onload = Game.main();
<canvas id="canvas">Unfortunately, your browser does not support HTML5</canvas>