经典游戏打砖块(粗糙版)
经典游戏打砖块(粗糙版)
简略地实现了游戏的主要逻辑,运行结果存在bug,当小球碰到挡板的边缘处,有时会发生颤动,个人猜测是因为碰撞检测时vy不断自乘-1导致,若有不同看法欢迎私聊讨论。
具体代码
<html>
<head>
<title>Breaker</title>
</head>
<body>
<canvas id = "gameCanvas" width="1024" height="768"></canvas>
<script src="breaker.js" type="text/javascript"></script>
</body>
</html>
breaker.js
window.onload = init;
window.onmousemove = mouseMoveHandler;
var context;
var bg2,ball,board;
//canvas的宽高
var cW= 1024,cH=768;
//挡板坐标
var boardX = 0,boardY = 630;
//小球坐标
var ballX= 400,ballY = 350;
//小球的速度
var vx = 4,vy = -8;
var bricks = [];
var hit;
var myInterval;
//初始化
function init(){
//获取canvas(获取画板)
var canvas = document.getElementById("gameCanvas");
//获取2d画布并交给画家context
context = canvas.getContext("2d");
//获取背景图片
bg2=addImage("assets/bg2.jpg");
//获取挡板图片
board= addImage("assets/5.png");
//获取小球图片
ball= addImage("assets/ball2.png");
//生成砖块
createBricks();
//添加循环机制
myInterval = setInterval(gameTick,1000 / 60);
}
//显示砖块
function updateBricks() {
// body...
for(var i =0;i<bricks.length;i++){
var item = bricks[i];
context.drawImage(item.item,item.x,item.y);
}
}
//产生砖块
function createBricks() {
// body...
for(var i = 0;i<7;i++){
for(var j= 0;j<4;j++){
var item = addImage("./assets/5.png");
// item.x=20+198*i;
// item.y = 95;
bricks.push({item:item,x:20+145*i,y:31+40*j});
}
}
}
//游戏循环逻辑
function gameTick(){
//清屏
clearScreen();
//绘制背景
context.drawImage(bg2,0,0);
//绘制挡板
context.drawImage(board,boardX,boardY);
//更新绘制砖块
updateBricks();
//更新小球位置
updateball();
//球板碰撞
ballHitboard();
//球砖碰撞
ballHitbricks();
}
//更新小球坐标
function updateball(){
ballX+=vx;
ballY+=vy;
if(ballX<0){
ballX = 0;
vx*=-1;
}else if(ballX>cW-ball.width){
ballX = cW-ball.width;
vx*=-1;
}
if(ballY<0){
ballY = 0;
vy*=-1;
}else if(ballY>cH-ball.height){
alert("gameover!");
clearInterval(myInterval);
}
context.drawImage(ball,ballX,ballY);
}
//鼠标控制挡板
function mouseMoveHandler(e){
boardX = e.x-board.width/2;
if(boardX<0){
boardX = 0;
}
else if(boardX>1024-board.width){
boardX = 1024-board.width;
}
}
//清屏
function clearScreen(){
context.clearRect(0,0,cW,cH);
}
//添加图片
function addImage(url){
var img = new Image();
img.src = url;
return img;
}
//输出log到控制台
function log(msg){
console.log(msg);
}
function test_ballHitboard(x,y,a,b,W,H) {
// body...
if(a-ball.width<=x && x<=a+W &&
y+ball.height>=b && y+ball.height<=b+H){
return true;
}
else return false;
}
//球板碰撞
function ballHitboard() {
hit = test_ballHitboard(ballX,ballY,boardX,boardY,board.width,board.height);
if(hit){
vy*=-1;
}
}
//球砖碰转
function ballHitbricks() {
// body...
for (var i = bricks.length-1;i>=0;i--){
var item = bricks[i];//把砖块取出来逐个判断是否发生碰撞
hit = test_ballHitbricks(ballX,ballY,item.x,item.y);
if(hit){
bricks.splice(i,1);//如果发生碰撞,则删除该砖块
vy*=-1;
}
}
}
//检测球砖碰撞
function test_ballHitbricks(ballX,ballY,bricksX,bricksY) {
// body...
if(ballX>=bricksX-ball.width && ballX<=bricksX+121 && ballY>=bricksY-29 && ballY<=bricksY)
return true;
else return false;
}
文件列表
- Breakers
- assets
- 5.png//砖块
- bg2.jpg//背景
- ball2.png//小球
- board.png//挡板
//上面四张图请自行制作
- index.html
- breaker.js
- assets