版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、用html5打造斯諾克桌球俱樂部設(shè)計(jì)案例本文介紹了如何利用html5技術(shù)來打造一款非??岬乃怪Z克桌球游戲,文章中詳細(xì)地列出了開發(fā)的全過程,并解說了實(shí)現(xiàn)這個游戲的幾個關(guān)鍵點(diǎn)。在文章末尾我向大家提供了游戲的在線實(shí)例頁面和源碼下載鏈接,如果你只是想玩玩(需要使用支持html5的瀏覽器,建議使用chrome 12, internet explorer 9 或者 fire fox 5及其以上版本),那你可以跳過正文拉到頁面最底端去玩玩那個游戲或者下載源碼,但我建議你好好看看實(shí)現(xiàn)過程,對我們學(xué)習(xí)html5非常有幫助。 毫無疑問,我們已經(jīng)目睹了html5背后的那場偉大的web開發(fā)革命。經(jīng)過那么多年html4
2、的統(tǒng)治,一場全新的運(yùn)動即將完全改變現(xiàn)在的web世界。正是他釋放出來的現(xiàn)代化氣息和豐富的用戶體驗(yàn),讓它很快地成為了一個獨(dú)特的插件運(yùn)行在類似flash和silverlight的框架之上。如果你是一個非常年輕的開發(fā)者,也許你是剛剛在開始學(xué)習(xí)html5,所以可能你并沒有注意到他有太大的變化。在任何時候,我希望這篇文章能夠幫助到你,當(dāng)然,也希望像我一樣的老手能從中學(xué)到一些新的花樣。你的點(diǎn)評對我來說非常重要,所以我很期待你的來信。當(dāng)然能讓我更興奮的是當(dāng)你在那個游戲畫面上右擊時暗暗地說一句“hey,這居然不是flash!也不是silverlight!”系統(tǒng)要求想要使用本文提供的html5桌球應(yīng)用,你必須安裝
3、下面的這些瀏覽器:chrome 12, internet explorer 9 or fire fox 5游戲規(guī)則也許你已經(jīng)知道這是一個什么樣的游戲了,是的,這是“英式斯諾克”,實(shí)際上更確切的說是“簡易版英式斯諾克”,因?yàn)闆]有實(shí)現(xiàn)所有的斯諾克游戲規(guī)則。你的目標(biāo)是按順序?qū)⒛繕?biāo)球灌入袋中,從而比其他選手得到更多的分?jǐn)?shù)。輪到你的時候,你就要出桿了:根據(jù)提示,你必須先打進(jìn)一個紅色球得到1分,如果打進(jìn)了,你就可以繼續(xù)打其他的球 - 但是這次你只能打彩色球了(也就是除紅色球以外的球)。如果成功打進(jìn),你將會得到各自彩球?qū)?yīng)的分?jǐn)?shù)。然后被打進(jìn)的彩球會回到球桌上,你可以繼續(xù)擊打其他的紅球。這樣周而復(fù)始,直到你失
4、敗為止。當(dāng)你把所有的紅球都打完以后,球桌上就只剩下6個彩球了,你的目標(biāo)是將這6個彩球按以下順序依次打入袋中:黃(2分)、綠(3分)、棕(4分)、藍(lán)(5分)、粉(6分)、黑(7分)。如果一個球不是按上面順序打進(jìn)的,那它將會回到球桌上,否則,它最終會留在袋里。當(dāng)所有球都打完后,游戲結(jié)束,得分最多的人勝出。犯規(guī)處理為了處罰你的犯規(guī),其他選手將會得到你的罰分: 白球掉入袋中罰4分 白球第一次擊中的球是錯誤的話罰第一個球的分值 第一個錯誤的球掉入袋中罰第一個球的分值 處罰的分?jǐn)?shù)至少是4下面的這段代碼展示了我是如何來計(jì)算犯規(guī)的:1. var strokenballscount =
5、60;0; 2. console.log('strokenballs.length: ' + strokenballs.length); 3. for (var i = 0; i < strokenballs.length; i+) 4. var ball
6、;= strokenballsi; 5. /causing the cue ball to first hit a ball other than the ball on 6. if (strokenballscount =
7、 0) 7. if (ball.points != teamsplayingteamid - 1.ballon.points) 8. if (ba
8、ll.points = 1 | teamsplayingteamid - 1.ballon.points = 1 | 9. fallenredcount = redcount) 10.
9、160; if (teamsplayingteamid - 1.ballon.points < 4) 11.
10、160; teamsplayingteamid - 1.foullistteamsplayingteamid - 1 12. .foullist.length = 4; 13.
11、160; $('#gameevents').append(' 14. foul 4 points : expected ' + 15. &
12、#160; teamsplayingteamid - 1.ballon.points + ', but hit ' + ball.points); 16.
13、160; 17. else 18.
14、 teamsplayingteamid - 1.foullistteamsplayingteamid - 1 19. .foullist.le
15、ngth = teamsplayingteamid - 1.ballon.points; 20. $('#gameevents').append(' 21. foul ' + teams
16、playingteamid - 1 22. .ballon.points + ' points : expected ' + teamsplayingteamid
17、;- 1 23. .ballon.points + ', but hit ' + ball.points); 24. &
18、#160; 25. break; 26.
19、60; 27. 28. 29. 30. strokenballscount+; 31.
20、 32. 33. /foul: causing the cue ball to miss all object balls 34. if (strokenballscount = 0) 35. teamsplayin
21、gteamid - 1.foullistteamsplayingteamid - 1.foullist.length = 4; 36. $('#gameevents').append(' 37. foul 4 points : causing the cue ball 38.
22、 to miss all object balls'); 39. 40. 41. for (var i = 0; i < pottedballs.length; i+) 42.
23、; var ball = pottedballsi; 43. /causing the cue ball to enter a pocket 44. if (ball.points = 0)
24、60; 45. teamsplayingteamid - 1.foullistteamsplayingteamid - 1.foullist.length = 4; 46. $('#gameevents').ap
25、pend(' 47. foul 4 points : causing the cue ball 48. to enter a pocket'); 49. 50.
26、0; else 51. /causing a ball different than the target ball to enter a pocket 52.
27、60; if (ball.points != teamsplayingteamid - 1.ballon.points) 53. if (ball.points = 1 | teamsplayingteamid
28、160;- 1.ballon.points = 1 54. | fallenredcount = redcount) 55.
29、60; if (teamsplayingteamid - 1.ballon.points < 4) 56. teamsplayingteamid - 1.
30、foullistteamsplayingteamid - 1 57. .foullist.length = 4; 58.
31、60; $('#gameevents').append(' 59. foul 4 points : ' 60.
32、; + ball.points + ' was potted, while ' + teamsplayingteamid - 1 61. &
33、#160; .ballon.points + ' was expected'); 62. $('#gameevents').append(' 63. ball.points:
34、' + ball.points); 64. $('#gameevents').append(' 65. teamsplayingteamid - 1 66.
35、; .ballon.points: ' + teamsplayingteamid - 1.ballon.points); 67.
36、60; $('#gameevents').append(' 68. fallenredcount: ' + fallenredcount); 69.
37、60; $('#gameevents').append(' 70. redcount: ' + redcount); 71. 72.
38、0; else 73. teamsplayingteamid - 1.foullistteamsplayingteamid
39、160;- 1 74. .foullist.length = teamsplayingteamid - 1.ballon.points; 75.
40、0; $('#gameevents').append(' 76. foul ' + teamsplayingteamid - 1 77.
41、; .ballon.points + ' points : ' + ball.points + ' was potted, while ' 78.
42、160; + teamsplayingteamid - 1.ballon.points + ' was expected'); 79.
43、0; 80. 81. 82. 83. 得分我們根據(jù)下面
44、的規(guī)則來計(jì)算得分:紅(1分)、黃(2分)、綠(3分)、棕(4分)、藍(lán)(5分)、粉(6分)、黑(7分)。代碼如下:1. if (teamsplayingteamid - 1.foullist.length = 0) 2. for (var i = 0; i < pottedballs.length; i+)&
45、#160; 3. var ball = pottedballsi; 4. /legally potting reds or colors
46、0;5. wonpoints += ball.points; 6. $('#gameevents').append(' 7. potted +'
47、;+ ball.points + ' points.'); 8. 9. 10. else 11.
48、; teamsplayingteamid - 1.foullist.sort(); 12. lostpoints = teamsplayingteamid - 1.foullistteamsplayingteamid - 1.foullist.length - 1; 13.
49、; $('#gameevents').append(' 14. lost ' + lostpoints + ' points.'); 15. 16. teamsplayingtea
50、mid - 1.points += wonpoints; 17. teamsawaitingteamid - 1.points += lostpoints; 選手的閃動動畫頭像游戲是有兩位選手參與的,每一位選手都有自己的昵稱和頭像,選手的昵稱我們就簡單地以“player 1”和“player 2”來命名了(也許讓用戶自己輸入會更漂亮)。每位選手的頭像是一只正在打桌球的可愛小狗。當(dāng)輪到其中一位選手時,他的頭像就會
51、有一閃一閃的動畫效果,同時對手的頭像會停止閃動。這個效果我們是通過改變img元素的css3屬性opacity的值來實(shí)現(xiàn)的:我們使用jquery的animatio函數(shù)讓opacity的值在0-1.0之間變化。1. function animatecurrentplayerimage() 2. var otherplayerimageid = 0; 3. if (playingteamid = 1)
52、 4. otherplayerimageid = 'player2image' 5. else 6. otherplayerimageid = 'player1image' 7. var
53、60;playerimageid = 'player' + playingteamid + 'image' 8. $('#' + playerimageid).animate( 9. opacity: 1.0 10. , 5
54、00, function () 11. $('#' + playerimageid).animate( 12. opacity: 0.0 13. ,&
55、#160;500, function () 14. $('#' + playerimageid).animate( 15. opacity: 1.0
56、16. , 500, function () 17. ); 18. ); 19. ); &
57、#160;20. 21. $('#' + otherplayerimageid).animate( 22. opacity: 0.25 23. , 1500, function () 24. );
58、25. 力量控制條一個優(yōu)秀的斯諾克選手都能很好地把握住每一桿的力度.不同的技巧需要不同的擊球方式:直接的,間接的,或者利用邊角的等等。不同方向和不同力度的組合可以構(gòu)造成千上萬種可能的路徑。幸運(yùn)的是,這個游戲提供了一個非常漂亮的力度控制條,可以幫助選手在擊球前調(diào)整他們的球桿。為了達(dá)到這一點(diǎn),我們使用了html5的meter元素標(biāo)簽,它可以完成測量距離的工作。meter標(biāo)簽最好在知道這次測量的最小值和最大值的情況下使用。在我們的這個例子中,這個值在0到100之間,因?yàn)閕e9不支持meter,所以我用了一張背景圖來替代,這樣效果也是一樣的。1. #strengthbar
59、60;position: absolute; margin:375px 0 0 139px; 2. width: 150px; color: lime; background-color: orange; 3. z-index: 5; 當(dāng)你點(diǎn)擊了力度條后,你實(shí)際上是選擇了一個新的力度。一開始你可能不是很熟練,但在真實(shí)世界中,這是需要時
60、間來訓(xùn)練自己的能力的。點(diǎn)擊力度條的代碼如下:1. $('#strengthbar').click(function (e) 2. var left = $('#strengthbar').css('margin-left').replace('px', ''); 3. var x = e.pagex
61、0;- left; 4. strength = (x / 150.0); 5. $('#strengthbar').val(strength * 100); 6. ); 在當(dāng)前選手的頭像框里面,你會注意到有一個小球,我叫他“ball on”,就是當(dāng)前選手在規(guī)定時間內(nèi)應(yīng)該要擊打的那個球。如果這個球消失了,那選手將失去4分。同樣如果選手第一次擊中的球不是框內(nèi)顯示的球,那他
62、也將失去4分。這個“ball on”是直接將canvas元素覆蓋在用戶頭像上的,所以你在頭像上看到的那個球,他看起來像是在標(biāo)準(zhǔn)的div上蓋了一個img元素,但是這個球并不是img實(shí)現(xiàn)的。當(dāng)然我們也不能直接在div上畫圓弧和直線,這就是為什么我要將canvas覆蓋到頭像上的原因了??纯创a吧:1. <canvas id="player1ballon" class="player1ballon"> 2. </canvas> <c
63、anvas id="player2ballon" class="player2ballon"> 3. </canvas> 1. var player1balloncontext = player1balloncanvas.getcontext('2d'); 2. var player2balloncontext = player2balloncanvas.getcontext('2d
64、9;); 3. . 4. . 5. . 6. function renderballon() 7. player1balloncontext.clearrect(0, 0, 500, 500); 8. player2balloncontext.clearrect(0, 0, 500, 500); 9.
65、; if (playingteamid = 1) 10. if (teams0.ballon != null) 11. drawball(player1balloncontext, teams0.ballon, new ve
66、ctor2d(30, 120), 20); 12. 13. else 14. if (teams1.ballon != null) 15. drawba
67、ll(player2balloncontext, teams1.ballon, new vector2d(30, 120), 20); 16. player1balloncontext.clearrect(0, 0, 133, 70); 17. 18. 旋轉(zhuǎn)屋頂上的電風(fēng)扇在這個游戲中這把電風(fēng)扇純屬拿來玩玩有趣一把的。那為什么
68、這里要放一把電風(fēng)扇?是這樣的,這個游戲的名字叫html5斯諾克俱樂部,放一把電風(fēng)扇就有俱樂部的氣氛了,當(dāng)然,我也是為了說明如何實(shí)現(xiàn)css3的旋轉(zhuǎn)。實(shí)現(xiàn)這個非常簡單:首先我們需要一張png格式的電扇圖片。只是我們并沒有用電扇本身的圖片,我們用他的投影。通過顯示風(fēng)扇在球桌上的投影,讓我們覺得它在屋頂上旋轉(zhuǎn),這樣就達(dá)到了我們目的:1. #rooffan position:absolute; left: 600px; top: -100px; width: 500px; height: 500px;&
69、#160; 2. border: 2px solid transparent; background-image: url('/content/images/rooffan.png'); 3. background-size: 100%; opacity: 0.3; z-index: 2; 4. . 5. . 6.
70、 . 7. <div id="rooffan"> </div> 為了獲得更為逼真的氣氛,我用paint.net軟件將電扇圖片平滑化了,現(xiàn)在你再也看不到電扇的邊緣了。我覺得這是達(dá)到如此酷的效果最為簡單的辦法。除了用了這圖像處理的把戲,我們僅僅使用了一個帶背景圖的普通的div元素,這并沒有什么特別。既然我們已經(jīng)得到了電扇圖片,我們就要讓它開始旋轉(zhuǎn)了。這里我們使用css3的rotate屬性來實(shí)現(xiàn)這一切。球桿動畫球桿的動畫對于這個游戲也不是必需的,但是這的確為此添加了不少樂趣。當(dāng)你開始用鼠標(biāo)在球桌上移動時,你會注意到
71、球桿的確是跟著你的鼠標(biāo)在轉(zhuǎn)動。這就是說球桿會一直保持跟隨鼠標(biāo)的移動,就像你身臨其境一般真實(shí)。因?yàn)檫x手只能用他的眼睛來瞄準(zhǔn),所以這個效果也會對選手有所幫助。球桿是單獨(dú)一張png圖片,圖片本身不直接以img的形式展現(xiàn),也不以背景的形式展現(xiàn),相反,它是直接展現(xiàn)在一個專門的canvas上的。當(dāng)然我們也可以用div和css3來達(dá)到同樣的效果,但我覺得這樣能更好的說明如何在canvas上展現(xiàn)圖片。首先,canvas元素會占據(jù)幾乎整個頁面的寬度。請注意這個特別的canvas有一個很大的z-index值,這樣球桿就可以一直在每個球的上方而不會被球遮蓋。當(dāng)你在球桌上移動鼠標(biāo)時,目標(biāo)點(diǎn)會實(shí)時更新,這時候球桿圖片會
72、進(jìn)行2次轉(zhuǎn)換:首先,通過計(jì)算得到母球的位置,其次翻轉(zhuǎn)母球周圍的球桿,通過這2步我們就得到了鼠標(biāo)所在點(diǎn)和母球的中心點(diǎn)。1. #cue position:absolute; 2. . 3. . 4. . 5. if (drawingtopcanvas.getcontext) 6. var cuecontext = drawingtopcanvas.getcontext('2d');
73、0;7. 8. . 9. . 10. . 11. var cuecenter = 15, -4; 12. var cue = new image; 13. cue.src = '<%: url.content("./content/images/cue.png") %>' 14. 15. var shadowc
74、ue = new image; 16. shadowcue.src = '<%: url.content("./content/images/shadowcue.png") %>' 17. cuecontext.clearrect(0, 0, topcanvaswidth, topcanvasheight); 18. 19. if
75、;(isready) 20. cuecontext.save(); 21. cuecontext.translate(cueball.position.x + 351, cueball.position.y + 145); 22.
76、60; cuecontext.rotate(shadowrotationangle - math.pi / 2); 23. cuecontext.drawimage(shadowcue, cuecenter0 + cuedistance, cuecenter1); 24. cuecontext
77、.restore(); 25. cuecontext.save(); 26. cuecontext.translate(cueball.position.x + 351, cueball.position.y + 140); 27.
78、160;cuecontext.rotate(angle - math.pi / 2); 28. cuecontext.drawimage(cue, cuecenter0 + cuedistance, cuecenter1); 29. cuecontext.restore(); 30.
79、60; 為了讓球桿變得更真實(shí)我們?yōu)榍驐U添加了投影,并且我們故意讓球桿投影的旋轉(zhuǎn)角度和球桿的角度不一樣,我們這樣做是為了讓球桿有3d的效果。最終的效果實(shí)在是太酷了。推拉球桿這個球桿動畫模仿了真實(shí)人類的特征:你是否看到過斯諾克選手在瞄準(zhǔn)的時候會推拉球桿?我們通過html5改變母球和球桿的距離實(shí)現(xiàn)了這一效果。當(dāng)達(dá)到一個極點(diǎn)是球桿會被拉回來,然后到達(dá)另一個極點(diǎn)時又會被向前推。這樣周而復(fù)始,知道選手停止移動鼠標(biāo)。1. var cuedistance = 0; 2. var cuepulling =
80、 true; 3. . 4. . 5. . 6. function render() 7. . 8. .
81、60;9. . 10. 11. if (cuepulling) 12.
82、 if (lastmousex = mousex | 13. lastmousey = mousey) 14.
83、; cuedistance += 1; 15. 16. else 17. &
84、#160; cuepulling = false; 18. getmousexy(); 19.
85、60; 20. 21. else 22. 23.
86、60; cuedistance -= 1; 24. 25. 26.
87、60;if (cuedistance > 40) 27. cuedistance = 40; 28. cuepulling&
88、#160;= false; 29. 30. else if (cuedistance < 0) 31.
89、60; cuedistance = 0; 32. cuepulling = true; 33. 34.
90、 . 35. . 36. . 顯示目標(biāo)路徑當(dāng)選手移動鼠標(biāo)時,我們會在母球和當(dāng)前鼠標(biāo)點(diǎn)之間畫一條虛線。這對選手們長距離瞄準(zhǔn)相當(dāng)?shù)谋憷?。這條
91、目標(biāo)路徑只有在等待用戶擊球時才會顯示:1. if (!cueball.pocketindex) 2. context.strokestyle = '#888' 3. context.linewidth = 4; 4. context.linecap = 'round' 5.
92、60; context.beginpath(); 6. 7. /here we draw the line 8. context.dashedline(cueball.position.x, cueball.position.y, targetx, targety); 9. 10.
93、160;context.closepath(); 11. context.stroke(); 12. 需要注意的是在html5 canvas中并沒有內(nèi)置函數(shù)來畫虛線。幸運(yùn)的是有一個叫phrogz的家伙在stackoverflow網(wǎng)站上發(fā)布了一個關(guān)于這個畫虛線的帖子:1. /function kindly provided by phrogz at: 2. / 3. var cp = window.canvas
94、renderingcontext2d && canvasrenderingcontext2d.prototype; 4. if (cp && cp.lineto) 5. cp.dashedline = function (x, y, x2, y2, dasharray) 6. &
95、#160; if (!dasharray) dasharray = 10, 5; 7. var dashcount = dasharray.length; 8. this.moveto(x, y); 9.
96、60; var dx = (x2 - x), dy = (y2 - y); 10. var slope = dy / dx; 11. var distremaining =
97、0;math.sqrt(dx * dx + dy * dy); 12. var dashindex = 0, draw = true; 13. while (distremaining >= 0.1) 1
98、4. var dashlength = dasharraydashindex+ % dashcount; 15. if (dashlength > distremaining) dashlength
99、60;= distremaining; 16. var xstep = math.sqrt(dashlength * dashlength / (1 + slope * slope); 17. 18.
100、 var signal = (x2 > x ? 1 : -1); 19. 20. x += xstep * signal; 21.
101、0; y += slope * xstep * signal; 22. thisdraw ? 'lineto' : 'moveto'(x, y); 23.
102、160; distremaining -= dashlength; 24. draw = !draw; 25. 26. 27. 顯示跟蹤路徑當(dāng)選手擊打
103、母球后,母球會在球桌上留下一條跟蹤線,用來標(biāo)明其上一個點(diǎn)的位置。創(chuàng)建這個跟蹤路徑比前面提到的目標(biāo)路徑復(fù)雜一點(diǎn)。首先我必須去實(shí)例化一個queue對象,這個項(xiàng)目中的queue對象原型由stephen morley提供。1. var tracingqueue = new queue(); 一旦球開始運(yùn)動,我們就將母球的實(shí)時位置壓入這個queue中:1. if (renderstep % 2 = 0) 2. draw();
104、0;3. enqueueposition(new vector2d(cueball.position.x, cueball.position.y); 4. enqueueposition函數(shù)確保了我們只保存前20個點(diǎn)的位置,這也就是為什么我們只讓顯示最近的母球的運(yùn)動路徑的原因。1. function enqueueposition(position) 2. tracingqueue.enqueue(position); &
105、#160;3. var len = tracingqueue.getlength(); 4. 5. if (len > 20) 6. tracingqueue.dequeue(); 7. 8.
106、接下來,我們要遍歷queue中的數(shù)據(jù),從而來創(chuàng)建這條跟蹤路徑:1. /drawing the tracing line 2. var lastposx = cueball.position.x; 3. var lastposy = cueball.position.y; 4. 5. var arr = tracingqueue.getarray(); 6. 7. if
107、;(!cueball.pocketindex) 8. context.strokestyle = '#363' 9. context.linewidth = 8; 10. context.linecap = 'round' 11. 12. &
108、#160;context.beginpath(); 13. var i = arr.length; 14. while (-i > -1) 15. var posx = arri.x; 16.
109、; var posy = arri.y; 17. context.dashedline(lastposx, lastposy, posx, posy, 10,200,10,20); 18. lastposx = posx; 19.
110、160; lastposy = posy; 20. 21. 22. context.closepath(); 23. context.stroke(); 24. 繪制小球小球和他們的投影都是呈現(xiàn)在一個特殊的canvas上(在球桿canvas下方)。在呈現(xiàn)小球時,我們先要呈現(xiàn)其投
111、影,這樣做主要是為了模擬3d的環(huán)境。每一個小球必須有投影,我們對每個小球的投影位置都會有一點(diǎn)細(xì)微的不同,這些細(xì)微差別表明了小球是在不同方向被投射的,也說明了光源所在的位置。每個小球是由一個公共函數(shù)來畫的,函數(shù)有兩個參數(shù):1)canvas context;2)小球?qū)ο?。函?shù)先畫出一個完整的圓弧然后根據(jù)小球?qū)ο筇峁┑念伾珜⑦@個圓弧線性填充。每一個小球?qū)ο笥?中顏色:光亮色、中色和暗色,這些顏色就是用來創(chuàng)建線性漸變顏色的,3d效果也是這樣做出來的。1. function drawball(context, ball, newposition, newsize)
112、 2. var position = ball.position; 3. var size = ball.size; 4. 5. if (newposition != null) 6.
113、;position = newposition; 7. 8. if (newsize != null) 9. size = newsize; 10. 11. /main circle 12.
114、 context.beginpath(); 13. context.fillstyle = ball.color; 14. context.arc(position.x, position.y, size, 0, math.pi * 2, true); 15. 16. var gra
115、dient = context.createradialgradient( 17. position.x - size / 2, position.y - size / 2, 0, position.x, 18. position.y, siz
116、e ); 19. 20. /bright spot 21. gradient.addcolorstop(0, ball.color); 22. gradient.addcolorstop(1, ball.darkcolor); 23. context.fillstyle =
117、;gradient; 24. context.fill(); 25. context.closepath(); 26. 27. context.beginpath(); 28. context.arc(position.x, position.y, size * 0.85, (mat
118、h.pi / 180) * 270, 29. (math.pi / 180) * 200, true); 30. context.lineto(ball.x, ball.y); 31. var gradient = context.createradialgradient( &
119、#160;32. position.x - size * .5, position.y - size * .5, 33. 0, position.x, position.y, size); 34. 35.
120、0; gradient.addcolorstop(0, ball.lightcolor); 36. gradient.addcolorstop(0.5, 'transparent'); 37. context.fillstyle = gradient; 38. context.fill(); 39. 40. 41. function drawballshadow(context, ball) 42. /main circle 43. context.beginpath(); 44.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度商業(yè)論壇活動搭建安全評估與保障合同
- 二零二五年度商業(yè)廣告位租賃合同解除申請書
- 二零二五年度鄭州市勞動合同管理實(shí)施細(xì)則
- 二零二五年度油漆涂料行業(yè)技術(shù)交流會合同
- 2025年度銷售員產(chǎn)品知識培訓(xùn)與銷售技巧提升合同
- 二零二五版黨政機(jī)關(guān)會議設(shè)備租賃及維護(hù)保養(yǎng)合同
- 2025年度父母子女間贈與遺產(chǎn)管理及執(zhí)行合同
- 2025年度農(nóng)業(yè)農(nóng)膜產(chǎn)品進(jìn)出口貿(mào)易合同4篇
- 二零二五年度診所掛證負(fù)責(zé)人免責(zé)及醫(yī)療責(zé)任分擔(dān)合同
- 基于云計(jì)算的2025年度企業(yè)信息化管理系統(tǒng)合同6篇
- 高二物理競賽霍爾效應(yīng) 課件
- 金融數(shù)學(xué)-(南京大學(xué))
- 基于核心素養(yǎng)下的英語寫作能力的培養(yǎng)策略
- 現(xiàn)場安全文明施工考核評分表
- 亞什蘭版膠衣操作指南
- 四年級上冊數(shù)學(xué)教案 6.1口算除法 人教版
- DB32-T 3129-2016適合機(jī)械化作業(yè)的單體鋼架塑料大棚 技術(shù)規(guī)范-(高清現(xiàn)行)
- 6.農(nóng)業(yè)產(chǎn)值與增加值核算統(tǒng)計(jì)報(bào)表制度(2020年)
- 人工挖孔樁施工監(jiān)測監(jiān)控措施
- 供應(yīng)商物料質(zhì)量問題賠償協(xié)議(終端)
- 物理人教版(2019)必修第二冊5.2運(yùn)動的合成與分解(共19張ppt)
評論
0/150
提交評論