国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

使用JavaScript和Canvas開發游戲之使用Canvas

開發 前端
這篇文章將帶領大家學習使用JavaScript和Canvas元素操作圖像了幾種不同的方式,這些方式在Canvas元素出現之前是不可能的事兒。

3、通過Canvas元素實現高級圖像操作

http://www.brighthub.com/internet/web-development/articles/39509.aspx

這篇文章將帶領大家學習使用JavaScript和Canvas元素操作圖像了幾種不同的方式,這些方式在Canvas元素出現之前是不可能的事兒。

上一篇文章演示了如何利用Canvas實現一個基本的圖像動畫。那個例子很簡單,同樣的效果通過修改IMG或DIV等標準HTML元素的一些屬性,照樣也可以輕易實現。下面我們就來演示一下畫布元素的高級應用,展示一下它的真正威力。

首先,還是準備一個HTML頁面。

  1.  
  2.  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">  
  3.  <html lang="en">  
  4.     <head>  
  5.        <title>JavaScript Platformer 2</title>  
  6.        <script type="text/javascript" src="jsplatformer2.js"></script>  
  7.        <style type="text/css">  
  8.           body { font-family: Arial,Helvetica,sans-serif;}  
  9.        </style>  
  10.     </head>  
  11.    <body>  
  12.       <p>  
  13.          <a href="http://www.brighthub.com/internet/web-development/articles/38364.aspx">  
  14.             Game Development with Javascript and the canvas element  
  15.          </a>  
  16.       </p>  
  17.       <canvas id="canvas" width="600" height="400">  
  18.          <p>Your browser does not support the canvas element.</p>  
  19.       </canvas>  
  20.       <br />  
  21.       <button onclick="currentFunction=alpha;">Change Alpha</button>  
  22.       <button onclick="currentFunction=shear;">Shear</button>  
  23.       <button onclick="currentFunction=scale;">Scale</button>  
  24.       <button onclick="currentFunction=rotate;">Rotate</button>  
  25.    </body>  
  26. </html> 

與上個一例子的HTML頁面相比,唯一的區別就是添加了一些按鈕。單擊這些按鈕,就會設置currentFunction變量(稍后介紹)的值,用以改變在渲染循環中運行的函數。

以下是 jsplatformer2.js 的代碼。

  1.  
  2. // 每秒多少幀  
  3. const FPS = 30;  
  4. const SECONDSBETWEENFRAMES = 1 / FPS;  
  5. const HALFIMAGEDIMENSION = 75;  
  6. const HALFCANVASWIDTH = 300;  
  7. const HALFCANVASHEIGHT = 200;  
  8. var image = new Image();  
  9. image.src = "jsplatformer2-smiley.jpg"//還是第一個例子中的圖像  
  10. var canvas = null;  
  11. var context2D = null;  
  12. var currentFunction = null;  
  13. var currentTime = 0;  
  14. var sineWave = 0;  
  15.  
  16. window.onload = init;  
  17.  
  18. function init()  
  19. {  
  20.    canvas = document.getElementById('canvas');  
  21.    context2D = canvas.getContext('2d');  
  22.    setInterval(draw, SECONDSBETWEENFRAMES * 1000);  
  23.    currentFunction = scale;  
  24. }  
  25.  
  26. function draw()  
  27. {  
  28.     currentTime += SECONDSBETWEENFRAMES;  
  29.     sineWave = (Math.sin(currentTime) + 1) / 2;  
  30.  
  31.     context2D.clearRect(0, 0, canvas.width, canvas.height);  
  32.  
  33.     context2D.save();  
  34.  
  35.     context2D.translate(HALFCANVASWIDTH - HALFIMAGEDIMENSION, HALFCANVASHEIGHT - HALFIMAGEDIMENSION);  
  36.  
  37.     currentFunction();  
  38.  
  39.     context2D.drawImage(image, 0, 0);  
  40.  
  41.     context2D.restore();  
  42. }  
  43.  
  44. function alpha()  
  45. {  
  46.     context2D.globalAlpha = sineWave;  
  47. }  
  48.  
  49. function shear()  
  50. {  
  51.     context2D.transform(1, 0, (sineWave - 0.5), 1, 0, 0);  
  52. }  
  53.  
  54. function scale()  
  55. {  
  56.     context2D.translate(HALFIMAGEDIMENSION * (1 - sineWave), HALFIMAGEDIMENSION * (1 - sineWave));  
  57.     context2D.scale(sineWave, sineWave);  
  58. }  
  59.  
  60. function rotate()  
  61. {  
  62.     context2D.translate(HALFIMAGEDIMENSION, HALFIMAGEDIMENSION);  
  63.     context2D.rotate(sineWave * Math.PI * 2);  
  64.     context2D.translate(-HALFIMAGEDIMENSION, -HALFIMAGEDIMENSION);  

跟前面一樣,這個JavaScript文件先定義了一些全局變量。

◆ FPS:每秒多少幀

◆ SECONDSBETWEENFRAMES:兩幀之間間隔的秒數(FPS的倒數)

◆ HALFIMAGEDIMENSION:要繪制圖像的寬度/高度的一半,用于把圖像定位到畫布的中心點

◆ HALFCANVASWIDTH:畫布寬度的一半,用于配合HALFIMAGEDIMENSION使用,以便在畫布上居中圖像

◆ HALFCANVASHEIGHT:畫布高度的一半,用于配合HALFIMAGEDIMENSION使用,以便在畫布上居中圖像

◆ currentFunction:渲染循環(參見上一篇文章)中運行的函數

◆ currentTime:應用已經運行了多少秒

◆ sineWave:0到1之間的一個值,用于控制圖像的運動

◆ image:要在畫布上繪制的圖像

◆ canvas:畫布元素的引用

◆ context2D:畫布元素的2D上下文的引用

然后,跟前面一樣,要設置在window的onload事件發生時立即調用init函數(關于init函數的介紹,請參見上一篇文章)。

draw函數

下面來看一看draw函數:

  1.  
  2. function draw()  
  3. {  
  4.     currentTime += SECONDSBETWEENFRAMES;  
  5.     sineWave = (Math.sin(currentTime) + 1) / 2;  
  6.  
  7.     context2D.clearRect(0, 0, canvas.width, canvas.height);  
  8.  
  9.     context2D.save();  
  10.     context2D.translate(HALFCANVASWIDTH - HALFIMAGEDIMENSION, HALFCANVASHEIGHT - HALFIMAGEDIMENSION);  
  11.     currentFunction();  
  12.     context2D.drawImage(image, 0, 0);  
  13.     context2D.restore();  
  14. }  

這個例子要演示4種效果:修改alpha值(透明度),以及縮放、旋轉和切變圖像。為了展示這些效果,需要基于某一范圍內的值來應用變化。變量sineWave就用來定義這個范圍值的基準。

標準的正弦函數能夠在-1到1之間產生非常完美的波形圖。首先,我們通過遞增currentTime變量來反映動畫已經運行了多長時間,然后再利用這個值在正弦曲線上找到一個點。給正弦函數返回的值(從-1到1)先加1再除以2,就可以把它們轉換成0到1這個范圍內的值。

  1. currentTime += SECONDSBETWEENFRAMES;  
  2. sineWave = (Math.sin(currentTime) + 1) / 2; 

然后,調用clearRect方法清空畫布,以便為后面的繪圖準備一個干凈的版面。

  1. context2D.clearRect(0, 0, canvas.width, canvas.height); 

應用到畫布上面的效果是可以累積的,因而就可以利用幾個簡單的函數來“組合”出效果來。例如,在向屏幕上繪制之前,可能會有一艘飛船需要旋轉、變換和縮放。因為所有效果都對畫布起作用,所以這些效果會應用到將被繪制在屏幕上的所有對象,而不僅僅是某一幅圖像或某一個形狀(比如一艘飛船)。

其中,save和restore函數為應用這些累積的效果提供了一種簡單的機制,可以將應用了這些效果的圖像或圖形繪制到畫布上,然后“撤銷”這些改變。后臺的操作是什么呢?save函數把當前的繪制狀態推進棧里,而restore函數則把最后一個狀態彈出棧。還拿前面提到的飛船為例,需要執行下列操作:

◆ 調用save函數(保存當前的繪制狀態)

◆ 旋轉、變換和縮放上下文

◆ 繪制飛船

調用restore函數,移除自上一次調用save方法以來所添加的任何效果,也就是撤銷之前的變化

在這里,我們就是要組合起來使用這兩個方法。首先,在把任何效果應用到畫布之前,先保存繪制狀態。

  1. context2D.save(); 

保存了繪制狀態之后,就該應用目標效果了。為此,首先調用translate函數,從而將隨后要繪制的圖像在畫布上居中。

  1. context2D.translate(HALFCANVASWIDTH - HALFIMAGEDIMENSION, HALFCANVASHEIGHT - HALFIMAGEDIMENSION); 

接下來,調用由變量currentFunction引用的函數。正是這些被引用的函數,是讓圖像發生alpha(透明度)變化以及縮放、旋轉和切變的關鍵。這些函數我們稍后再介紹。

  1. currentFunction(); 

為圖像應用完效果之后,就可以把它繪制到畫布上面了。所以,接下來就是調用drawImage來繪圖。

  1. context2D.drawImage(image, 0, 0);  

最后,再調用restore函數,把自調用save函數以來應用的所有效果從畫布上移除。

  1. context2D.restore(); 

alpha函數

  1. function alpha()  
  2. {  
  3.     context2D.globalAlpha = sineWave;  

通過修改上下文對象的globalAlpha屬性,所有后續繪制操作的透明度都會被修改。將globalAlpha設置為0,意味著被繪制的任何對象都將完全透明,而將這個屬性設置為1,則意味著任何繪制操作都會保持原有的透明度級別。在此,我們通過修改這個globalAlpha屬性,可以實現笑臉的淡入和淡出效果。

shear函數

  1. function shear()  
  2. {  
  3.     context2D.transform(1, 0, (sineWave - 0.5), 1, 0, 0);  
  4. }  

切變操作是通過transform函數向畫布應用一個矩陣來實現的。變換矩陣本身就是一個值得研究的主題,但對我們來說,如果不想理解背后的數學原理,可以在網上找到很多標準的2D變換矩陣(http://en.wikipedia.org/wiki/Transformation_matrix#Examples_in_2D_graphics),直接使用transform函數來應用它們即可。所謂切變,其實就是把圖像的頂部或底部推到一邊。

scale函數

  1. function scale()  
  2.  {  
  3.      context2D.translate(HALFIMAGEDIMENSION * (1 - sineWave), HALFIMAGEDIMENSION * (1 - sineWave));  
  4. 56  
  5.     context2D.scale(sineWave, sineWave);  
  6.  }  

顧名思義,scale(縮放)函數修改的是圖像的大小。但在此之前,我們還調用了一次transalte函數。這是為了讓縮放后的圖像在畫布上居中。如果你把這行代碼注釋掉,就會發現圖像會從左上角向右下角膨脹。調用translate函數就是為抵消其圓心的位移,讓圖像始終居中。

rotate函數

  1. function rotate()  
  2. {  
  3.     context2D.translate(HALFIMAGEDIMENSION, HALFIMAGEDIMENSION);  
  4.     context2D.rotate(sineWave * Math.PI * 2);  
  5.     context2D.translate(-HALFIMAGEDIMENSION, -HALFIMAGEDIMENSION);  
  6. }  

與scale函數類似,rotate(旋轉)函數的作用也正如其名:旋轉圖像。與scale函數同樣類似的是,這里也額外調用了translate函數以確保圖像圍繞中心點而不是左上角旋轉。建議大家把對translate函數的調用注釋掉,自己看一看結果有什么不同。

剛剛我們看到了使用畫布元素實現的4種也還算簡單的效果,這些效果使用標準的HTML元素幾乎是不可能做到的。其中,有的效果可以使用scale和rotate等內置函數來實現,而使用transform函數則可以完成大量的圖像操作(切變只是其中之一)。

看看Demo吧。http://webdemos.sourceforge.net/jsplatformer2/jsplatformer2.html

原文作者:Matthew Casperson 原文鏈接: Game Development with JavaScript and the Canvas element

譯文作者:李松峰 譯文鏈接:http://www.cn-cuckoo.com/2011/08/10/game-development-with-javascript-and-the-canvas-element-2554.html

【編輯推薦】

  1. 使用JavaScript和Canvas開發游戲之認識Canvas
  2. JavaScript入門之語言基礎
  3. JavaScript入門之事件、cookie、定時等
  4. 給用HTML 5開發移動應用的5個警告
  5. 云端JavaScript漫游指南(視頻)
責任編輯:陳貽新 來源: 李松峰的博客
相關推薦

2011-08-11 09:16:50

JavaScript

2012-01-04 13:55:23

Canvas

2012-05-09 09:41:58

HTML5

2013-05-20 17:13:17

Android游戲開發CanvasPaint

2022-03-09 09:00:41

SwiftUI視圖生成器Swift

2012-02-24 15:28:36

ibmdw

2021-01-06 10:05:09

鴻蒙HarmonyOSCanvas

2022-05-27 11:22:40

Canvas超級瑪麗游戲

2010-09-30 13:11:59

J2MECanvas

2021-01-04 11:10:14

鴻蒙HarmonyOSCanvas

2022-02-23 15:17:04

鴻蒙OpenHarmonJacascript

2012-05-09 12:18:14

HTML5Canvas

2009-12-29 10:06:09

WPF Canvas

2021-09-01 22:59:31

Canvas標簽語法

2022-06-29 14:06:54

canvas鴻蒙

2012-06-04 10:16:18

HTML5

2023-02-28 11:43:35

2011-05-16 17:19:29

游戲開發iPhone

2025-08-11 08:55:30

HTML前端字體異常

2014-08-04 17:46:15

NavBarTarBar
點贊
收藏

51CTO技術棧公眾號

福利一区视频| 久久天天做天天爱综合色| 亚洲国产精品欧美一二99| 欧美高清不卡在线| 白白操在线视频| 国产成人a视频高清在线观看| 国产精品一区二区在线观看不卡| 最新国产の精品合集bt伙计| 亚洲欧美一区二区精品久久久| 欧美日本韩国国产| 欧美24videosex性欧美| 国产精品久久久亚洲一区| 欧美三级韩国三级日本三斤| 天天久久人人| 久久在线观看| 亚洲欧美日韩中文字幕一区二区三区| 国产成人亚洲综合91精品| 亚洲欧美日本免费| 久久婷婷av| 亚洲二区视频在线| 韩日精品中文字幕| 国产视频三区| 第四色成人网| 亚洲一区二区三区四区不卡 | 色呦呦网站入口| 色香欲www7777综合网| 中文字幕精品一区| 91综合免费在线| 污污影院在线观看| 91社区在线播放| 国产日韩精品一区二区| 麻豆传媒在线免费| 99久久久精品| 91亚洲国产成人久久精品网站| 精品视频一区二区三区四区五区| 亚洲高清资源| 国产精品国产自产拍在线| 久久精品一区二区三区四区| 欧美电影免费提供在线观看| 久久久久久久久国产| 中文字幕在线视频免费观看| 成人av手机在线观看| 欧美 国产 精品| 丰满岳乱妇一区二区三区| 欧美日韩一区二区三区在线观看免| 不卡在线一区二区| 国产精品网站视频| 国产啊啊啊视频在线观看| 国产精品综合视频| 97国产在线视频| 4kfree性满足欧美hd18| 亚洲国产精品成人| 欧美α欧美αv大片| 成人亚洲视频在线观看| 久久激情久久| 成人免费淫片视频软件| 亚洲瘦老头同性70tv| www.欧美精品| 亚洲精品中文字幕乱码| 中文字幕中文字幕在线中心一区| 亚洲天堂av一区| 日本国产在线| 精品日本高清在线播放| 亚洲jjzzjjzz在线观看| 久久久国产精华| 亚洲一区二三| 一区二区三区网站| 91av免费看| 国产亚洲一区| 亚洲天堂av在线免费| www日韩tube| 亚洲成人精品av| sm国产在线调教视频| 亚洲欧美日韩一区| 国产wwwxx| 国产精品久久精品日日| 久久精品中文字幕一区二区三区 | 国产高清一区在线观看| 一区二区亚洲精品国产| 欧美男gay| 激情图片qvod| 92国产精品观看| 欧美午夜性生活| 91在线精品一区二区三区| 国产精品久久国产三级国电话系列| 中文不卡在线| 国产综合色香蕉精品| 久久免费影院| 国产视频亚洲视频| 亚洲动漫精品| 国产91视频一区| 激情小说亚洲一区| 久久天天躁狠狠躁夜夜躁| 91精品日本| 亚洲狠狠爱一区二区三区| 在线观看av的网站| 色婷婷综合久色| 黄色软件在线观看| 午夜激情一区二区三区| 午夜肉伦伦影院| 国产亚洲精品免费| 成人黄色一区二区| 亚洲综合色丁香婷婷六月图片| 黄色激情在线视频| 日韩国产精品大片| 日韩久久在线| 蓝色福利精品导航| 亚洲资源在线网| 秋霞影院一区二区| 日本一区二区三区视频在线观看 | 欧美性在线观看| 欧美日韩一区二区国产| 亚洲最大成人在线观看| 伊人一区二区三区久久精品| 电影中文字幕一区二区| 国产亚洲一区精品| 先锋影音网一区二区| 精品国产免费一区二区三区香蕉| 午夜视频在线观看网站| 亚洲大胆美女视频| 成人三级视频| 亚洲精品国产一区| 欧美激情中文不卡| heyzo中文字幕在线| 91精品久久久久久久久久入口| 九色porny在线| 欧美视频在线观看一区二区| 欧美人体一区二区三区| 38少妇精品导航| 美女久久网站| 2021狠狠干| 亚洲人亚洲人成电影网站色| 开心快乐六月丁香婷婷| 日韩精品久久久久| 欧美午夜视频| 男同互操gay射视频在线看| 中文字幕av资源一区| 国产美女高潮在线| 亚洲精品久久在线| 999在线精品| 中文字幕欧美日韩一区二区| 91黄色在线观看| 精品一区二区三区亚洲| 中文字幕99| 久久综合一区二区| 男人免费av| 精品sm在线观看| 国产欧美一区| 亚洲黄色一区二区三区| 久久综合色鬼综合色| 国产性一级片| 日韩一区二区在线看| 免费观看在线综合| 嫩草在线视频| 国产91热爆ts人妖在线| 99精品视频中文字幕| 大片免费在线观看| 国产精品福利片| 亚洲福利久久| 特级全黄一级毛片| 亚洲福利精品在线| 久久精品亚洲成在人线av网址| 国产91av在线| 伊人情人综合网| 日韩和欧美的一区二区| 麻豆国产一区二区| 青青在线免费视频| 亚洲精品va在线观看| 亚洲色图图片网| 制服丝袜亚洲播放| 久久精品女人天堂av免费观看| 亚洲精品中文字| 免费欧美激情| 国产三级精品网站| 亚洲网站视频| 尤物av无码色av无码| 日本国产一区二区| 超碰aⅴ人人做人人爽欧美| 2020国产精品视频| 亚洲人metart人体| 一本色道久久亚洲综合精品蜜桃| 欧美亚洲一区二区在线观看| 亚洲成人a级片| 色播久久人人爽人人爽人人片视av| 日韩久久精品网| 91免费版在线观看| 在线观看亚洲视频| 日av在线不卡| 电影av一区| 国产精品视频免费一区二区三区| 91网站在线观看视频| 午夜精品成人av| 欧美一级日本a级v片| 亚洲成a人v欧美综合天堂下载| 大地资源网3页在线观看| 91精品综合视频| 国产精品人人做人人爽人人添| 久久久亚洲欧洲日产| 天堂在线亚洲| 98精品国产自产在线观看|