这是一个非常基础的躲避小行星的游戏,在Canvas中采用一些基本技巧来创建动画和交互式游戏。
成品链接:http://www.gilbertsun.net/Asteroid%20avoidance/index.htmlHTML和CSS文件没什么可说的,就直接从JavaScript代码开始
重置和启动游戏函数的建立
function startGame(){
//重置游戏状态
uiScore.html("0");
uiStats.show();
//初始游戏设置
playGame=false;
//声明需要使用的小行星数目
asteroids=new Array();
numAsteroids=10;
score=0
//创建玩家对象的位置
player=new Player(canvasWidth/2,500);
//创建小行星(重点说一句,因为开始阶段小行星在界面之上,所以y的位置是“-小行星半径-随机数”,这样就能保证小行星初始位置在画布上面)
for(var i=0; i<numAsteroids; i++){
var radius=5+(Math.random()*10);
var x=Math.floor(Math.random()*canvasWidth);
var y=-radius-Math.floor(Math.random()*canvasHeight);
var vY=5+(Math.random()*5);
asteroids.push(new Asteroid(x,y,radius,vY));
};
//键盘监听
$(window).keydown(function(e){
var keyCode=e.keyCode;
if(!playGame){
playGame=true;
soundBackground.currentTime=0;
soundBackground.play();
timer();
animate();
};
if(keyCode==arrowUp){
player.moveUp=true;
if(soundThrust.paused){
soundThrust.currentTime=0;
soundThrust.play();
};
}else if(keyCode==arrowDown){
player.moveDown=true;
}else if(keyCode==arrowRight){
player.moveRight=true;
}else if(keyCode==arrowLeft){
player.moveLeft=true;
};
});
$(window).keyup(function(e){
var keyCode=e.keyCode;
if(keyCode==arrowUp){
player.moveUp=false;
soundThrust.pause();
}else if(keyCode==arrowDown){
player.moveDown=false;
}else if(keyCode==arrowRight){
player.moveRight=false;
}else if(keyCode==arrowLeft){
player.moveLeft=false;
};
if (keyCode==space){
bullets.shoot=false;
};
});
//开始动画循环
animate();
};
初始化游戏环境
function init(){
uiStats.hide();
uiComplete.hide();
uiPlay.click(function(e){
e.preventDefault();
uiIntro.hide();
soundThrust.pause();
soundBackground.pause();
startGame();
});
uiReset.click(function(e){
e.preventDefault();
uiComplete.hide();
//重置时删除监听
$(window).unbind("keyup");
$(window).unbind("keydown");
clearTimeout(scoreTimeout);
startGame();
});
};
//计时器函数
function timer(){
if(playGame){
scoreTimeout=setTimeout(function(){
uiScore.html(++score);
//增加游戏难度(根据分数来增加难度,每增加5分,小行星的数量增加5个)
if(score%5==0){
numAsteroids +=5;
};
timer();
},1000);
};
};
动画循环,游戏的关键就在这里
function animate(){
//清除
context.clearRect(0,0,canvasWidth,canvasHeight);
//更新小行星的位置
var asteroidsLength=asteroids.length;
for(var i=0;i<asteroidsLength;i++){
var tmpAsteroid=asteroids[i];
tmpAsteroid.y +=tmpAsteroid.vY;
//背景纵向循环(这个循环实现玩家永无止境穿越的效果,每当小行星移动到画布下方之时,都重置小行星到画布上方,看上去像是一颗全新的小行星,其实还是原来的那一颗)
if(tmpAsteroid.y+tmpAsteroid.radius>600){
tmpAsteroid.radius=5+(Math.random()*10);
tmpAsteroid.x=Math.floor(Math.random()*canvasWidth);
tmpAsteroid.y=-tmpAsteroid.radius;
tmpAsteroid.vY=5+(Math.random()*5);
};
//碰撞检测(勾股定理,根据小行星和玩家的x,y,求出他们之间的距离)
var dX=player.x+player.halfWidth-tmpAsteroid.x;
var dY=player.y+player.halfHeight-tmpAsteroid.y;
var distance=Math.sqrt((dX*dX)+(dY*dY));
if (distance<player.halfHeight+tmpAsteroid.radius){
soundThrust.pause();
soundDeath.currentTime=0;
soundDeath.play();
//游戏结束
playGame=false;
clearTimeout(scoreTimeout);
uiStats.hide();
uiComplete.show();
soundBackground.pause();
$(window).unbind("keyup");
$(window).unbind("keydown");
};
context.fillStyle="rgb(192,192,192)";
context.beginPath();
context.arc(tmpAsteroid.x,tmpAsteroid.y,tmpAsteroid.radius,0,Math.PI*2,true);
context.closePath();
context.fill();
};
//显示玩家的飞船(通过控制速度来实现玩家飞船的移动)
player.vX=0;
player.vY=0;
if(player.moveUp){
player.vY=-3;
};
if(player.moveDown){
player.vY=3;
};
if(player.moveRight){
player.vX=3;
};
if(player.moveLeft){
player.vX=-3;
};
player.x +=player.vX;
player.y +=player.vY;
//添加边界
if(player.x-player.halfWidth<20){
player.x=20+player.halfWidth;
}else if(player.x+player.halfWidth>canvasWidth-20){
player.x=canvasWidth-20-player.halfWidth;
}
if(player.y-player.halfHeight<20){
player.y=20+player.halfHeight;
}else if(player.y+player.halfHeight>canvasHeight-20){
player.y=canvasHeight-20-player.halfHeight;
};
//绘制飞船火焰(绘制一个橘色三角形作为火焰,飞船屁股中心向左减5为起点,y轴加火焰长度为第二个点,屁股中心向右加5为终点)
if(player.moveUp){
context.save();
context.translate(player.x+player.halfWidth,player.y+player.height);
if(player.flameLength==20){
player.flameLength=15;
}else{
player.flameLength=20;
};
context.fillStyle="orange";
context.beginPath();
context.moveTo(-5,0);
context.lineTo(0,player.flameLength);
context.lineTo(5,0);
context.closePath();
context.fill();
context.restore();
};
//绘制飞船的形状
if(player.vX==0){
context.drawImage(ship_center,player.x,player.y,player.width,player.height);
}else if(player.moveLeft){
context.drawImage(ship_left,player.x,player.y,player.width,player.height);
}else if(player.moveRight){
context.drawImage(ship_right,player.x,player.y,player.width,player.height);
};
//增加小行星数量
while(asteroids.length<numAsteroids){
var radius=5+(Math.random()*10);
var x=Math.floor(Math.random()*canvasWidth);
var y=-Math.floor(Math.random()*canvasHeight)-radius;
var vY=5+(Math.random()*5);
asteroids.push(new Asteroid(x,y,radius,vY));
};
if(playGame){
//33毫秒后再次运行动画循环
setTimeout(animate,33);
};
};
init();
});
游戏很简单,不过当个课程设计足够了
源码下载http://www.kuaipan.cn/file/id_131656939649106455.htm