Javascript+Canvas实现吸尘器模型

来源:互联网 发布:淘宝微淘的好处 编辑:程序博客网 时间:2024/04/29 22:51

自从复旦学生网的前辈给我看了canvas标签用来做游戏的功能之后便一发不可收拾,做出了几个有意思的东西,这个吸尘器就是一个很简单的模型。


首先这个模型有两类物体:吸尘器(红色小球)、垃圾(黑色小球)。其中垃圾随机分布在画布中,吸尘器跟随鼠标移动。当吸尘器靠近垃圾的时候,垃圾会移动位置,逐渐靠近吸尘器,直到被吸入,从画布上删除。


首先定义基本属性如下:

<span style="font-size:18px;">var width = 1200;//画布宽var height = 600;//画布高var total = 1000;//小球总数</span><pre name="code" class="html"><span style="font-size:18px;">var canvas=document.getElementById('myCanvas');var ctx=canvas.getContext('2d');</span>

整个模型是逐帧操作的最简单的MVC模型,每个小球无论红黑都是一个对象,其中黑球对象储存在数组中(是否有更佳的数据结构尚未研究),

<span style="font-size:18px;">var mainball={};var allBalls = new Array();</span>

对象里储存该小球的XY坐标,注意初始状态小球是随机分布在画布中的。

<span style="font-size:18px;">function Ball()//小球构造器函数{this.x = width*Math.random();this.y = height*Math.random();}</span>


生成所有黑球的函数函数如下:

<span style="font-size:18px;">function create()//产生小球{var cre ;for(cre=0;cre<total;cre++){if(allBalls.length < total){var ball = new Ball();allBalls.push(ball);}}}</span>


对于红球的操作,即当鼠标移动的时候,获取鼠标在canvas上的坐标,在下一帧把红球坐标修改为鼠标坐标,即可实现红球跟随鼠标。

<span style="font-size:18px;">function movemainball(evt){if(!evt){evt = window.event;}var xx=evt.clientX;var yy=evt.clientY;mainball.x = xx;mainball.y = yy;}</span>


对于每一帧的动作,定义动作函数如下:

function act(){var leng =allBalls.lengthfor(var i=0;i<allBalls.length;i++){<span style="white-space:pre"></span>//遍历每个黑球var xx = allBalls[i].x-mainball.x;var yy = allBalls[i].y-mainball.y;var dis = Math.sqrt(xx*xx+yy*yy);//dis即黑球与红球的距离
if(dis<400)//当黑球距离与红球小于400px时,开始移动(这个距离可随意修改){var speed = 500/dis;//黑球距离红球越近,移动速度越快allBalls[i].x = allBalls[i].x-speed*xx/dis;allBalls[i].y = allBalls[i].y-speed*yy/dis;}if(dis<20)//距离小于20px时被“吸入”{allBalls.splice(i,1);//数组中删除该黑球元素}}}


定义绘制函数draw()

function draw(){
ctx.clearRect(0,0,width,height);//清除前一帧的内容,重绘画布
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>//绘制红球
ctx.beginPath();ctx.arc(mainball.x, mainball.y, 5, 0, Math.PI*2, true); ctx.fillStyle = "#FF0000"; ctx.fill();
<span style="white-space:pre"></span>//遍历数组,绘制黑球for(i=0;i<=allBalls.length;i++){ ctx.beginPath();ctx.arc(allBalls[i].x, allBalls[i].y, 5, 0, Math.PI*2, true); ctx.fillStyle = "#000000"; ctx.fill();}}


最后在画布上产生小球,并且用setInterval设置帧数:
create();setInterval("act()",20)//这里的帧数视性能、对流畅度的要求所定setInterval("draw()",20)



整体HTML源码如下:

<!DOCTYPE HTML><html><body><canvas id="myCanvas" width="1200" height="600">your browser does not support the canvas tag </canvas><script type="text/javascript">document.onmousemove = movemainball;var width = 1200;var height = 600;var total = 1000;var canvas=document.getElementById('myCanvas');var ctx=canvas.getContext('2d');var allBalls = new Array();var mainball={};function movemainball(evt){if(!evt){evt = window.event;}var xx=evt.clientX;var yy=evt.clientY;mainball.x = xx;mainball.y = yy;}function Ball()//小球构造器函数{this.x = width*Math.random();this.y = height*Math.random();}function create()//产生小球{var cre ;for(cre=0;cre<total;cre++){if(allBalls.length < total){var ball = new Ball();allBalls.push(ball);}}}function draw(){ctx.clearRect(0,0,width,height);ctx.beginPath();ctx.arc(mainball.x, mainball.y, 5, 0, Math.PI*2, true); ctx.fillStyle = "#FF0000"; ctx.fill();for(i=0;i<=allBalls.length;i++){ ctx.beginPath();ctx.arc(allBalls[i].x, allBalls[i].y, 5, 0, Math.PI*2, true); ctx.fillStyle = "#000000"; ctx.fill();}}function act(){var leng =allBalls.lengthfor(var i=0;i<allBalls.length;i++){var xx = allBalls[i].x-mainball.x;var yy = allBalls[i].y-mainball.y;var dis = Math.sqrt(xx*xx+yy*yy);if(dis<400){var speed = 500/dis;allBalls[i].x = allBalls[i].x-speed*xx/dis;allBalls[i].y = allBalls[i].y-speed*yy/dis;}if(dis<20){allBalls.splice(i,1);}}}function stark(){act();draw();}create();//setInterval("create()",500)setInterval("act()",20)setInterval("draw()",20)</script></body></html>



0 0
原创粉丝点击