html5 canvas绘制打砖块小游戏
源代码
github源码下载地址
项目展示


下面放上主要代码
index.js代码
var game = {
canvas : document.getElementById('canvas'),
ctx : canvas.getContext('2d'),
clientWidth: document.documentElement.clientWidth,
clientHeight: document.documentElement.clientHeight,
launcher: new Image(),
gameOver: new Image(),
addSpeed: new Image(),
addPower: new Image(),
actions: {},
launcher_x: document.documentElement.clientWidth/2 - 50/2,
launcher_y : document.documentElement.clientHeight-60,
audioBallState: null,
audioBall : new Audio(),
gameFlag: false,
init: function() {
if(this.clientWidth>900){
this.canvas.width = 375;
this.canvas.height = 667;
this.launcher_y = this.canvas.height - 60;
this.launcher_x = this.canvas.width/2 - 50/2;
}else{
this.canvas.width = this.clientWidth;
this.canvas.height = this.clientHeight;
}
this.launcher.src = "./image/launcher.png";
this.gameOver.src = "./image/game_over.png";
},
start: function() {
this.gameFlag = true;
this.init();
game.ball.init();
game.brick.init();
game.tool.init();
this.draw();
this.sounds();
this.canvas.addEventListener('mousedown',this.mouse_touch_Down);
this.canvas.addEventListener('mousemove',this.mouse_touch_Move);
this.canvas.addEventListener('touchstart',this.mouse_touch_Down);
this.canvas.addEventListener('touchmove',this.mouse_touch_Move);
},
sounds: function() {
game.audioBall.src="./sounds/ball.mp3";
game.audioBall.ontimeupdate=function(){
if(game.audioBall.currentTime>=0.1){
game.audioBall.pause();
}
};
game.audioBallState = setInterval(function(){
game.audioBall.currentTime = 0;
game.audioBall.play();
},1000);
},
play: function (name, action, interval) {
var that = this;
this.actions[name] = setInterval(function () {
action();
that.draw();
}, interval || 50);
},
stop: function (name) {
clearInterval(game.actions[name]);
},
draw: function () {
this.ctx.clearRect(0, 0,this.clientWidth,this.clientHeight);
this.ctx.save();
for(var i=game.ball.balls.length-1; i>=0; i--){
game.ball.balls[i].draw();
}
for(var i=game.tool.tools.length-1; i>=0; i--){
game.tool.tools[i].draw();
if(game.tool.tools[i].remove){
game.tool.tools.splice(i,1);
}
}
for(var t=game.brick.bricks.length-1; t>=0; t--){
for(var j=0;j<8;j++){
game.brick.bricks[t][j].draw();
if(game.brick.bricks[t][j].x>game.launcher_x+5 && game.brick.bricks[t][j].x<game.launcher_x+45
&& game.brick.bricks[t][j].y>game.launcher_y && game.brick.bricks[t][j].y<game.launcher_y+50
&& game.brick.bricks[t][j].num>0){
this.canvas.removeEventListener('mousemove',this.mouse_touch_Move);
this.canvas.removeEventListener('touchmove',this.mouse_touch_Move);
game.stop('addBalls')
game.stop('removeBalls')
game.stop('drawBalls')
game.stop('moveBalls')
game.stop('addBricks')
game.stop('removeBricks')
game.stop('drawBricks')
game.stop('moveBricks')
game.stop('addTools')
game.stop('removeTools')
game.stop('drawTools')
game.stop('moveTools')
clearInterval(game.audioBallState);
game.audioBall.pause();
game.over.draw();
game.gameFlag = false;
console.log("结束")
}
for(var b=game.ball.balls.length-1; b>=0;b--){
if(game.ball.balls[b].y<(game.brick.bricks[t][j].y+game.brick.bricks[t][j].height) && game.ball.balls[b].y>game.brick.bricks[t][j].y
&& game.ball.balls[b].x>game.brick.bricks[t][j].x && game.ball.balls[b].x<game.brick.bricks[t][j].x+game.brick.bricks[t][j].width
&& game.brick.bricks[t][j].num >0){
var brick_num = game.brick.bricks[t][j].num
game.ball.balls.splice(b,1);
if((brick_num-game.score.launcher_power)>0){
game.brick.bricks[t][j].num -= game.score.launcher_power;
game.score.score_sum += game.score.launcher_power;
}else{
game.brickOver(game.brick.bricks[t][j].x,game.brick.bricks[t][j].y);
game.score.score_sum += brick_num;
game.brick.bricks[t][j].num -= game.score.launcher_power;
}
}
}
}
}
game.shoot.draw();
game.score.draw();
this.ctx.restore();
},
mouse_touch_Down: function(e) {
var px = (e.offsetX || (e.clientX - game.canvas.offsetLeft) || e.touches[0].pageX);
var py = (e.offsetY || (e.clientY - game.canvas.offsetTop) || e.touches[0].pageY);
var x = px-50/2;
if(game.gameFlag){
game.launcher_x = x;
}else{
if(px > ((game.canvas.width-200)/2) && px < ((game.canvas.width-200)/2+200)
&& py > ((game.canvas.height-150)/2) && py<((game.canvas.height-150)/2)+150){
game.ball.balls = []
game.brick.bricks = []
game.start();
}
}
game.draw();
},
mouse_touch_Move: function(e) {
var px = (e.offsetX || (e.clientX - game.canvas.offsetLeft) || e.touches[0].pageX);
var x = px-50/2;
game.launcher_x = x;
game.draw();
},
getRandom: function (max) {
return parseInt(Math.random()*max);
},
brickOver: function(x,y){
var ctx = game.ctx;
var agle=0;
ctx.save();
ctx.translate(x,y)
ctx.clearRect(-game.canvas.width/2,-game.canvas.height/2,game.canvas.width,game.canvas.height);
for(var i=0;i<=100;i+=parseInt(Math.random()*30)){
for(var j =0;j<=100;j+=parseInt(Math.random()*30)){
agle = parseInt(Math.random()*360)
ctx.rotate(agle*Math.PI/180);
ctx.fillRect(i,j,10,10);
ctx.fill();
ctx.rotate(-agle*Math.PI/180);
}
}
ctx.restore();
}
}
game.score = {
launcher_speed: 5,
launcher_power: 1,
score_sum: 0,
draw: function () {
var ctx = game.ctx;
ctx.save();
ctx.translate(10, 10);
ctx.font = "14px 微软雅黑";
ctx.fillStyle = "#fff";
ctx.fillText("攻速:" + this.launcher_speed,0, 30);
ctx.fillText("威力:" + this.launcher_power, 0, 60);
ctx.fillText("得分:" + this.score_sum,0,90);
ctx.fill();
ctx.stroke();
ctx.restore();
},
addScore: function (num) {
this.launcher_speed += num;
this.draw();
},
};
game.shoot = {
draw: function() {
var ctx = game.ctx;
game.launcher.onload =function() {
ctx.drawImage(game.launcher, game.launcher_x,game.launcher_y);
}
ctx.drawImage(game.launcher, game.launcher_x,game.launcher_y);
}
}
game.tool = {
tools: [],
init: function () {
var that = this;
game.play('moveTools',function() {
for(var i=game.tool.tools.length-1; i>=0; i--){
game.tool.tools[i].move();
}
},40)
game.play('addTools',function(){
that.tools.push(new Tool(game.getRandom(2),game.getRandom(300),30));
},5000)
game.play('removeTools',function(){
for(var i=that.tools.length-1; i>=0; i--){
if(that.tools[i].y>680){
that.tools.splice(i,1);
}
}
},100)
}
}
var Tool = function(img_i,x,y){
this.i = img_i;
this.x = x;
this.y = y;
this.remove = false;
}
Tool.prototype.move = function() {
this.y += 3;
if(this.y>500 && game.launcher_x>this.x && game.launcher_x<this.x+50
&& game.launcher_y >this.y && game.launcher_y<this.y+60){
console.log("吃到工具")
if(this.img_i == 0){
game.score.launcher_power +=1;
}else{
game.score.launcher_speed +=2;
}
this.remove = true;
}
}
Tool.prototype.draw = function() {
var ctx = game.ctx;
ctx.beginPath();
if(this.i==0){
ctx.fillStyle = "#FF0000";
}else{
ctx.fillStyle = "#00BFFF";
}
ctx.arc(this.x, this.y,10, 0, Math.PI * 2);
ctx.fill();
}
game.ball = {
balls: [],
init: function () {
var that = this;
game.play('moveBalls',function() {
for(var i=game.ball.balls.length-1; i>=0; i--){
game.ball.balls[i].move();
}
},50/game.score.launcher_speed)
game.play('addBalls',function(){
that.balls.push(new Ball(game.launcher_x+25, game.launcher_y+20, "white"));
},1000/game.score.launcher_speed)
game.play('removeBalls',function(){
for(var i=that.balls.length-1; i>=0; i--){
if(that.balls[i].y<0){
that.balls.splice(i,1);
}
}
},20)
},
}
var Ball = function (x, y, color) {
this.x = x;
this.y = y;
this.color = color;
this.width = 10;
this.height = 10;
};
Ball.prototype.move = function() {
this.y -= 5
}
Ball.prototype.draw = function () {
var ctx = game.ctx;
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.strokeStyle = this.color;
ctx.arc(this.x, this.y,this.width, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
};
game.brick = {
bricks: [],
nums: [0,0,1,3,5,8],
colors: ['rgba(255,255,255,0)','rgba(255,255,255,0)','#FDD835','green','orange','red'],
init: function(){
var brick_width = game.canvas.width/8;
var brick_height = game.canvas.height/20;
var that = this;
game.play('moveBricks',function() {
for(var t=game.brick.bricks.length-1; t>=0; t--){
for(var j=0;j<8;j++){
game.brick.bricks[t][j].move();
}
}
},40)
game.play('addBricks',function(){
var bricks_j=[];
for(let i=0; i<8;i++){
var index=game.getRandom(6)
bricks_j.push(new Bricks(brick_width*i,-40,brick_width,brick_height,that.colors[index],that.nums[index]));
}
that.bricks.push(bricks_j);
bricks_j=[]
},5000)
game.play('removeBricks',function(){
for(var i=that.bricks.length-1;i>=0;i--){
if(that.bricks[i][0].y>game.canvas.height+30){
that.bricks.splice(i,1);
}
}
},100)
}
}
var Bricks = function(x,y,width,height,color,num){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
this.color=color;
this.num=num;
}
Bricks.prototype.move = function() {
this.y +=3;
}
Bricks.prototype.draw = function () {
var ctx = game.ctx;
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
ctx.font = "20px 微软雅黑";
ctx.strokeStyle = "#fff";
if(this.num >0){
ctx.strokeText(this.num,this.x+this.width/2-5,this.y+this.height/2+5)
}else{
this.color = 'rgba(255,255,255,0)';
}
ctx.fill();
ctx.stroke();
};
game.over = {
draw() {
var ctx = game.ctx;
ctx.font = "20px 微软雅黑";
ctx.fillStyle = "#fff";
ctx.fillRect((game.canvas.width-200)/2,(game.canvas.height-150)/2,200,150);
ctx.strokeStyle = '#000';
ctx.strokeText("得分:"+game.score.score_sum,(game.canvas.width-200)/2+60, (game.canvas.height-150)/2+40);
ctx.strokeText("游戏结束",(game.canvas.width-200)/2+60, (game.canvas.height-150)/2+80);
ctx.strokeText("重新开始",(game.canvas.width-200)/2+60, (game.canvas.height-150)/2+130);
ctx.stroke();
ctx.fill();
}
}
game.start();
index.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>打砖块小游戏</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="content">
<canvas id="canvas">
不支持画板对象
</canvas>
</div>
<script src="js/index.js"></script>
</body>
</html>
index.css 代码
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
width: 100%;
}
.content{
width: 375px;
margin: 0 auto;
}
canvas{
background-image: linear-gradient(#212121,#3E2723);
}