久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      HTML5邊玩邊學(xué)(七)-動(dòng)畫初步之飛舞的精靈

      一、為什么選擇 HTML5

      HTML5 邊玩邊學(xué)算上這篇已經(jīng)是第七篇了,在這篇開始之前,我想先說明一下為什么叫“HTML5” 邊玩邊學(xué),因?yàn)橛腥藢?HTML5 提出質(zhì)疑,畢竟他是一個(gè)新生事物。我承認(rèn)我用 HTML5 來吸引眼球了,如果看過邊玩邊學(xué)系列的每一篇,你會(huì)發(fā)現(xiàn)前六篇文章內(nèi)容的和 HTML5 關(guān)系不是太大,真正的內(nèi)容其實(shí)是 2D 圖形圖像編程的學(xué)習(xí)筆記。

      如果我們想學(xué)習(xí) 2D 編程,其實(shí)可供選擇的編程環(huán)境數(shù)不勝數(shù):MFC、Delphi都有圖形圖像處理功能(即GDI),Java、.Net 更不用說了,如果你支持開源,GTK、QT、wxPython 也是不錯(cuò)的選擇,F(xiàn)lash 更是拿手好戲,甚至幾個(gè)流行的只能手機(jī)平臺(tái)應(yīng)該也有 2D 模塊。

      如果你選擇了上面任何一款編程環(huán)境學(xué)習(xí) 2D 編程,你會(huì)發(fā)現(xiàn)他們的內(nèi)容基本上是一樣的:線型、填充、顏色、漸變、圖像、組合、裁剪區(qū)、變形等等,甚至連函數(shù)名很多都是一摸一樣,畢竟他們的理論基礎(chǔ)都是圖形學(xué)。

      搞清楚我們真正想學(xué)習(xí)什么以后,其實(shí)編程環(huán)境只是個(gè)工具而已,我們根據(jù)個(gè)人喜好,選擇最方便的一款來使用。其實(shí)我更青睞 Python 編程環(huán)境,只是如果我用了Python,估計(jì)跟我交流的人就不會(huì)太多了,大家機(jī)器里安裝 Python 運(yùn)行時(shí)的估計(jì)不會(huì)太多。

      那么為什么選擇 HTML5 而不是其他呢?首先,Javascript 語法簡潔靈活,相應(yīng)的函數(shù)庫小巧但是夠用, HTML5 Canvas 標(biāo)簽的 2D 表現(xiàn)能力也達(dá)到了要求,Chrome 瀏覽器的運(yùn)行速度讓人滿意。除此之外,我們不用安裝笨重的集成開發(fā)環(huán)境,不需要安裝運(yùn)行時(shí),我們只需要一個(gè)加強(qiáng)功能的記事本、一個(gè)瀏覽器就可以去實(shí)踐我們的想法,并且直接將效果呈現(xiàn)在網(wǎng)絡(luò)上。我們只是發(fā)表文章同其他人分享自己的想法而已,至于平臺(tái)、框架、語言特性,這些無關(guān)的東西當(dāng)然牽扯的越少越好,這就是我選擇 HTML5 的原因。

      所以,請大家不要誤解了標(biāo)題的含義:這個(gè)系列并不是 HTML5 的學(xué)習(xí)筆記,而只是用 HTML5 來展現(xiàn)一些知識(shí)內(nèi)容而已,你更多關(guān)注的應(yīng)該是知識(shí)和內(nèi)容本身,你可以在任何其他一款編程環(huán)境下再現(xiàn)他們。

      二、動(dòng)畫初步

      動(dòng)畫就是一系列連續(xù)的畫面按順序呈現(xiàn)出來而已,只是,在電影電視中,這些畫面實(shí)現(xiàn)已經(jīng)被準(zhǔn)備好了,而在電腦程序中,我們見到每一瞬間的畫面都是即時(shí)繪制的,大體流程可以表述如下:

      a、輕微改變圖形的數(shù)據(jù)(坐標(biāo)、形狀、顏色等等)

      b、清空畫布

      c、繪制圖形

      d、回到步驟 a

      當(dāng)然,這里只是給出了一個(gè)最簡單的流程框架,要實(shí)現(xiàn)復(fù)雜的動(dòng)畫可能還要考慮更多的問題,比如局部清除、碰撞檢測之類的。

      另外,繪制過程中有兩個(gè)速度需要控制:

      第一個(gè)是繪制速度,即每秒鐘繪制多少次(幀),或者也可以這樣說,每一幀暫停多少時(shí)間。如果你的動(dòng)畫每一幀都是一個(gè)樣子,只是位置不同,這個(gè)速度影響不大。

      第二個(gè)圖形移動(dòng)的速度。

      所以,千萬不要把這兩個(gè)速度搞混了,繪制的越快,只能代表動(dòng)畫更流暢,但并不代表你的圖像移動(dòng)的更快。

      使用 HTML5 繪制動(dòng)畫基本上就是上面這個(gè)流程,只是你還需要注意兩點(diǎn):

      1、為了方便繪制的圖形,我們經(jīng)常會(huì)改變上下文對象的的狀態(tài),所以在繪制圖形前后,千萬別忘了保存和恢復(fù)狀態(tài),如果你不太了解狀態(tài)是什么,請看前面的一篇文章《HTML5邊玩邊學(xué)(6):汽車人,變形……》

      2、我們需要將整個(gè)繪制動(dòng)作放到定時(shí)器里面,否則整個(gè)瀏覽器將失去響應(yīng)。Javascript 有兩個(gè)定時(shí)器方法,分別是:

      setInterval(code,millisec) 和 setTimeout(code,millisec)

      這兩個(gè)方法我就介紹了,可以去 Google 相關(guān)的資料。

      下面我們給出一個(gè)上下移動(dòng)方塊的小動(dòng)畫,當(dāng)遇到頂部或者底部時(shí),會(huì)改變方向。代碼如下:

      基本動(dòng)畫        Code highlighting produced by Actipro CodeHighlighter (freeware)  http://www.CodeHighlighter.com/    --><canvas id="canvas1" width="250" height="300" style="background-color:black">        你的瀏覽器不支持 Canvas 標(biāo)簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器    </canvas><br/>    幀數(shù):<input  id="txt1" type="text" value="25"/><br/>    每次移動(dòng)距離:<input type="text" id="txt2" value="10"/><br/>    <input type="button" value="開始" onclick="move_box()"/>    <input type="button" value="暫停" onclick="stop()"/>            <script type="text/javascript">        //定時(shí)器        var interval=null;                //停止動(dòng)畫        function stop(){            clearInterval(interval);        }            //===================================================================        //基本動(dòng)畫        //====================================================================        function move_box(){            //停止動(dòng)畫            stop();            //移動(dòng)速度            var delta=parseInt(document.getElementById('txt1').value);            //每秒繪制多少次            var fps=parseInt(document.getElementById('txt2').value);                //畫布對象            var canvas=document.getElementById("canvas1")            //獲取上下文對象            var ctx = canvas.getContext("2d");            //設(shè)置顏色            ctx.fillStyle="red";                        //方塊的初始位置            var x=100;var y=50;            //方塊的長度和寬度            var w=30;var h=30;                        //開始動(dòng)畫            interval = setInterval(function(){                //改變 y 坐標(biāo)                y=y+delta;                //上邊緣檢測                if(y<0){                    y=0;                    delta=-delta;                }                //下邊緣檢測                if((y+h)>canvas.getAttribute("height")){                    y=canvas.getAttribute("height")-h;                    delta=-delta;                }                 //清空畫布                ctx.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height"));                //保存狀態(tài)                ctx.save();                //移動(dòng)坐標(biāo)                ctx.translate(x,y);                //重新繪制                ctx.fillRect(0,0,w,h);                //恢復(fù)狀態(tài)                ctx.restore();            },1000/fps);        }        </script>

      三、重新組織代碼

      上面的代碼能正常工作了,但是存在很多問題,主要有以下幾點(diǎn):

      1、計(jì)算方塊位置的代碼和繪制方塊的代碼混雜一起,即邏輯和視圖混雜,基本上不能擴(kuò)展了

      2、代碼沒辦法復(fù)用,比如我們需要繪制多個(gè)不同的方塊對象:起始位置、大小、顏色、速度各不相同,每一種情況都需要重寫一遍。

      下面我們重新組織一下代碼,把方塊的共同屬性抽象出來,組成一個(gè) Box 類,由這個(gè) Box 類負(fù)責(zé)計(jì)算每一幀方塊的位置,這樣就可以解決上面兩個(gè)問題了。代碼如下:

      重新組織代碼        Code highlighting produced by Actipro CodeHighlighter (freeware)  http://www.CodeHighlighter.com/    --><canvas id="canvas2" width="250" height="300" style="background-color:black">        你的瀏覽器不支持 Canvas 標(biāo)簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器    </canvas><br/>    <input type="button" value="開始" onclick="move_box2()"/>    <input type="button" value="暫停" onclick="stop()"/>        <script type="text/javascript">        //定時(shí)器        var interval=null;                //停止動(dòng)畫        function stop(){            clearInterval(interval);        }            //===================================================================        //重新組織代碼        //====================================================================        //方塊的構(gòu)造函數(shù)        function Box(color,x,y,w,h,delta){            this.color=color;            this.x=x;            this.y=y;            this.w=w;            this.h=h;            this.delta=delta;            //三十幀            this.fps=30;            //每一幀的延遲時(shí)間            this.delay=1000/this.fps;            //上一次重繪的時(shí)間            this.last_update=0;        }                //方塊更新        Box.prototype.update=function(canvas){            //獲取當(dāng)前時(shí)間            var now=(new Date()).getTime();            //如果達(dá)到了延遲時(shí)間,則更新數(shù)據(jù)            if((now-this.last_update)>this.delay){                            //改變 y 坐標(biāo)                this.y=this.y+this.delta;                //上邊緣檢測                if(this.y<0){                    this.y=0;                    this.delta=-this.delta;                }                //下邊緣檢測                if((this.y+this.h)>canvas.getAttribute("height")){                    this.y=canvas.getAttribute("height")-this.h;                    this.delta=-this.delta;                }                 //記下最新一次繪制時(shí)間                this.last_update=now;            }                    }                        function move_box2(){            //停止動(dòng)畫            stop();            //畫布對象            var canvas=document.getElementById("canvas2")            //獲取上下文對象            var ctx = canvas.getContext("2d");            //清空畫布            ctx.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height"));                        //創(chuàng)建多個(gè)方塊對象            var boxes=[];            boxes[0]= new Box("red",3,2,10,35,2,10);//速度10            boxes[1]= new Box("blue",60,28,44,15,5);//速度20            boxes[2]= new Box("green",130,200,23,18,10);//速度30            boxes[3]= new Box("pink",200,150,35,10,20);//速度40                        //開始動(dòng)畫繪制            interval = setInterval(function(){                for(var i=0;i<boxes.length;i++){                    //取出一個(gè)方塊                    var box=boxes[i];                    //清空這個(gè)方塊                    ctx.clearRect(box.x,box.y,box.w,box.h);                    //更新數(shù)據(jù)                    box.update(canvas);                    //保存狀態(tài)                    ctx.save();                    //設(shè)置顏色                    ctx.fillStyle=box.color;                    //移動(dòng)坐標(biāo)                    ctx.translate(box.x,box.y);                    //重新繪制                    ctx.fillRect(0,0,box.w,box.h);                    //恢復(fù)狀態(tài)                    ctx.restore();                }            },1);//盡可能快的循環(huán)        }        </script>

      四、精靈登場

      據(jù)說在很久遠(yuǎn)的年代,有多遠(yuǎn)我也不知道,可能是任天堂紅白機(jī)是哪個(gè)年代吧,由于游戲機(jī)處理器的計(jì)算速度有限,所以專門設(shè)置了一個(gè)硬件用來處理角色圖像的相關(guān)數(shù)據(jù),這些數(shù)據(jù)可能包括:

      1、計(jì)算當(dāng)前的角色應(yīng)該繪制哪一幀。上面我們的方塊雖然在移動(dòng),但是始終都是一個(gè)樣子;可是在游戲中,一個(gè)跑動(dòng)的精靈,跑動(dòng)動(dòng)作是由很多幅連續(xù)的圖像組成,我們需要知道現(xiàn)在應(yīng)該繪制其中的哪一幅圖像;

      2、表現(xiàn)精靈動(dòng)作的很多幅連續(xù)的圖像通常是集中放置在一個(gè)大圖中,我們需要計(jì)算當(dāng)前繪制的那一幅,在大圖中處于什么位置,并把它截取出來

      上面說到這個(gè)硬件,曾經(jīng)被叫做 Sprite 精靈?,F(xiàn)如今,我們的處理器已經(jīng)十分強(qiáng)大,不再需要 Sprite 這樣的輔助硬件,但是這樣的功能仍然需要,只不過用軟件來實(shí)現(xiàn)罷了,所以,我們依然用 Sprite 來稱呼游戲中的一個(gè)角色。

      這里有一幅圖像,他描繪了一個(gè)小精靈的飛行動(dòng)作

      HTML5邊玩邊學(xué)(七)-動(dòng)畫初步之飛舞的精靈

      下面我們將實(shí)現(xiàn)一個(gè) Sprite 類,讓他在瀏覽器里面飛起來。

      精靈登場        Code highlighting produced by Actipro CodeHighlighter (freeware)  http://www.CodeHighlighter.com/    --><canvas id="canvas3" width="250" height="300" style="background-color:black">        你的瀏覽器不支持 &lt;canvas&gt;標(biāo)簽,請使用 Chrome 瀏覽器 或者 FireFox 瀏覽器    </canvas><br/>    幀數(shù):<input  id="txt4" type="text" value="10"/><br/>    速度:<input type="text" id="txt5" value="5"/><br/>    比例:<input type="text" id="txt6" value="2"/><br/>    <input type="button" value="開始" onclick="animate()"/>    <input type="button" value="暫停" onclick="stop()"/>        <script type="text/javascript">        //定時(shí)器        var interval=null;                //停止動(dòng)畫        function stop(){            clearInterval(interval);        }                //===================================================================        //精靈登場        //====================================================================        //每一幀在大圖中的位置        var frames=[];        frames[0]=[0,4,19,19];        frames[1]=[22,1,24,19];        frames[2]=[49,0,18,17];        frames[3]=[1,32,18,17];        frames[4]=[22,33,24,19];        frames[5]=[49,36,19,19];                //精靈類        function Sprite(dx,dy,delta,fps){            this.dx=dx;            this.dy=dy;            this.fps=fps;            this.delay=1000/fps;            this.last_update=0;            //移動(dòng)速度            this.delta=-delta;            //幀編號            this.index=0;            //方向            this.dir_left=true;        }                Sprite.prototype.update=function(canvas){            //獲取當(dāng)前時(shí)間            var now=(new Date()).getTime();            if((now-this.last_update)>this.delay){                if(this.dir_left){                    //方向朝左,只繪制0 1 2幀                    if(this.index>2)                        this.index=0;                }                else{                    //方向朝右,只繪制 3 4 5 幀                    if(this.index>5)                        this.index=3;                }                //取出當(dāng)前幀的坐標(biāo)                this.frame=frames[this.index];                                //當(dāng)前幀在大圖中的位置                this.sx=this.frame[0];                this.sy=this.frame[1];                this.sw=this.frame[2];                this.sh=this.frame[3];                                //當(dāng)前幀大小                this.dw=this.frame[2];                this.dh=this.frame[3];                                //改變 x 坐標(biāo)                this.dx=this.dx+this.delta;                //左邊緣檢測                if(this.dx<0){                    this.dx=0;                    //轉(zhuǎn)向                    this.delta=-this.delta;                    this.dir_left=false;                    this.index=3;                }                //右邊緣檢測                if((this.dx+this.dw)>canvas.getAttribute("width")){                    this.dx=canvas.getAttribute("width")-this.dw;                    //轉(zhuǎn)向                    this.delta=-this.delta;                    this.dir_left=true;                    this.index=0;                }                         this.dy=this.dy;//y 不移動(dòng)                                    this.index++;                this.last_update=now;            }        }                function animate(){            //停止動(dòng)畫            stop();            //移動(dòng)速度            var delta=parseInt(document.getElementById('txt4').value);            //每秒繪制多少次            var fps=parseInt(document.getElementById('txt5').value);            //比例            var scale=parseInt(document.getElementById('txt6').value);                        //畫布對象            var canvas=document.getElementById("canvas3")            //獲取上下文對象            var ctx = canvas.getContext("2d");            //清空畫布            ctx.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height"));                        var img=new Image();            img.src="http://images.cnblogs.com/cnblogs_com/myqiao/html5/sprite.gif";                var sprite=new Sprite(120,150,delta,fps);            interval = setInterval(function(){                //清空畫布                ctx.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height"));                //更新數(shù)據(jù)                sprite.update(canvas);                //保存狀態(tài)                ctx.save();                //移動(dòng)坐標(biāo)                ctx.translate(sprite.dx,sprite.dy);                ctx.scale(scale,scale);                ctx.drawImage(img,sprite.sx,sprite.sy,sprite.sw,sprite.sh,0,0,sprite.dw,sprite.dh);                //恢復(fù)狀態(tài)                ctx.restore();            },1);                    }            </script>

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號