javascript+canvas实现Go To The Moon小游戏
2016-12-08 11:55
851 查看
第一次使用这个博客系统,所以还不知道怎么弄,代码一团乱。。。。这个demo70%的自写,30%的算法,但是核心就在算法,所以相当于转载了别人的文章,算法来自《Html+javascript动画核心基础》这本书,很推荐想做web动画的同学看看!
这个demo还有问题没有解决,最后的gameOver回调函数并没有按照预期的设想弹出提示,我改了很久,始终不知道错在哪儿,希望那大大们帮我指出来!谢谢啦!
最后的插入段是js部分!太乱了。。。
Go To The Moon
*{
margin: 0;
padding: 0;
font-family: Magneto;
font-size: 16px;
color: rgb(109,178,255);
}
body{
/background: rgba(59,61,64,0.7);/当渐变不被支持时,这是垫底的背景色*/
background-color: black;
}
h1{
display: block;
font-size: 2rem;
text-align: center;
width: 70%;
margin-left: 15%;
}
#txt{
position: absolute;
top: 50px;
left: 50px;
z-index: 999999;
}
#canvasGame{
/border: 1px solid green;/
position: absolute;
top: 40px;
left: 15px;
}
.moon{
box-shadow:0 0 50px rgba(225,221,200,0.7);
}
这个demo还有问题没有解决,最后的gameOver回调函数并没有按照预期的设想弹出提示,我改了很久,始终不知道错在哪儿,希望那大大们帮我指出来!谢谢啦!
最后的插入段是js部分!太乱了。。。
Go To The Moon
*{
margin: 0;
padding: 0;
font-family: Magneto;
font-size: 16px;
color: rgb(109,178,255);
}
body{
/background: rgba(59,61,64,0.7);/当渐变不被支持时,这是垫底的背景色*/
background-color: black;
}
h1{
display: block;
font-size: 2rem;
text-align: center;
width: 70%;
margin-left: 15%;
}
#txt{
position: absolute;
top: 50px;
left: 50px;
z-index: 999999;
}
#canvasGame{
/border: 1px solid green;/
position: absolute;
top: 40px;
left: 15px;
}
.moon{
box-shadow:0 0 50px rgba(225,221,200,0.7);
}
Go To The Moon
<script type="text/javascript"> //stars绘制在canvasBg之上,rocket,moon,stone皆绘制在canvasGame之上, //rocket位置为x/y,stone为sx/sy以示区别 //检查stone和rocket的距离,如果两者collisionTimes=3,则游戏失败 //当rocket与moon距离小于两者半径之和时,游戏完成 var canvasGame=document.getElementById("canvasGame"), canvasBg=document.getElementById("canvasBg"), ctxGame=canvasGame.getContext("2d"), ctxBg=canvasBg.getContext("2d"); //设置canvasBg的宽高为全屏幕 canvasGame.width=window.innerWidth-30; canvasGame.height=window.innerHeight-50; canvasBg.width=window.innerWidth-30; canvasBg.height=window.innerHeight-50; //rocket对象 //gameOver var gameGoodOver=function(){ //clearInterval(timeId); ctxGame.clearRect(0,0,canvasGame.width,canvasGame.height); //window.cancelAnimationFrame(startGame); ctxGame.font="60px 微软雅黑 blue"; ctxGame.textAlign="center"; ctxGame.textBaseline="minddle"; ctxGame.fillText("She is gone.....",canvasGame.width/2,canvasGame.height/2); } var gameBadOver=function(){ //clearInterval(timeId); ctxGame.clearRect(0,0,canvasGame.width,canvasGame.height); //window.cancelAnimationFrame(); ctxGame.font="60px 微软雅黑 blue"; ctxGame.textAlign="center"; ctxGame.textBaseline="minddle"; ctxGame.fillText("U lost urself and her love..",canvasGame.width/2,canvasGame.height/2); } //边界检测,rocket/stone碰到边界就弹回来 var checkBorder=function(obj){ var topBorder=0, bottomBorder=canvasGame.height, rightBorder=canvasGame.width, leftBorder=0; if((obj.x+obj.radius) > rightBorder){ //this.x=canvasGame.width-10;//rocket位置重置 obj.vx *=obj.bounce;//速度向相反方向反弹,同时逐渐减少 //alert("超出右边界"); } if((obj.x-obj.radius) < leftBorder){ // this.x=this.radius; obj.vx *= obj.bounce; //alert("超出左边界"); } if((obj.y+obj.radius) > bottomBorder){ // this.y=canvasGame.height-10; obj.vy *= obj.bounce; //alert("超出下边界"); } if((obj.y-obj.radius) < topBorder){ // this.y=10; //alert("超出上边界"); obj.vy *= obj.bounce; } } //碰撞检测,发生弹动 var checkCollision=function(obj1,obj2){ var dx = obj1.x - obj2.x, dy = obj1.y - obj2.y; var dist = Math.floor(Math.sqrt( dx*dx + dy*dy )), minDist = obj1.radius + obj2.radius; //document.getElementById("txt").innerHTML=distance; if(dist < minDist){ var angle = Math.atan2(dy,dx); var tx = obj2.x + Math.cos(angle)*minDist, ty = obj2.y + Math.sin(angle)*minDist; sax = (tx - obj1.x) * obj1.spring; say = (ty - obj1.y) * obj1.spring; //alert(ax+"/"+ay); //两球互相相反方向运动 obj1.vx += sax; obj1.vy += say; obj2.vx -= sax; obj2.vy -= say; } } //颜色生成 var makeColor=function(){ var r=Math.floor(Math.random()*256+1); var g=Math.floor(Math.random()*256+1);//g在r上下五个色素之内 var b=Math.floor(Math.random()*256+1); var a=Math.random(); var color="rgba("+r+","+g+","+b+","+a+")"; return color; } //按键事件,←表示火箭向左转,→表示火箭向右转,↑表示火箭加速(pushPower) window.addEventListener("keydown",function(event){ //ctx.clearRect(0,0,width,height); switch(event.keyCode){ case 37: vr=-3;break;//之所以用3是因为转向角的计算不算快也不会太慢。。。刚合适,试出来的 case 39: vr=3;break; case 38: pushPower=0.1; rocket.flame=true; break; } },false); //松开按键之后,停止旋转,rocket加速度停止,旋转加速度也停止 window.addEventListener("keyup",function(){ vr=0; pushPower=0; rocket.flame=false; },false); var vr=0,//rocket的按键控制属性,vr用来控制旋转的角度 pushPower=0;//rocket推力 var Rocket=function(){ //rocket位置 this.x=0; this.y=0; this.vx=0; this.vy=0; //vr旋转速度向量,vx水平速度,ax水平加速度,vy竖直速度,ay竖直加速度,pushPower火箭向上的动力速度 //rocket旋转角度 this.rotation=0; //rocket是否点火,默认没有点火 this.flame=false; //rocket与border碰撞之后的反弹力 this.bounce=-0.7; this.radius=15; } //绘制rocket Rocket.prototype.drawRocket=function(ctx){ ctx.save(); //rocket的位置偏移 ctx.translate(this.x,this.y); ctx.rotate(this.rotation); ctx.lineWidth=1; ctx.strokeStyle="white"; ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(-5,-5); ctx.lineTo(0,-10); ctx.lineTo(20,0); ctx.lineTo(0,10); ctx.lineTo(-5,5); ctx.lineTo(0,0); //如果flame为true,则表示此时加速,画出火焰 if(this.flame){ ctx.moveTo(-3,-3); ctx.lineTo(-8,0); ctx.lineTo(-3,3); } ctx.closePath(); ctx.stroke(); ctx.restore(); } Rocket.prototype.chekcStone=function(stone){ var collisionTimes=0; var dx = this.x - stone.x; var dy = this.y - stone.y; var dist = Math.sqrt(dx*dx + dy*dy); var minDist = this.radius + stone.radius; if(dist < minDist){ collisionTimes++;//碰撞三次之后游戏结束 if(collisionTimes==3){ clearInterval(timeId); //window.cancelAnimationFrame(gameBadOver); gameBadOver(); } } } //绘制小行星 //star对象 var Star=function(){ this.x=Math.floor(Math.random()*canvasBg.width+1); this.y=Math.floor(Math.random()*canvasBg.height+1); } Star.prototype.drawStar=function(ctx,color){ ctx.save(); ctx.fillStyle=color; ctx.lineWidth=1; ctx.beginPath(); //ctx.arc(this.x,this.y,5,0,Math.PI*2,false); ctx.moveTo(this.x-2,this.y-2); ctx.lineTo(this.x,this.y-5); ctx.lineTo(this.x+2,this.y-2); ctx.lineTo(this.x+5,this.y); ctx.lineTo(this.x+2,this.y+1); ctx.lineTo(this.x+3,this.y+3); ctx.lineTo(this.x,this.y+2); ctx.lineTo(this.x-3,this.y+3); ctx.lineTo(this.x-2,this.y+1); ctx.lineTo(this.x-5,this.y); ctx.lineTo(this.x-2,this.y-2); //ctx.closePath(); //ctx.stroke(); ctx.fill(); ctx.restore(); } //border和star的碰撞检测,与rocket的检测 var stars=[];//存放star var starNum=Math.floor(Math.random()*150+100);//star最少有100个,最多有250个 for(var star , i = 0 ; i < starNum ; i++ ){ star=new Star(); //star.id="star"+i; star.x=Math.floor(Math.random()*canvasBg.width+1); star.y=Math.floor(Math.random()*canvasBg.height+1); stars.push(star); } for(var i=0;i<stars.length;i++){ stars[i].drawStar(ctxBg,makeColor()); } //stone陨石,从左至右,从右至左 var Stone=function(){ this.color="gray";//"rgb(86,84,73)";垫底色 this.x=0; this.y=0; this.vx=0; this.vy=0; this.radius=0; this.bounce=-0.9;//边界反弹力 this.spring=0.03;//两球碰撞反弹力 } Stone.prototype.drawStone=function(ctx){ ctx.save(); ctx.fillStyle=this.color; ctx.shadowColor="gray"; ctx.shadowBlur=this.radius/2; ctx.beginPath(); ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,false); ctx.fill(); ctx.restore(); } var stones = []; var stoneNum = 10;//Math.floor(Math.random()*15); for(var stone,i = 0 ; i < stoneNum ; i++){ stone = new Stone(); stone.x = Math.random()*(canvasGame.width-100)+20; stone.y = Math.random()*(canvasGame.height-100)+20; stone.vx = Math.random()*1-0.5; stone.vy = Math.random()*1-0.5; stone.radius = Math.floor(Math.random()*10+2); stone.color = makeColor(); //stone.rotation=Math.atan2(vx,vy); stones.push(stone); } //调用drawStone绘制stone var stoneMove=function(stone){ stone.x += stone.vx; stone.y += stone.vy; checkBorder(stone);//检查边界,碰撞反弹 stone.drawStone(ctxGame); } var showStone=function(){ //window.requestAnimationFrame(showStone); ctxGame.clearRect(0,0,canvasGame.width,canvasGame.height); //碰撞检测 for(var i=0;i<stones.length;i++){ stoneMove(stones[i]); } //showStone(); }; //moon var moon=new Stone(); moon.color="rgb(122,114,48)"; moon.x=canvasGame.width-50; moon.y=50; moon.vy=0; moon.vx=0; moon.radius=100; moon.color=makeColor(); //moon.drawStone(ctxGame); //rocket var rocket=new Rocket(); rocket.x=100; rocket.y=canvasGame.height-100; rocket.drawRocket(ctxGame); var timeId=null; var startGame=function(){ //window.requestAnimationFrame(startGame); clearInterval(timeId); timeId=setInterval(function(){ ctxGame.clearRect(0,0,canvasGame.width,canvasGame.height); //绘制stone //showStone(); //碰撞检查 for(var i=0 ; i < stones.length ; i++){ //var obj1=stones[i]; //stone和moon相碰。。 for(var j=i+1;j<stones.length; j++){ //var obj2=stones[j]; checkCollision(stones[i],moon); checkCollision(stones[i],rocket); rocket.chekcStone(stones[i]); checkCollision(stones[i],stones[j]); checkCollision(stones[j],moon); checkCollision(stones[j],rocket); rocket.chekcStone(stones[j]); showStone(); } } //rocket旋转角度,角度值 rocket.rotation += (vr*Math.PI/180); var angle=rocket.rotation; //水平加速度 rocket.ax=Math.cos(angle)*pushPower; //竖直加速度 rocket.ay=Math.sin(angle)*pushPower; //alert(ax+":"+ay); //速度等于加速度加上之前的速度 rocket.vx += rocket.ax; rocket.vy += rocket.ay; //位置等于现在位置加上速度 rocket.x += rocket.vx; rocket.y += rocket.vy; checkBorder(rocket); //检查rocket与moon位置,接触则游戏完成 if(Math.sqrt((rocket.x - moon.x)*(rocket.x - moon.x)+(rocket.y - moon.y)*(rocket.y - moon.y)) < moon.radius){ //window.cancelAnimationFrame(gameGoodOver); clearInterval(timeId); gameGoodOver(); } //document.getElementById("txt").innerHTML="rocket.rotation:"+rocket.x+":"+rocket.y; rocket.drawRocket(ctxGame); //startGame(); //绘制moon moon.drawStone(ctxGame); //startGame(); },1000/60) }; startGame(); </script> </html>
相关文章推荐
- Go实战--实现一个简单聊天室chatroom(The way to go)
- Go实战--实现一个并发时钟服务器(The way to go)
- 【JavaScript】canvas实现一个小游戏
- Go实战--实现一个单向链表(The way to go)
- Go实战--实现一个自己的网络请求日志httplogger(The way to go)
- #715 – 在Canvas中使用Thumb控件实现拖动目标的功能(Using the Thumb Control to Drag Objects on a Canvas)
- Go实战--实现简单的restful api(The way to go)
- javascript+canvas实现小游戏-贪吃蛇
- Go实战--实现一个简单的tcp服务端和客户端(The way to go)
- "Go to the Main Table Form" differences between Axapta 2.x and Dynamics AX 4
- [Javascript] A function works like 'print_r()' in PHP to print out the details of an object for JS debugging
- Using the Dojo JavaScript Library to Build Ajax Applications一书翻译完毕
- JS两栏等高:Javascript set two columns to have the same height
- make the javascript to run in innerHTML
- How to overwrite the method in Javascript
- Using the Dojo JavaScript Library to Build Ajax Applications一书翻译完毕
- Dojo: Using the Dojo JavaScript Library to Build Ajax Applications
- FCKEditor 2.x: How to add a new button with custom javascript to the toolbar
- Go to study out of the dormitory again
- 实现zoom to the selected feature之一:了解QueryAttributesTask control