flash as3控制坐標(biāo)旋轉(zhuǎn)_第1頁
flash as3控制坐標(biāo)旋轉(zhuǎn)_第2頁
flash as3控制坐標(biāo)旋轉(zhuǎn)_第3頁
flash as3控制坐標(biāo)旋轉(zhuǎn)_第4頁
flash as3控制坐標(biāo)旋轉(zhuǎn)_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、flash as3控制坐標(biāo)旋轉(zhuǎn) 2010-06-13 14:30第十章 坐標(biāo)旋轉(zhuǎn)及角度反彈本章介紹了一項(xiàng)特殊技術(shù),著名的坐標(biāo)旋轉(zhuǎn)。如同其名,它是物體指繞著某點(diǎn)旋轉(zhuǎn)其坐標(biāo),在制作一些非常有趣的效果時,坐標(biāo)旋轉(zhuǎn)是必不可少的。其中就包括在 Flash 界討論了很多年的問題:“如何在斜面上進(jìn)行反彈?”,本章我會給大家一一解答。另一個用坐標(biāo)旋轉(zhuǎn)完成的程序是兩物體之間的交互反彈效果。我們會在下一章討論動量守衡時進(jìn)行講解。而本章的坐標(biāo)旋轉(zhuǎn),我們之前也已經(jīng)接觸過了。如果大家想跳過這章的話,我勸您還是先坐下來,瀏覽一遍為好。簡單的坐標(biāo)旋轉(zhuǎn)雖然我們在第三章講三角學(xué)的時候介紹過計(jì)算的坐標(biāo)旋轉(zhuǎn)的方法,但還是先來做一下

2、回顧。假設(shè)知道一個中心點(diǎn),一個物體,一個半徑和一個角度。通過不斷地增加或減少角度,并運(yùn)用基本的三角學(xué)知識讓物體繞著中心點(diǎn)旋轉(zhuǎn)。我們可將變量設(shè)為 vr (旋轉(zhuǎn)速度)來控制角度的增加或減少。還有,不要忘記角度應(yīng)用弧度制來表示。代碼的結(jié)構(gòu)如下所示:vr = 0.1;angle = 0;radius = 100;centerX = 250;centerY = 200;/ 在 enterFrame 處理函數(shù)中:sprite.x = centerX + cos(angle) * radius;sprite.y = centerY + sin(angle) * radius;angle += vr;根據(jù)角度

3、與半徑使用簡單的三角函數(shù)設(shè)置物體的 x,y 屬性,并在每幀中改變角度。我們用 Flash 動畫演示一下。下面是第一個例子,文檔類 Rotate1.as:package import flash.display.Sprite;import flash.events.Event;public class Rotate1 extends Sprite private var ball:Ball;private var angle:Number = 0;private var radius:Number = 150;private var vr:Number = .05;public function

4、 Rotate1() init();private function init():void ball = new Ball();addChild(ball);addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):void ball.x = stage.stageWidth / 2 + Math.cos(angle) * radius;ball.y = stage.stageHeight / 2 + Math.sin(angle) * radius;angle +

5、= vr;這段代碼中沒有什么新的知識點(diǎn)。大家可以改變一下角度與半徑,試驗(yàn)運(yùn)行結(jié)果。但是如果我們只知道物體與中心點(diǎn)的位置又該怎么辦呢?用 x,y 坐標(biāo)計(jì)算出當(dāng)前的角度(angle)與半徑(radius)也并非難事。代碼如下:var dx:Number = ball.x - centerX;var dy:Number = ball.y - centerY;var angle:Number = Math.atan2(dy, dx);var radius:Number = Math.sqrt(dx * dx + dy * dy);這種基于坐標(biāo)的旋轉(zhuǎn)只對單個物體的旋轉(zhuǎn)效果比較好,尤其是一次性就可確定角度

6、和半徑的情況下。但是在動態(tài)的程序中,有時需要旋轉(zhuǎn)多個物體,而它們與中心點(diǎn)的相對位置可能會發(fā)生改變。因此,對于每個物體來說,都需要計(jì)算距離,角度和半徑,還要用 vr 來增加角度,最后才能算出新的 x,y 坐標(biāo),每幀都如此。這就顯得太麻煩了,并且效率也不會很高。沒關(guān)系,我們還有更好的辦法。高級坐標(biāo)旋轉(zhuǎn)如果物體要繞著某一點(diǎn)旋轉(zhuǎn),并且以物體本身的位置作為旋轉(zhuǎn)的起點(diǎn),那么下面給大家一個公式。這個公式只需要給出物體距離中心點(diǎn)的相對 x,y 坐標(biāo)和旋轉(zhuǎn)的角度。它就會返回物體相對于中心點(diǎn)的新的坐標(biāo)位置?;竟饺缦拢簒1 = cos(angle) * x - sin(angle) * y;y1 = cos(a

7、ngle) * y + sin(angle) * x;公式看上去像是一串相互對稱的數(shù)字或符號,這是我剛剛接觸它時的感覺。雖然使用這個公式很多次了,但依然有這樣的感覺。我曾多次用圖形來解釋這些正弦余弦函數(shù)是如何讓 x,y 變化的,每一次都會有全新的感覺。研究 30 分鐘后,我發(fā)現(xiàn)這是兩串非常對稱的符號。雖然我通常都會給大家解釋某項(xiàng)技術(shù)完整的概念,但是如果這次我還這樣做的話,那我可能就是偽君子了。因?yàn)?,就我個人而言,也只是將這個公式背下來,以便在做夢時能把它敲出來。如果您掌握的三角學(xué)的知道比我豐富的話,那當(dāng)然最好,這樣您也許會對這項(xiàng)技術(shù)有更深層的了解;不過,即使您不是制造火箭的科學(xué)家,那么只要記住

8、這個公式,可以同樣完成出色的效果。讓我們看看這個公式都說了些什么,如圖 10-1 所示。x,y 當(dāng)然就是旋轉(zhuǎn)后的坐標(biāo)了。更準(zhǔn)確地說,這是物體繞中心點(diǎn)旋轉(zhuǎn)后的坐標(biāo)。因此,如果中心點(diǎn)位于 200,100,而物體位于 300,150,那么 x 就是 300 200 = 100,y 就是 150 100 = 50。圖10-1 坐標(biāo)旋轉(zhuǎn)角度(angle)就是某一時刻內(nèi)旋轉(zhuǎn)物體位置的大小。這并非當(dāng)前的角度,也不是旋轉(zhuǎn)后的角度,而是這兩者之間的差值。換句話講,如果物體在離中心點(diǎn) 45 度的位置,而這次的角度是 5 度,我們就要在當(dāng)前角度的基礎(chǔ)上再旋轉(zhuǎn) 5 度,到達(dá) 50 度這個位置上。這里我們并不關(guān)心最初或

9、最終的角度,只關(guān)心旋轉(zhuǎn)了多少度。通常來講,這個角度都是用弧度制表示的。OK,讓我們來看例子吧。單物體旋轉(zhuǎn)本例中將一個小球放在隨機(jī)的位置上,并使用前面介紹的方法對它進(jìn)行旋轉(zhuǎn)(文檔類 Rotate2.as):package import flash.display.Sprite;import flash.events.Event;public class Rotate2 extends Sprite private var ball:Ball;private var vr:Number = .05;private var cos:Number = Math.cos(vr);private var

10、sin:Number = Math.sin(vr);public function Rotate2() init();private function init():void ball = new Ball();addChild(ball);ball.x = Math.random() * stage.stageWidth;ball.y = Math.random() * stage.stageHeight;addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):v

11、oid var x1:Number = ball.x - stage.stageWidth / 2;var y1:Number = ball.y - stage.stageHeight / 2;var x2:Number = cos * x1 - sin * y1;var y2:Number = cos * y1 + sin * x1;ball.x = stage.stageWidth / 2 + x2;ball.y = stage.stageHeight / 2 + y2;在使用 vr 之前將它設(shè)成了 0.05,再計(jì)算這個角度的正弦和余弦值。根據(jù)小球與舞臺中心點(diǎn)的位置計(jì)算出 x1 和 y1。

12、然后使用前面講到的坐標(biāo)旋轉(zhuǎn)公式,計(jì)算出小球的新位置 x2 和 y2。由于這個位置是小球與中心點(diǎn)的相對位置,所以我們還需要把 x2 和 y2 與中心點(diǎn)相加求出最終小球的位置。實(shí)驗(yàn)一下,我們發(fā)現(xiàn)這個例子與早先那個版本執(zhí)行的結(jié)果是一樣的。也許大家會問,既然功能完全一樣,為什么還要使用這個看起來很復(fù)雜的公式呢?如果處理的內(nèi)容非常簡單,也許您的說法是正確的。下面讓我們來看看這個公式在簡化問題時的應(yīng)用。首先,考慮多物體旋轉(zhuǎn)的情況。來源:( - 第十章 坐標(biāo)旋轉(zhuǎn)及角度反彈FL車在臣_FL車在臣_新浪博客 多物體旋轉(zhuǎn)假設(shè)要旋轉(zhuǎn)多個物體,所有的影片都保存在命為 sprites 的數(shù)組中。那么 for 循環(huán)應(yīng)該是

13、這樣的:for (var i:uint = 0; i numSprites; i+) var sprite:Sprite = spritesi;var dx:Number = sprite.x - centerX;var dy:Number = sprite.y - centerY;var angle:Number = Math.atan2(dy, dx);var dist:Number = Math.sqrt(dx * dx + dy * dy);angle += vr;sprite.x = centerX + Math.cos(angle) * dist;sprite.y = center

14、Y + Math.sin(angle) * dist;然而如果使用高級坐標(biāo)旋轉(zhuǎn)的方法應(yīng)該是這樣的:var cos:Number = Math.cos(vr);var sin:Number = Math.sin(vr);for (var i:uint = 0; i numSprites; i+) var sprite:Sprite = spritesi;var x1:Number = sprite.x - centerX;var y1:Number = sprite.y - centerY;var x2:Number = cos * x1 - sin * y1;var y2:Number = c

15、os * y1 + sin * x1;sprite.x = centerX + x2;sprite.y = centerY + y2;請注意第一個版本中我們在 for 循環(huán)里調(diào)用了四次 Math 函數(shù),這意味著每個物體的旋轉(zhuǎn)都要執(zhí)行四次函數(shù)調(diào)用。第二個版本中只執(zhí)行了兩次函數(shù)調(diào)用,而且都是在 for 循環(huán)以外面執(zhí)行的,意味著它們只執(zhí)行了一次,與物體的數(shù)量無關(guān)。舉個例子,如果我們有 30 個影片,如果使用第一個版本的代碼每幀需要調(diào)用 120 次 Math 函數(shù)。大家可以想想哪個版本的效率最高。在前上一個例子程序中,刪去 enterFrame 中的 sin 和 cos 函數(shù)。這是因?yàn)檫@段程序中的角度

16、是固定的,因此可以直接給出結(jié)果。但是在很多情況下,旋轉(zhuǎn)的角度不是固定不變的,這就需要每次進(jìn)行重新計(jì)算正余弦的值。解釋一下最后這個概念。舉個例子,用鼠標(biāo)位置控制多個物體旋轉(zhuǎn)的速度。如果鼠標(biāo)在屏幕中心,則不產(chǎn)生旋轉(zhuǎn)。如果鼠標(biāo)向左移動,則物體逆時針旋轉(zhuǎn),并且越向左速度越快。如果向右移動,則順時針旋轉(zhuǎn)。除了創(chuàng)建多個 Ball 實(shí)例,并以數(shù)組存儲以外,這個例子與前面那個非常相似。下面是文檔類(Rotation3.as):package import flash.display.Sprite;import flash.events.Event;public class Rotate3 extends Sp

17、rite private var balls:Array;private var numBalls:uint = 10;private var vr:Number = .05;public function Rotate3() init();private function init():void balls = new Array();for (var i:uint = 0; i numBalls; i+) var ball:Ball = new Ball();balls.push(ball);addChild(ball);ball.x = Math.random() * stage.sta

18、geWidth;ball.y = Math.random() * stage.stageHeight;addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):void var angle:Number = (mouseX - stage.stageWidth / 2) * .001;var cos:Number = Math.cos(angle);var sin:Number = Math.sin(angle);for (var i:uint = 0; i -bal

19、l.height / 2) y2 = -ball.height / 2;vy1 *= bounce;/ 將一切旋轉(zhuǎn)回去x1 = cos * x2 - sin * y2;y1 = cos * y2 + sin * x2;ball.vx = cos * vx1 - sin * vy1;ball.vy = cos * vy1 + sin * vx1;ball.x = line.x + x1;ball.y = line.y + y1;開始,聲明變量 ball,line,gravity,bounce。在 enterFrame 函數(shù)中執(zhí)行基本運(yùn)動代碼。然后,獲得 line 的角度并轉(zhuǎn)化為弧度制。有了角度,就可以求出正余弦的值。接下來,用 ball 的位置減去 line 的位置,獲得 ball 的 x,y 與 line 的相對位置。下面,準(zhǔn)備對物體進(jìn)行旋轉(zhuǎn)!在看到這兩代碼時,注意到好像是錯的。/ 旋轉(zhuǎn)坐標(biāo)var x2:Number = cos * x1 + sin * y1;var y2:Number = cos * y1 - sin * x1;這里的加號與減號與最初的坐標(biāo)旋轉(zhuǎn)公式是相反的,最初我們的公式是:x1 = cos(angle) * x - sin(angle) * y;y1 = cos(angle) * y + sin(angle) * x;這并沒有錯??紤]

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論