當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式教程
[導(dǎo)讀]如何制作動(dòng)畫(huà)程序

■前言

在前一講中我們講述了如何利用低級(jí)API制作圖表應(yīng)用程序的方法。如果僅僅是圖表內(nèi)容的表示,那么在WEB上就可以用靜止的頁(yè)面表示。但是在手機(jī)應(yīng)用程序中表示的話(huà),就能讓圖表內(nèi)容具有動(dòng)感。這就是應(yīng)用程序與WEB的區(qū)別,這也正是其優(yōu)點(diǎn)所在。在本講中我們將進(jìn)一步講述如何在手機(jī)應(yīng)用程序中制作動(dòng)畫(huà),并詳細(xì)介紹其具體操作方法。

■4-1動(dòng)畫(huà)

基本上,動(dòng)畫(huà)能夠表現(xiàn)出文字、圖形、圖片等的描繪位置和畫(huà)面自身的連續(xù)變化。目前的程序中,按下按鍵,就會(huì)實(shí)行既定的方法。直到實(shí)行完既定方法之后才能進(jìn)行其他方法操作。但是,表示動(dòng)畫(huà)過(guò)程中,不實(shí)行動(dòng)畫(huà)表示以外的方法就沒(méi)有什么意義,因此應(yīng)該有必要在表示動(dòng)畫(huà)的同時(shí)也可以實(shí)行其他的方法。所以掌握線(xiàn)程和計(jì)時(shí)器技術(shù)的知識(shí)和應(yīng)用是必不可少的。接下來(lái),我們將詳細(xì)介紹線(xiàn)程和計(jì)時(shí)器。

■4-1-1線(xiàn)程

線(xiàn)程是執(zhí)行程序的最小單位,用來(lái)執(zhí)行Standalone的Java應(yīng)用程序的main()方法。當(dāng)你需要同步執(zhí)行多個(gè)操作,可以用多線(xiàn)程并發(fā)執(zhí)行。使用這種線(xiàn)程的程序被稱(chēng)為“多線(xiàn)程程序”。

■4-1-1-1線(xiàn)程的使用

首先我們盡快學(xué)習(xí)怎樣使用“線(xiàn)程”。有兩種方法能使用線(xiàn)程:Runnable接口的使用方法和Thread類(lèi)的繼承類(lèi)的定義方法。在此,我們使用前一個(gè)方法—實(shí)現(xiàn)Runnable接口的方法。

實(shí)現(xiàn)Runnable接口的類(lèi)必須要覆蓋run()方法。覆蓋的run()方法中記述了用線(xiàn)程執(zhí)行的處理。(ex.1)

classTestCanvasextendsCanvasimplementsRunnable{

/**

*線(xiàn)程執(zhí)行的處理

**/

publicvoidrun(){

//記述處理

.

.

}

/**

*描繪方法

**/

publicvoidpaint(Graphicsg){

//描繪處理

.

.

}

}

ex.1

另外一種方法是使用線(xiàn)程類(lèi)Thread。如下所示:用構(gòu)造函數(shù)傳遞一個(gè)參數(shù)到該類(lèi)的實(shí)例,該參數(shù)是實(shí)現(xiàn)Runnable接口的。使用start()方法就啟動(dòng)該線(xiàn)程了。(ex.2)

Runnablerunnable=newTestCanvas();//實(shí)現(xiàn)Runnable類(lèi)

Threadthread=newThread(runnable);

thread.start();

ex.2

■4-1-1-2制作簡(jiǎn)單的動(dòng)畫(huà)

接著我們來(lái)看線(xiàn)程如何被用于制作簡(jiǎn)單的動(dòng)畫(huà)。在下面的實(shí)例中,球從左向右運(yùn)動(dòng)。(ex.3)

importjavax.microedition.lcdui.Display;

importjavax.microedition.midlet.MIDlet;

importjavax.microedition.midlet.MIDletStateChangeException;

/**

*球飛出去的實(shí)例動(dòng)畫(huà)

*/

publicclassMovingBallextendsMIDlet{

privateDisplaydisplay;

privateMovingBallCanvascanvas;

/**

*構(gòu)造函數(shù)

*/

publicMovingBall(){

display=Display.getDisplay(this);

canvas=newMovingBallCanvas();

}

/**

*運(yùn)行時(shí)的處理

*/

protectedvoidstartApp()throwsMIDletStateChangeException{

display.setCurrent(canvas);

}

protectedvoidpauseApp(){}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{}

}

importjavax.microedition.lcdui.Canvas;importjavax.microedition.lcdui.Graphics;

/**

*球飛出去的實(shí)例動(dòng)畫(huà)的canvas。

*/

publicclassMovingBallCanvasextendsCanvasimplementsRunnable{

privateintx;//球的X坐標(biāo)

/**

*構(gòu)造函數(shù)

*/

publicMovingBallCanvas(){

Threadth=newThread(this);

th.start();

}

/**

*線(xiàn)程運(yùn)行的處理

*/

publicvoidrun(){

while(true){

x+=3;//更改球的坐標(biāo)

repaint();//再次描繪

try{

Thread.sleep(100);//100毫秒待機(jī)

}catch(InterruptedExceptione){

}

}

}

/**

*描繪方法

*/

protectedvoidpaint(Graphicsg){

//清除畫(huà)面

g.setColor(255,255,255);//白色

g.fillRect(0,0,getWidth(),getHeight());

//表示球

g.setColor(255,0,0);

g.fillArc(x,50,20,20,0,360);

}

}

Figure1

■4-1-1-3線(xiàn)程的待機(jī)處理

■4-1-1-3線(xiàn)程的待機(jī)處理

我們看看run()是如何支持等待機(jī)制的。如果沒(méi)有任何等待,球會(huì)迅速?gòu)淖笙蛴绎w而我們無(wú)法察覺(jué)。為此,執(zhí)行Thread中的靜態(tài)方法sleep。在其參數(shù)中指定等待時(shí)間(單位毫秒)。(ex.4)

Figure1

4-1-1

-3線(xiàn)程的待機(jī)處理

我們看看run()是如何支持等待機(jī)制的。如果沒(méi)有任何等待,球會(huì)迅速?gòu)淖笙蛴绎w而我們無(wú)法察覺(jué)。為此,執(zhí)行Thread中的靜態(tài)方法sleep。在其參數(shù)中指定等待時(shí)間(單位毫秒)。(ex.4)

Thread.sleep(100);//100毫秒待機(jī)

ex.4

如此例所示,處理和處理之間能夠待機(jī)100毫秒,按另外觀(guān)點(diǎn)看,與在100毫秒的定期間隔下運(yùn)行處理是一樣的。定期間隔下的處理,使用名為T(mén)imer的類(lèi)同樣能夠?qū)崿F(xiàn)。下面說(shuō)明一下Timer。

■4-1-2Timer

JAVA提供了計(jì)時(shí)器功能,它能有規(guī)則地、重復(fù)地執(zhí)行或者在指定時(shí)間里執(zhí)行。線(xiàn)程的運(yùn)算可以是連續(xù)的,而不僅僅是按規(guī)則的進(jìn)度。計(jì)時(shí)器的便利在于系統(tǒng)已經(jīng)為你準(zhǔn)備好特定的方法用于在指定時(shí)間或定時(shí)執(zhí)行。

■4-1-2-1時(shí)間的使用

Timer類(lèi)和TimerTask類(lèi)能夠?qū)崿F(xiàn)計(jì)時(shí)器的功能。

實(shí)例化一個(gè)TIMER的類(lèi),再調(diào)用一個(gè)繼承了TIMERTASK的類(lèi)做SCHEDULE。這樣,TimerTask子類(lèi)的run()就會(huì)在指定時(shí)間或周期被Timer實(shí)例呼叫。(表1)[!--empirenews.page--]

Table1

Timer

在Timer類(lèi)中主要使用下面的方法。

•voidschedule(TimerTasktask,Datedate)

•voidschedule(TimerTasktask,Datedate,longperiod)

•voidschedule(TimerTasktask,longdelay)

•voidschedule(TimerTasktask,longdelay,longperiod)

•voidcancel()

這些schedule方法用于設(shè)定任務(wù)及何時(shí)執(zhí)行。若不設(shè)定第三個(gè)自變量period,在第二個(gè)自變量所指定的時(shí)間任務(wù)只執(zhí)行一次。否則第二個(gè)自變量所指定的時(shí)間之后,任務(wù)會(huì)反復(fù)執(zhí)行,自變量period是反復(fù)執(zhí)行時(shí)的延時(shí)。另外,呼叫出cancel方法,則會(huì)結(jié)束計(jì)時(shí)器程序。

TimerTask

TimerTask是抽象類(lèi)。需要定義其子類(lèi)。在所繼承的類(lèi)中必須重載抽象方法run(),必須根據(jù)計(jì)時(shí)器的schedule定義具體的操作。

在TimerTask類(lèi)中主要使用如下的方法。

•abstractvoidrun()

•voidcancel()

按照Timer類(lèi)中所設(shè)定的schedule執(zhí)行run()方法。用cancel()方法能夠結(jié)束任務(wù)。

現(xiàn)在來(lái)看看用線(xiàn)程實(shí)現(xiàn)的圓球運(yùn)動(dòng)的動(dòng)畫(huà)--在這里我們也可以使用計(jì)時(shí)器來(lái)實(shí)現(xiàn)。如下所示:(ex.5)

importjavax.microedition.lcdui.Display;

importjavax.microedition.midlet.*;

/**

*球飛出去的動(dòng)畫(huà)實(shí)例計(jì)時(shí)器版

*/

publicclassTimerMovingBallextendsMIDlet{

privateDisplaydisplay;

privateTimerMovingBallCanvascanvas;

/**

*構(gòu)造函數(shù)

*/

publicTimerMovingBall(){

display=Display.getDisplay(this);

canvas=newTimerMovingBallCanvas();

}

/**

*運(yùn)行時(shí)的處理

*/

protectedvoidstartApp()throwsMIDletStateChangeException{

display.setCurrent(canvas);

}

protectedvoidpauseApp(){}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{}

}

importjava.util.*;

importjavax.microedition.lcdui.*;

/**

*球飛出去的實(shí)例動(dòng)畫(huà)的canvas。

*/

publicclassTimerMovingBallCanvasextendsCanvas{

privateintx;//球的x坐標(biāo)

privateImageimg;

privateTimertimer;

privateTimerTasktask;

/**

*構(gòu)造函數(shù)

*/

publicTimerMovingBallCanvas(){

//讀取畫(huà)像

try{

img=Image.createImage("/back.PNG");

}catch(Exceptione){

e.printStackTrace();

}

//Timer,TimerTask的設(shè)定

timer=newTimer();

task=newTimerMovingBallTask(this);

timer.schedule(task,100,100);

//從第101毫秒開(kāi)始在每100毫秒運(yùn)行任務(wù)

}

/**

*描繪方法

*/

protectedvoidpaint(Graphicsg){

g.drawImage(img,0,0,Graphics.LEFT|Graphics.TOP);

//表示球

g.setColor(255,0,0);

g.drawString(“withTimer”,0,0,Graphics.TOP|Graphics.LEFT);

g.fillArc(x,50,40,40,0,360);

}

/**

*能夠變化球的X坐標(biāo)

*/

publicvoidincrement(){

x+=3;

}

}

/**

*計(jì)時(shí)器任務(wù)根據(jù)計(jì)時(shí)器所設(shè)定的時(shí)間表,運(yùn)行run()方法。

*/

classTimerMovingBallTaskextendsTimerTask{

privateTimerMovingBallCanvascanvas;

/**

*構(gòu)造函數(shù)

*/

publicTimerMovingBallTask(TimerMovingBallCanvascanvas){

this.canvas=canvas;

}

/**

*呼叫計(jì)時(shí)器時(shí)所進(jìn)行的處理

*/

publicvoidrun(){

canvas.increment();

canvas.repaint();

}

}

ex.5

TimerMovingCanvas類(lèi)的構(gòu)造函數(shù)中進(jìn)行下面的計(jì)時(shí)器設(shè)定。

//Timer,TimerTask的設(shè)定

timer=newTimer();

task=newTimerMovingBallTask(this);

timer.schedule(task,100,100);//從第101毫秒開(kāi)始在每100毫秒運(yùn)行任務(wù)

在TimerMovingBallTask中,從TimerTask繼承的run()被調(diào)用,X坐標(biāo)的遞增使得球運(yùn)動(dòng)起來(lái)。這樣有規(guī)律地使X坐標(biāo)遞增,就使得圓球在畫(huà)面上從左到右移動(dòng)。(圖2)。

publicvoidrun(){

canvas.increment();

canvas.repaint();

}

図2

■雙緩沖

一旦進(jìn)行動(dòng)畫(huà)就要頻繁地反復(fù)操作描繪處理,畫(huà)面處理中可能會(huì)突然發(fā)生屏幕閃爍。為了能夠控制屏幕的閃爍,一般會(huì)使用雙緩沖的手法。用雙緩沖存儲(chǔ)器并不是直接在畫(huà)面上進(jìn)行描繪,而是在被稱(chēng)為屏幕外畫(huà)像的虛擬畫(huà)像上描繪全部之后,由于是表示畫(huà)面,所以能控制屏幕的閃爍。(圖3)

Figure3

根據(jù)手機(jī)機(jī)種的不同,事先將Canvas類(lèi)與雙緩沖存儲(chǔ)器相對(duì)應(yīng)的情況也是有的。換言之,即使實(shí)現(xiàn)方?jīng)]有明確地定義雙緩沖存儲(chǔ)器,則在用雙緩沖存儲(chǔ)器的機(jī)制進(jìn)行描繪的情況下,沒(méi)必要特別關(guān)心閃爍的解決方案,但是要在不同的機(jī)型上運(yùn)行。N800的機(jī)型已經(jīng)能適應(yīng)此雙緩沖存儲(chǔ)器。為此,開(kāi)發(fā)N800應(yīng)用程序的時(shí)候,有時(shí)會(huì)有必要在這闡述雙緩沖存儲(chǔ)器的處理。此時(shí),應(yīng)該知道終端是否適應(yīng)雙緩沖存儲(chǔ)器、以及是否有必要分開(kāi)處理。[!--empirenews.page--]

使用Canvas類(lèi)的isDoubleBufferd()方法就能知道是否適應(yīng)雙緩沖存儲(chǔ)器。由于使用這種方法可以區(qū)分開(kāi)適應(yīng)雙緩沖存儲(chǔ)器的情況和不適應(yīng)適應(yīng)的情況,因此無(wú)論在什么樣的環(huán)境下都能夠有效控制閃爍現(xiàn)象。示例如下:(ex.6)

classDoubleBufferdCanvasextendsCanvas{

ImageoffImg=null;//關(guān)閉畫(huà)面的圖片

/**

*表示canvas之前所運(yùn)行的方法

*/

protectedvoidshowNotify(){

if(!isDoubleBuffered()){//關(guān)閉畫(huà)面的圖片

offImg=Image.createImage(getWidth(),getHeight());

}

}

/**

*描繪方法

*/

protectedvoidpaint(Graphicsg){

Graphicsbg=null;

if(offImg!=null){

bg=offImg.getGraphics();

}else{

bg=g;

}

//使用bg描繪

bg.setColor(255,255,255);

bg.fillRect(0,0,getWidth(),getHeight());

bg.setColor(255,0,0);

bg.drawArc(x,y,30,30,0,360);//描畫(huà)圓

//將offscreenimage導(dǎo)入畫(huà)面

if(!isDoubleBuffered()){

g.drawImage(offImg,0,0,Graphics.TOP|Graphics.LEFT);

bg=null;

}

}

}

ex.6

■制作應(yīng)用程序

4-3-1時(shí)鐘的應(yīng)用程序

那么,現(xiàn)在我們就作為示范使用動(dòng)畫(huà)制作應(yīng)用程序吧。在本講中將要制作的應(yīng)用程序就是模擬表應(yīng)用程序。利用秒表,描繪出模擬表。在描繪模擬表針時(shí)使用三角函數(shù)。類(lèi)結(jié)構(gòu)表如下:(表2)

Table2

4-3-2時(shí)間的設(shè)定

在模擬表應(yīng)用程序中秒針一秒動(dòng)一下。因此,使用秒表,要設(shè)定每秒不同時(shí)刻的畫(huà)面更新。在ClockCanvas類(lèi)的paint方法內(nèi)取得時(shí)刻,描繪鐘表。秒表任務(wù)如下所示:(ex.7)

/**********************************************

*秒表任務(wù)

**********************************************/

classClockTimerTaskextendsTimerTask{

privateClockCanvascanvas;

/**

*構(gòu)造函數(shù)

*/

publicClockTimerTask(ClockCanvascanvas){

this.canvas=canvas;

}

/**

*在每個(gè)指定時(shí)間內(nèi)運(yùn)行

*/

publicvoidrun(){

canvas.repaint();//再次描繪canvas

}

}

ex.7

定義完秒表任務(wù)后,就要在秒表上設(shè)定秒表任務(wù)。用ClockCanvas類(lèi)的構(gòu)造函數(shù)進(jìn)行如下設(shè)定。(ex.8)

/**

*構(gòu)造函數(shù)

*/

publicClockCanvas(){

//設(shè)定秒表

timer=newTimer();

timerTask=newClockTimerTask(this);

timer.schedule(timerTask,1000,1000);//Onceevery1,000ms

}

ex.8

4-3-3描畫(huà)鐘表

設(shè)定完秒表后開(kāi)始描繪鐘表。下面就是鐘表的框架(clock.png)。(圖4)

Figure4

接下來(lái)描畫(huà)秒針。因?yàn)橐鶕?jù)時(shí)刻變化秒針的位置,所以有必要根據(jù)時(shí)刻計(jì)算秒針的位置。在這兒用Graphics類(lèi)的drawLine方法描繪秒針。在表的中心坐標(biāo)上固定住線(xiàn)的始點(diǎn),從時(shí)刻中計(jì)算出線(xiàn)的終點(diǎn)。

使用三角函數(shù)計(jì)算秒針終點(diǎn)的坐標(biāo)。表的中心坐標(biāo)是(x,y)、秒針的長(zhǎng)度設(shè)為1,秒針的角度設(shè)為θ,那么終點(diǎn)的坐標(biāo)就是(x+l*cos(θ),y+l*sin(θ))。(圖5)

Figure5

三角函數(shù)的實(shí)際計(jì)算,在J2SE中,Math類(lèi)有sin,cos方法,所以通常會(huì)使用這些方法,而J2ME中是沒(méi)有這種方法的。因此,在本講中定義了名為T(mén)rigonometricFunctions的類(lèi),將預(yù)先計(jì)算好的sin,cos值擴(kuò)大10000倍排列并保持在這個(gè)類(lèi)中。所謂擴(kuò)大10000倍,是由于J2ME不支持double和float等小數(shù)點(diǎn)型,所以不能原封不動(dòng)地保存小數(shù)點(diǎn)sin,cos。因此,用MIDP處理小數(shù)時(shí),將小數(shù)擴(kuò)大幾倍變成整數(shù)加以保持,實(shí)際上在使用時(shí),用事先乘出的數(shù)值再除以所乘的數(shù)值,計(jì)算并使用由此而得出的實(shí)際值。

然而,在J2ME下處理含有小數(shù)的數(shù)值時(shí),由于要將小數(shù)四舍五入成整數(shù)所以就會(huì)產(chǎn)生誤差。例如:0.12341234…四舍五入成整數(shù)就是0,這與原來(lái)的0.12341234…是有誤差的。由于要盡量減少誤差,所以計(jì)算之前要盡可能的乘以大數(shù)值并且有必要保存其整數(shù)。例如:在先前的0.12341234…基礎(chǔ)上乘以1000后就變成了123.41234…,小數(shù)點(diǎn)以下四舍五入后就是123。將123除以1000后就是0.123。這與開(kāi)始的數(shù)值之間的誤差僅為0.00041234…,原封不動(dòng)的將原來(lái)的數(shù)值四舍五入后數(shù)值0產(chǎn)生的誤差是0.00041234…,二者相比則前者的誤差要小的多??傊?,小數(shù)上乘以的數(shù)值越大四舍五入后與原來(lái)的數(shù)值之間的誤差就越小。

先講sin,cos的數(shù)值擴(kuò)大10000倍,秒針坐標(biāo)計(jì)算的最后在除以10000。N800畫(huà)面尺寸的縱長(zhǎng)為180,那么進(jìn)行180*x(只有X為小數(shù))計(jì)算時(shí)的最大誤差是

0.0000999...*180=0.017999...isapproximately0.0180

總是比1小,沒(méi)有四舍五入的誤差。

接下來(lái)描繪秒針。SecondAngle作為秒針的角度,SECOND_LENGTH是秒針的長(zhǎng)度,表的中心坐標(biāo)是(CENTER_X,CENTER_Y)。(ex.9)

intsecondX=CENTER_X+TrigonometricFunctions.COS[secondAngle]*SECOND_LENGTH/10000;

intsecondY=CENTER_Y-TrigonometricFunctions.SIN[secondAngle]*SECOND_LENGTH/10000;

g.drawLine(CENTER_X,CENTER_Y,secondX,secondY);

ex.9

下面是ClockCanvas類(lèi)的源碼。畫(huà)面上有表的中心坐標(biāo)。

importjava.util.*;

importjavax.microedition.lcdui.*;[!--empirenews.page--]

/**

*時(shí)鐘的畫(huà)面

*/

publicclassClockCanvasextendsCanvas{

privateClockTimerTasktimerTask;

privateTimertimer;

privatefinalStringIMAGE_PATH="/clock.png";

privatefinalintCLOCK_WIDTH=150;//時(shí)鐘的畫(huà)面寬度

privatefinalintCENTER_X=5+CLOCK_WIDTH/2;

privatefinalintCENTER_Y=CLOCK_WIDTH/2;

privatefinalintHOUR_LENGTH=CLOCK_WIDTH/4;//時(shí)鐘的長(zhǎng)度

privatefinalintMINUTE_LENGTH=CLOCK_WIDTH*2/5;//分鐘的長(zhǎng)度

privatefinalintSECOND_LENGTH=CLOCK_WIDTH*2/5;//秒鐘的長(zhǎng)度

privateImageimg;//畫(huà)面的背景

/**

*構(gòu)造函數(shù)

*/

publicClockCanvas(){

//設(shè)置timer

timer=newTimer();

timerTask=newClockTimerTask(this);

timer.schedule(timerTask,1000,1000);

//登陸背景畫(huà)面

try{

img=Image.createImage(IMAGE_PATH);

}catch(Exceptione){

e.printStackTrace();

}

}

/**

*畫(huà)時(shí)鐘

*/

protectedvoidpaint(Graphicsg){

//背景的設(shè)置

g.setColor(255,255,255);

g.fillRect(0,0,getWidth(),getHeight());

g.drawImage(img,5,0,Graphics.TOP|Graphics.LEFT);

//獲得時(shí)間

Calendarcal=Calendar.getInstance();

inthour=(int)cal.get(Calendar.HOUR);

inthour_of_day=(int)cal.get(Calendar.HOUR_OF_DAY);

intminute=(int)cal.get(Calendar.MINUTE);

intsecond=(int)cal.get(Calendar.SECOND);

intyear=(int)cal.get(Calendar.YEAR);

intmonth=(int)cal.get(Calendar.MONTH)+1;

intday=(int)cal.get(Calendar.DAY_OF_MONTH);

//顯示時(shí)間

g.setColor(0,0,200);

StringdateString=year+"/"+month+"/"+day+""+hour_of_day+":"+minute+":"+second;

g.drawString(dateString,CENTER_X,getHeight()-25,Graphics.TOP|Graphics.HCENTER);

//時(shí)鐘時(shí)針的顯示

g.setColor(100,100,100);

inthourAngle=360-30*hour+90;

if(hourAngle>=360)hourAngle-=360;

inthourX=CENTER_X+TrigonometricFunctions.COS[hourAngle]*HOUR_LENGTH/TrigonometricFunctions.MULTIPLE;

inthourY=CENTER_Y-TrigonometricFunctions.SIN[hourAngle]*HOUR_LENGTH/TrigonometricFunctions.MULTIPLE;

//描繪時(shí)針

for(inti=-2;i<3;i++){

g.drawLine(CENTER_X+i,CENTER_Y+i,hourX,hourY);

g.drawLine(CENTER_X-i,CENTER_Y+i,hourX,hourY);

}

//分針的顯示

intminuteAngle=360-6*minute+90;

if(minuteAngle>=360)minuteAngle-=360;

intminuteX=CENTER_X+TrigonometricFunctions.COS[minuteAngle]*MINUTE_LENGTH/TrigonometricFunctions.MULTIPLE;

intminuteY=CENTER_Y-TrigonometricFunctions.SIN[minuteAngle]*MINUTE_LENGTH/TrigonometricFunctions.MULTIPLE;//j`

//畫(huà)分針的范圍

for(inti=-2;i<3;i++){

g.drawLine(CENTER_X+i,CENTER_Y+i,minuteX,minuteY);

g.drawLine(CENTER_X-i,CENTER_Y+i,minuteX,minuteY);

}

//秒針的顯示

intsecondAngle=360-6*second+90;

if(secondAngle>=360)secondAngle-=360;

intsecondX=CENTER_X+TrigonometricFunctions.COS[secondAngle]*SECOND_LENGTH/TrigonometricFunctions.MULTIPLE;

intsecondY=CENTER_Y-TrigonometricFunctions.SIN[secondAngle]*SECOND_LENGTH/TrigonometricFunctions.MULTIPLE;

g.drawLine(CENTER_X,CENTER_Y,secondX,secondY);

}

}

Figure6

4-3-4

擴(kuò)展函數(shù)

在本講中制作的模擬表應(yīng)用程序是實(shí)現(xiàn)了表的最小功能的示范應(yīng)用程序。在本應(yīng)用程序中,也可以自己增加鬧鐘和跑秒等擴(kuò)展功能,這些自己都嘗試一番哦。

4-4總結(jié)

在本講中我們講述了制作動(dòng)畫(huà)應(yīng)用程序的具體方法。使用動(dòng)畫(huà),就要對(duì)畫(huà)像賦予動(dòng)感,這比游戲還要復(fù)雜,所以應(yīng)該能夠制作圖表應(yīng)用程序。要運(yùn)行動(dòng)畫(huà),線(xiàn)據(jù)和秒表是不可缺少的基本技術(shù),但是線(xiàn)據(jù)知識(shí)是一門(mén)深?yuàn)W的技術(shù)。參照本講中的樣品,加深線(xiàn)據(jù)方面的知識(shí),就能夠制作成不錯(cuò)的應(yīng)用程序。在下一講中,我們將就效果音和BGM、聲音等技術(shù)進(jìn)行詳細(xì)講解。敬請(qǐng)關(guān)注!

4-3-4完成

以下是所制作的程序的源碼。

Clock.java

ClockCanvas.java

ClockTimerTask.java

TrigonometricFunctions.java

[!--empirenews.page--]

運(yùn)行結(jié)果如下所示:(図6).

Figure6

4-3-4

擴(kuò)展函數(shù)

在本講中制作的模擬表應(yīng)用程序是實(shí)現(xiàn)了表的最小功能的示范應(yīng)用程序。在本應(yīng)用程序中,也可以自己增加鬧鐘和跑秒等擴(kuò)展功能,這些自己都嘗試一番哦。

4-4總結(jié)

在本講中我們講述了制作動(dòng)畫(huà)應(yīng)用程序的具體方法。使用動(dòng)畫(huà),就要對(duì)畫(huà)像賦予動(dòng)感,這比游戲還要復(fù)雜,所以應(yīng)該能夠制作圖表應(yīng)用程序。要運(yùn)行動(dòng)畫(huà),線(xiàn)據(jù)和秒表是不可缺少的基本技術(shù),但是線(xiàn)據(jù)知識(shí)是一門(mén)深?yuàn)W的技術(shù)。參照本講中的樣品,加深線(xiàn)據(jù)方面的知識(shí),就能夠制作成不錯(cuò)的應(yīng)用程序。在下一講中,我們將就效果音和BGM、聲音等技術(shù)進(jìn)行詳細(xì)講解。敬請(qǐng)關(guān)注!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀(guān)點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉