您好,登錄后才能下訂單哦!
2.canvas模擬重力
上一章中,知道了怎么在canvas中畫圖,知道了球是怎么運(yùn)動(dòng)起來的.那么就來模擬一下球在重力下的運(yùn)動(dòng).思路有2個(gè).
1.設(shè)球的初始位置是: x0,y0.時(shí)間是t.那么用公式 S = x0 + v0 * t +0.5 * a * t *t;
就是路程 = 初速度*時(shí)間 + 1/2*加速度*時(shí)間的平方.
我們可以得到客戶端的時(shí)間,沒一幀都用初始點(diǎn)來計(jì)算.
2.我們可以算出每一幀的速度,然后進(jìn)行移動(dòng).
來看看下面的代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>小球自由落體</title> <!------------------------------------------------------------------------------> <style type="text/css"> body{margin:0px; background:#154654;} #myCanvas{ border:1px #0000FF solid;} </style> <!------------------------------------------------------------------------------> <script type="text/javascript"> var SCREEN_WIDTH = screen.availWidth; var SCREEN_HEIGHT = screen.availHeight; </script> </head> <body> <canvas id="myCanvas" <!-- -->> your browser is not support canvas. </canvas> <!----------------------------------------------------------------------------> <script type="text/javascript"> function ballMove(canvasID) { var canvas = document.getElementById(canvasID); //得到canvas canvas.width = SCREEN_WIDTH; canvas.height = SCREEN_HEIGHT; var canvas2D = canvas.getContext("2d"); var refreshRate = ~~(1000/30); //刷新速率 var radius = 100; //園的半徑 var ballColor = "rgba(255,255,0,1)" //圓的顏色 var x = 0; //圓心的運(yùn)動(dòng)坐標(biāo) var y = 0; var x0 = 100; //球的起始位置 var y0 = 600; var yt = 0; //縱坐標(biāo)時(shí)間 var xt = 0; //橫坐標(biāo)時(shí)間 var flashT = 0.05; //踩點(diǎn)率 越低越精致 var vx = 100; //求的起始速度,注意方向. var vy = -100; var rate_x = vx; //球的實(shí)際速度 var rate_y = vy; var ax = 0; //X方向加速度 var ay = 15; //y方向加速度 var x_off = 10; //x方向移動(dòng)速度 var y_off = 10; //y方向移動(dòng)速度 var damping = 0; //球的阻尼效果 var damping_off = 0; var flagx = 1; //標(biāo)志變量 var flagy = 1; var flag = 1; var carshRight = SCREEN_WIDTH - radius; //碰撞的實(shí)際寬度 var carshButtom = SCREEN_HEIGHT - radius; //碰撞的實(shí)際高度 var carshLeft = 0 + radius; var carshTop = 0 +radius; stopBall = setInterval( function() { //第一幀 x = x0 + (vx*xt + 0.5*ax*xt*xt); y = y0 + (vy*yt + 0.5*ay*yt*yt); //判斷 if(y > carshButtom) //到底了 { y = carshButtom; y0 = carshButtom; if(flag == 1) { vate_y = vy + ay*yt; flag = -1; } vy = vate_y * -1; vate_y = vate_y - damping; damping = damping - damping_off; yt = 0; if(vy > 0) clearInterval(stopBall); //球停止了. //alert(damping); //if(damping <= 9)alert(1);//clearInterval(stopBall); } //畫圖 canvas2D.beginPath(); ////下面兩句是清除畫布的功能 canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); canvas2D.arc(x,y,radius,0,Math.PI*2,false); canvas2D.fillStyle = ballColor; canvas2D.fill(); //改變 /* x = x + flagx * x_off; y = y + flagy * y_off; if( (x+radius) > SCREEN_WIDTH || (x-radius) < 0)flagx *= -1; if( (y+radius) > SCREEN_HEIGHT || (y-radius) < 0)flagy *= -1; if( x > carshRight || x < carshLeft)flagx *= -1; if( y > carshButtom || y < carshTop)flagy *= -1;*/ xt = xt + flashT; yt = yt + flashT; /* if(y > carshButtom) //到底了 { if(flagx == 1) { vate_y = vy + 9.8*t; vy = vate_y * -1; t = 0; flagx = -1; } } if(t > 1)flagx = 1;*/ } ,refreshRate); } //canvas 的寬和高默認(rèn)為 300 * 150,注意設(shè)置數(shù)值都時(shí)候,不用加單位,不用加"PX"; ballMove("myCanvas"); //go canvas painer </script> </body> </html>
這個(gè)是用時(shí)間來改變的.其實(shí)我們可以用向量.自己定義一個(gè)向量類,用向量就能實(shí)驗(yàn)了.這個(gè)時(shí)候,小球就能進(jìn)行自由下落了.我們可以給他的初速度用拖動(dòng)來控制.例如這樣:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>小球自由落體+拖動(dòng)</title> <!------------------------------------------------------------------------------> <style type="text/css"> body{margin:0px;} #myCanvas{ border:1px #0000FF solid;} </style> <!------------------------------------------------------------------------------> <script type="text/javascript"> var SCREEN_WIDTH = screen.availWidth; var SCREEN_HEIGHT = screen.availHeight - 150; </script> </head> <body> <!--<div > 小球的半徑<input type="text" value="" /> 小球的顏色<input type="text" value="" /> 水平方向加速度<input type="text" value="" /> 豎直方向加速度<input type="text" value="" /> </div>--> <canvas id="myCanvas" > your browser is not support canvas. </canvas> <!----------------------------------------------------------------------------> <script type="text/javascript"> function ballMove(canvasID,x0,y0,vx,vy,ax,ay,radius,damping,flashT) { var canvas = document.getElementById(canvasID); //得到canvas canvas.width = SCREEN_WIDTH; canvas.height = SCREEN_HEIGHT; var canvas2D = canvas.getContext("2d"); var refreshRate = ~~(1000/60); //刷新速率 var radius = radius||30; //園的半徑 var ballColor = lineColor//圓的顏色 var x = 0; //圓心的運(yùn)動(dòng)坐標(biāo) var y = 0; var x0 = x0||500; //球的起始位置 var y0 = y0||300; var yt = 0 //縱坐標(biāo)時(shí)間 var xt = 0 //橫坐標(biāo)時(shí)間 var flashT = flashT||0.1; //踩點(diǎn)率 越低越精致 var vx = vx||0; //求的起始速度,注意方向. var vy = vy||0; var rate_x = vx; //球的實(shí)際速度 var rate_y = vy; var ax = ax||0; //X方向加速度 var ay = ay||10; //y方向加速度 var x_off = 10; //x方向移動(dòng)速度 var y_off = 10; //y方向移動(dòng)速度 var damping = damping||0; //球的阻尼效果 var damping_off = 0.5; var flagx = 1; //標(biāo)志變量 var flagy = 1; var flag = 1; var carshRight = SCREEN_WIDTH - radius; //碰撞的實(shí)際寬度 var carshButtom = SCREEN_HEIGHT - radius; //碰撞的實(shí)際高度 var carshLeft = 0 + radius; var carshTop = 0 +radius; stopBall = setInterval( function() { //第一幀 x = x0 + (vx*xt + 0.5*ax*xt*xt); y = y0 + (vy*yt + 0.5*ay*yt*yt); //判斷 if(y > carshButtom) //到底了 { y = carshButtom; y0 = carshButtom; if(flag == 1) { vate_y = vy + ay*yt; flag = -1; } vy = vate_y * -1; vate_y = vate_y - damping; damping = damping - damping_off; if(damping < 0)damping = 0; yt = 0; if(vy > 0) clearInterval(stopBall); //球停止了. //alert(damping); //if(damping <= 9)alert(1);//clearInterval(stopBall); } //畫圖 canvas2D.beginPath(); ////下面兩句是清除畫布的功能 canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); canvas2D.arc(x,y,radius,0,Math.PI*2,false); canvas2D.fillStyle = ballColor; canvas2D.fill(); //改變 /* x = x + flagx * x_off; y = y + flagy * y_off; if( (x+radius) > SCREEN_WIDTH || (x-radius) < 0)flagx *= -1; if( (y+radius) > SCREEN_HEIGHT || (y-radius) < 0)flagy *= -1; if( x > carshRight || x < carshLeft)flagx *= -1; if( y > carshButtom || y < carshTop)flagy *= -1;*/ xt = xt + flashT; yt = yt + flashT; //最后一幀 if(isDown) { clearInterval(stopBall); //重新繪圖 canvas2D.beginPath(); ////下面兩句是清除畫布的功能 canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); canvas2D.arc(evt.clientX,evt.clientY,radius,0,Math.PI*2,false); canvas2D.fillStyle = ballColor; canvas2D.fill(); } /* if(y > carshButtom) //到底了 { if(flagx == 1) { vate_y = vy + 9.8*t; vy = vate_y * -1; t = 0; flagx = -1; } } if(t > 1)flagx = 1;*/ } ,refreshRate); //alert(1); } </script> <script type="text/javascript"> var x0 = 0; var y0 = 0; var ballX = 0; var ballY = 0; var x1 = 0; var y1 = 0; var upX = 0; var upY = 0; var evt,evt1,evt2; var startTime = 0; var stopTime = 0; var getvx = 0; var getvy = 0; var isDown = false; var radius = 30; var canvas = document.getElementById("myCanvas"); //得到canvas var canvas2D = canvas.getContext("2d"); var lineColor = canvas2D.createLinearGradient(0,0,1366,768); lineColor.addColorStop(0,"rgba(0,0,0,1)"); lineColor.addColorStop(0.2,"rgba(120,0,0,1)"); lineColor.addColorStop(0.4,"rgba(0,120,0,1)"); lineColor.addColorStop(0.6,"rgba(0,0,255,1)"); lineColor.addColorStop(0.8,"rgba(125,45,0,1)"); lineColor.addColorStop(1,"rgba(45,86,111,1)"); var ballColor = lineColor; canvas.width = SCREEN_WIDTH; canvas.height = SCREEN_HEIGHT; function getOldMouseXY() { evt = event || window.event; x0 = evt.clientX; y0 = evt.clientY; isDown = true; //alert(ball.getBoundingClientRect().left); ballX = x0; ballY = y0; //畫圖 //alert(1); canvas2D.beginPath(); ////下面兩句是清除畫布的功能 canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); canvas2D.arc(x0,y0,radius,0,Math.PI*2,false); canvas2D.fillStyle = ballColor; canvas2D.fill(); //alert(ballY); startTime = new Date(); } function getNewMouseXY() { evt1 = event || window.event; //alert(upX+","+upY+" "+x1+","+y1); //速度計(jì)算 stopTime = new Date(); var timeOff = stopTime.getTime() - startTime.getTime(); getvx = ~~((x1 - x0)*100/timeOff); getvy = ~~((y1 - y0)*100/timeOff); //alert(getvx+","+getvy); // alert(timeOff); //畫圖 ballMove("myCanvas",x1,y1,getvx,getvy,0,10,radius,10); isDown = false; } function dragBall() { evt2 = event || window.event; if(isDown) //是否按下了鼠標(biāo)左鍵 { x1 = evt2.clientX; y1 = evt2.clientY; var dragX = x1-x0+ballX; var dragY = y1-y0+ballY; //畫圖 canvas2D.beginPath(); ////下面兩句是清除畫布的功能 canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT); canvas2D.arc(dragX,dragY,radius,0,Math.PI*2,false); canvas2D.fillStyle = ballColor; canvas2D.fill(); } } </script> <script type="text/javascript"> //var ball = document.getElementById("myCanvas"); = getOldMouseXY; //注意給一個(gè)事件賦值的時(shí)候,不用加括號(hào). = dragBall; = getNewMouseXY; </script> </body> </html>
這樣就小球就能用鼠標(biāo)進(jìn)行初始度的開始了.可是現(xiàn)在我們沒有實(shí)現(xiàn)什么類啊,沒有用到JS的類.在接下來的學(xué)習(xí)中,我將自己來建立一個(gè)類,用這個(gè)類來實(shí)驗(yàn)這些效果.
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。