- J2ME手機游戲設計與開發
- 劉暢 張旭輝編著
- 12字
- 2019-01-01 07:08:58
3.6 高級屏幕類綜合應用實例
3.6.1 Form組件綜合練習
【例3-14】 Form組件綜合練習。前面已經學習了所有的Form組件,這里將所有的組件都集中放置在Form界面上,進行綜合練習。
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class mainMidlet extends MIDlet implements CommandListener{ private Form mainscreen; private Command okCommand = new Command("OK", Command.OK, 1); private Command exitCommand = new Command("Exit", Command.EXIT, 1); private Display display; public mainMidlet() { mainscreen= new Form("Form demo"); mainscreen.addCommand(okCommand); mainscreen.addCommand(exitCommand); mainscreen.setCommandListener(this); //創建StringItem對象 mainscreen.append(new StringItem("StringItem Test", "The following is Duke.")); //創建ImageItem對象 Image img=null; try { img= Image.createImage("/smallDuke.png"); } catch (Exception e) {} mainscreen.append(new ImageItem("ImageItem test", img, ImageItem.LAYOUT_CENTER, "Image can not display")); //創建Choice對象 String[] editable_choices={"editable", "uneditable"}; mainscreen.append(new ChoiceGroup("Gauge option",Choice.EXCLUSIVE, editable_choices,null)); //創建TextField對象 mainscreen.append(new TextField("TextField", "", 20, TextField. ANY)); //創建DateField對象 mainscreen.append(new DateField("DateField", DateField.DATE)); //創建Gauge對象 mainscreen.append(new Gauge("Gauge Test",true,100,50)); //創建Display對象 display=Display.getDisplay(this); } public void startApp() throws MIDletStateChangeException { display.setCurrent(mainscreen); public void pauseApp() { } public void destroyApp(boolean unconditional) { //清除所有對象 mainscreen=null; okCommand = null; exitCommand = null; display=null; } public void commandAction(Command c, Displayable d) { if(c==okCommand) { //事件響應 } else if(c==exitCommand) { //退出程序 destroyApp(true); notifyDestroyed(); } } }
執行效果如圖3-26所示。

圖3-26 Form組件綜合應用效果圖
3.6.2 生物鐘軟件
1.游戲設計思想
人體生物鐘的節律特征如表3-19所示。
表3-19 人體生物鐘的節律特征
節律的計算公式:
Y=X%N:Y是節律,X是總天數,N是節律周期。
體力節律:Y1=X%23
情緒節律:Y2=X%28
智力節律:Y3=X%33
·當Y=0或Y=1或(N/2-1)<=Y<=(N/2+1)時,人體處于臨界日;
·當Y<N/2時,且不是臨界日,人體則處于高潮期;
·當Y>N/2時,且不是臨界日,人體則處于低潮期。
游戲規則:游戲者輸入出生日期,系統檢測出游戲者當日的體力、情緒和智力方面的生理現象。
2.游戲設計流程
生物鐘軟件設計流程圖如圖3-27所示。

圖3-27 生物鐘軟件流程圖
3.游戲設計的難點和解決方法
(1)如何計算天數。
Date Date;=datefield.getDate() Long temp=System.currenttimeMillis-date.getTime(); Long X=temp/24/60/60/1000;
(2)重置游戲。
將3個StringItem清空或者設成無檢測即可:
si1.setText(""); si2.setText(""); si3.setText("");
4.程序的完整代碼
import java.util.Date; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class ClockMidlet extends MIDlet implements CommandListener { Form f; DateField df; StringItem si1; StringItem si2; StringItem si3; Command exitCommand; Command checkCommand; Command restartCommand; public ClockMidlet() { super(); f=new Form("生物鐘"); df=new DateField("出生日期",DateField.DATE); si1=new StringItem("體力",""); si2=new StringItem("情緒",""); si3=new StringItem("智力",""); exitCommand=new Command("退出",Command.EXIT,1); checkCommand=new Command("檢測",Command.OK,2); restartCommand=new Command("重置",Command.OK,2); f.addCommand(exitCommand); f.addCommand(checkCommand); f.addCommand(restartCommand); f.append(df); f.append(si1); f.append(si2); f.append(si3); f.setCommandListener(this); } protected void destroyApp(boolean arg0) { } protected void pauseApp() {} protected void startApp(){ Display.getDisplay(this).setCurrent(f); } public void commandAction(Command cmd, Displayable arg1) { if(cmd==checkCommand) { Date date=df.getDate(); long temp=System.currentTimeMillis()-date.getTime(); long X=temp/24/60/60/1000; long Y1=X%23; long Y2=X%28; long Y3=X%33; if(Y1==0||Y1==1||(Y1>=23/2-1&&Y1<=23/2+1)) //計算體力周期 si1.setText("易患疾病"); else if(Y1<23/2) si1.setText("體力充沛精力旺"); else si1.setText("體力不足易疲勞"); if(Y2==0||Y2==1||(Y2>=28/2-1&&Y2<=28/2+1)) //計算情緒周期 si2.setText("容易沖動"); else if(Y2<28/2) si2.setText("情緒高精神爽"); else si2.setText("情緒低心情煩"); if(Y3==0||Y3==1||(Y3>=33/2-1&&Y3<=33/2+1)) //計算智力周期 si3.setText("易出差錯"); else if(Y2<33/2) si3.setText("思維敏捷反應快"); else si3.setText("反應遲鈍記憶差"); }else if(cmd==exitCommand) //退出按鈕 { destroyApp(false); notifyDestroyed(); }else if(cmd==restartCommand) //重置按鈕 { si1.setText(""); si2.setText(""); si3.setText(""); } } }
5.執行效果如圖3-28所示

圖3-28 生物鐘軟件效果圖
3.6.3 猜數字游戲設計
1.游戲設計思想
計算機隨機產生不重復的四位數字,用戶輸入猜測的數字,根據所給反饋信息繼續輸入,直到正確或者到達最多次數失敗為止。
(1)每次啟動游戲,系統先隨機生成一個四位數,每個數字不重復。
(2)游戲者有5次機會來猜出目標數,每次機會中,游戲者可以輸入一個四位數,同樣不允許重復,例如2334是錯誤的。
(3)游戲者輸入后,單擊“確定”按鈕,系統給出判斷信息,以文本形式出現,例如2A1B,即有2個數的位置正確和數字正確,1個數的位置錯誤但是數字正確。
(4)如果輸入數與目標數完全正確則成功,若5次都沒猜對,則失敗。
2.游戲的設計流程
猜數字游戲設計流程圖如圖3-29所示。

圖3-29 猜數字游戲流程圖
3.游戲的制作難點和解決方法
(1)啟動游戲后,如何生成四位不同的隨機數。
Random隨機類的用法如下。
構造方法:Random r=new Random();
常用方法:r.nextInt(); 生成一個隨機整數,通常采用以下方法處理Math.abs(ran.nextInt()%10)生成10以內的整數。
private void initNum() { for(int i=0;i<4;i++) { n_Num[i]=Math.abs(ran.nextInt()%10); for(int j=i;j<i;j++) { if(n_Num[i]==n_Num[j]) //避免生成相 同的數字 { j--; break; } } } }
(2)如何判斷游戲者輸入的數字是合法的。
private boolean check(char[] a_Num) { if(tf.getString().length()!=4) //判斷是否輸入了四位數 return false; for(int i=0;i<4;i++) //判斷是否輸入了重復的數字 for(int j=i;j<4;j++) { if(a Num[i]==a_Num[j]&&i!=j) return false; } return true; }
(3)如何根據游戲者的輸入給出反饋信息。
tf.getChars(c_aNum); //獲取輸入內容 if(check(c_aNum)) //判斷輸入內容是否正確的 { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if((int)(c_aNum[i]-'0')==n_Num[j]) //進行對比,計算nA和nB { if(i==j) nA++; else nB++; } }
4.完整代碼
import java.util.Random; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class GuessMidlet extends MIDlet implements CommandListener { Display disp; Form form; TextField tf; StringItem si; Command cmdEnter; Command cmdExit; Random ran=new Random(); int[] n_Num=new int[4]; char[] c_aNum=new char[4]; public GuessMidlet() { disp=Display.getDisplay(this); form=new Form("猜數字"); tf=new TextField("輸入數字","",4,TextField.NUMERIC); si=new StringItem("反饋信息",""); cmdEnter=new Command("確定",Command.OK,1); cmdExit=new Command("退出",Command.EXIT,1); form.append(tf); form.append(si); form.addCommand(cmdEnter); form.addCommand(cmdExit); form.setCommandListener(this); form.setCommandListener(this); initNum(); } private void initNum() { for(int i=0;i<4;i++) { n_Num[i]=Math.abs(ran.nextInt()%10); for(int j=i;j<i;j++) { if(n_Num[i]==n_Num[j]) { j--; break; } } } } protected void destroyApp(boolean arg0) throws MIDletStateChange Exception { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { disp.setCurrent(form); } private boolean check(char[] a_Num) { if(tf.getString().length()!=4) return false; for(int i=0;i<4;i++) for(int j=i;j<4;j++) {if(a_Num[i]==a_Num[j]&&i!=j) return false; } return true; } public void commandAction(Command cmd, Displayable d) { int nA=0; int nB=0; if(cmd==cmdExit) { try { destroyApp(false); } catch (MIDletStateChangeException e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } notifyDestroyed(); } else if(cmd==cmdEnter) { tf.getChars(c_aNum); if(check(c_aNum)) { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if((int)(c_aNum[i]-'0')==n_Num[j]) { if(i==j) nA++; else nB++; } } else { System.out.println("False"); } StringBuffer buffer=new StringBuffer(); buffer.append(nA); buffer.append("A"); buffer.append(nB); buffer.append("B"); si.setText(buffer.toString()); } } }
5.執行效果如圖3-30所示

圖3-30 猜數字游戲效果圖
3.6.4 心理測試軟件
1.游戲的設計思想
(1)用戶根據問題選擇答案,答完所有題目后單擊“確定”按鈕,根據所選答案給出心理測試的結果信息。
(2)第一個界面顯示心理測試的問題。
(3)用戶輸入后,計算所得分數切換到第二個界面。
(4)第二個界面給出相應的信息,并且可以返回到第一個界面。
(5)第一個界面可以退出軟件。
2.界面對象分析
(1)界面1:formAsk負責提出問題。
Form對象:
ChoiceGroup對象,負責給出問題和選項;
Command對象,負責退出和確定。
(2)界面2:formAnswer負責給出心理測試的答案。
Form對象:
Command對象,負責返回初始界面。
3.游戲的設計流程
心理測試軟件設計流程圖如圖3-31所示。

圖3-31 心理測試軟件流程圖
4.游戲的制作難點和解決方法
(1)計算得分。根據選項的序號設定得分:
int i=cg1.getSelectedIndex()+cg2.getSelectedIndex()+ cg3.getSelectedIndex()+cg4.getSelectedIndex()+cg5.getSelectedIndex();
(2)返回問題界面時同時清除答案界面的內容。
if(cmd==cmdBack){ disp.setCurrent(formAsk); formAnswer.deleteAll(); }
5.完整代碼
import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class HeartMidlet extends MIDlet implements CommandListener { Display disp; Form formAsk,formAnswer; ChoiceGroup cg1,cg2,cg3,cg4,cg5; Command cmdEnter; Command cmdExit,cmdBack; public HeartMidlet() { disp=Display.getDisplay(this); formAsk=new Form("提問"); formAnswer=new Form("測試結果"); cg1=new ChoiceGroup("你想改變目前的生活狀態么?",ChoiceGroup. EXCLUSIVE); cg1.append("想", null); cg1.append("無所謂", null); cg1.append("不想", null); cg2=new ChoiceGroup("你想改變目前的生活狀態么?",ChoiceGroup. EXCLUSIVE); cg2.append("想", null); cg2.append("無所謂", null); cg2.append("不想", null); cg3=new ChoiceGroup("你想改變目前的生活狀態么?",ChoiceGroup. EXCLUSIVE); cg3.append("想", null); cg3.append("無所謂", null); cg3.append("不想", null); cg4=new ChoiceGroup("你想改變目前的生活狀態么?",ChoiceGroup. EXCLUSIVE); cg4.append("想", null); cg4.append("無所謂", null); cg4.append("不想", null); cg5=new ChoiceGroup("你想改變目前的生活狀態么?",ChoiceGroup. EXCLUSIVE); cg5.append("想", null); cg5.append("無所謂", null); cg5.append("不想", null); cmdEnter=new Command("確定",Command.OK,1); cmdExit=new Command("退出",Command.EXIT,2); cmdBack=new Command("返回",Command.BACK,2); formAsk.append(cg1); formAsk.append(cg2); formAsk.append(cg3); formAsk.append(cg4); formAsk.append(cg5); formAsk.addCommand(cmdEnter); formAsk.addCommand(cmdExit); formAnswer.addCommand(cmdBack); formAsk.setCommandListener(this); formAnswer.setCommandListener(this); } protected void destroyApp(boolean arg0) { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { disp.setCurrent(formAsk); } public void commandAction(Command cmd, Displayable arg1) { if(cmd==cmdExit) { destroyApp(false); notifyDestroyed(); }else if(cmd==cmdBack){ disp.setCurrent(formAsk); formAnswer.deleteAll(); }else if(cmd==cmdEnter) { int i=cg1.getSelectedIndex()+cg2.getSelectedIndex()+ cg3.getSelectedIndex()+cg4.getSelectedIndex()+cg5.getSelectedIndex(); if(i<4) formAnswer.append("你處在比較積極的狀態"); else if(i<6) formAnswer.append("你已經開始發懶了"); else if(i<8) formAnswer.append("你的惰性很大了"); else if(i<=10) formAnswer.append("你已經是懶骨頭了"); disp.setCurrent(formAnswer); } } }
6.執行效果如圖3-32所示

圖3-32 心理測試軟件效果圖
3.6.5 電子書的制作
通過高級屏幕類閱讀已經存儲在程序中的詩詞,重點是建立詩詞目錄界面及每首詩詞的顯示界面。
1.游戲功能
啟動界面加載條,當加載結束后進入一級菜單,選項包括“唐詩鑒賞”和“宋詞鑒賞”。根據選擇進入相應的二級菜單,包括唐詩和宋詞的題目,然后進入具體的內容閱讀。
2.程序的構成
整個程序只有一個EBookMIDlet類,用來切換不同的顯示內容。
本程序主要是通過高級屏幕類閱讀已經存儲在程序中的詩詞,重點是建立詩詞目錄界面以及每首詩詞的顯示界面。
完整代碼如下:
import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; public class EBookMIDlet extends MIDlet implements Runnable,CommandListener, ItemCommandListener{ /**屏幕顯示對象*/ private Display display; /**加載提示*/ private Alert alert; /**加載條*/ private Gauge gauge; /**數目列表*/ private List list; /**章節列表*/ private Form form; /**書本內容*/ private TextBox textBox; /**初始時間*/ long firstTime; private Image image; private final Command cmdEnter = new Command("進入",Command.OK,1); private final Command cmdExit = new Command("退出",Command.EXIT,1); private final Command cmdBack = new Command("返回",Command.BACK,1); /**當前書目索引*/ private int curBookIndex = 0; /**書目*/ private String[] bookName = {"《唐詩鑒賞》","《宋詞鑒賞》"}; /**二維字符串數組,用以每首詩詞的序號、名稱、作者及內容*/ private String[][] text = {{ "第一首","水調歌\n作者:無名氏\n","平沙落日大荒西,隴上明星高復低。\n孤山幾處看烽火,壯士連營候鼓鼙。", "第二首","感遇四首之一\n作者:張九齡\n"," 孤鴻海上來,池潢不敢顧。\n側見雙翠鳥,巢在三珠樹。\n矯矯珍木巔,得無金丸懼。\n美服患人指,高明逼神惡。\n今我游冥冥,弋者何所慕。", "第三首","春思\n作者:李白\n"," 燕草如碧絲,秦桑低綠枝。\n當君懷歸日,是妾斷腸時。\n春風不相識,何事入羅幃?", "第四首","夕次盱眙縣\n作者:韋應物\n"," 落帆逗淮鎮,停舫臨孤驛。\n浩浩風起波,冥冥日沈夕。\n人歸山郭暗,雁下蘆洲白。\n獨夜憶秦關,聽鐘未眠客。", "第五首","溪居\n作者:柳宗元\n"," 久為簪組累,幸此南夷謫。\n閑依農圃鄰,偶似山林客。\n曉耕翻露草,夜榜響溪石。\n來往不逢人,長歌楚天碧。", "第六首","塞下曲\n作者:王昌齡\n"," 飲馬渡秋水,水寒風似刀。\n平沙日未沒,黯黯見臨洮。\n昔日長城戰,咸言意氣高。\n黃塵足今古,白骨亂蓬蒿。", "第七首","子夜四時歌:春歌\n作者:李白\n"," 秦地羅敷女,采桑綠水邊。\n素手青條上,紅妝白日鮮。\n蠶饑妾欲去,五馬莫留連。", "第八首","子夜四時歌:夏歌\n作者:李白\n"," 鏡湖三百里,菡萏發荷花。\n五月西施采,人看隘若耶。\n回舟不待月,歸去越王家。", "第九首","子夜四時歌:秋歌\n作者:李白\n","長安一片月,萬戶搗衣聲。\n秋風吹不盡,總是玉關情。\n何日平胡虜,良人罷遠征?", "第十首","子夜四時歌:冬歌\n作者:李白\n","明朝驛使發,一夜絮征袍。\n素手抽針冷,那堪把剪刀。\n裁縫寄遠道,幾日到臨洮?", "第十一首","送別\n作者:王維\n","下馬飲君酒,問君何所之。\n君言不得意,歸臥南山陲。\n但去莫復聞,白云無盡時。"}, { "第一首","宴山亭.北行見杏花\n作者:趙佶\n","裁剪冰綃,輕疊數重,淡著燕脂勻注。\n新樣靚妝,艷溢香融,羞殺蕊珠宮女。\n易得凋零,更多少、無情風雨。 愁苦,問院落凄涼,幾番春暮?\n憑寄離恨重重,者雙燕何曾,會人言語?\n天遙地遠,萬水千山,知他故宮何處?怎不思量?\n除夢里有曾去。無據,和夢也新來不做。", "第二首","木蘭花\n作者:錢惟演\n","城上風光鶯語亂,城下煙波春拍岸。\n綠楊芳草幾時休?淚眼愁腸先已斷。\n情懷漸覺成衰晚,鸞鏡朱顏驚暗換。\n昔年多病厭芳尊,今日芳尊惟恐淺。", "第三首","蘇幕遮\n作者:范仲淹\n","碧云天,黃葉地,秋色連波,波上寒煙翠。\n山映斜陽天接水,芳草無情,更在斜陽外。\n黯鄉魂,追旅思。夜夜除非,好夢留人睡。\n明月樓高休獨倚,酒入愁腸,化作相思淚。", "第四首","御街行\n作者:范仲淹\n","紛紛墜葉飄香砌。夜寂靜,寒聲碎。\n真珠簾卷玉樓空,天淡銀河垂地。\n年年今夜,月華如練,長是人千里。\n愁腸已斷無由醉,酒未到,先成淚。\n殘燈明滅枕頭[奇支],諳盡孤眠滋味。\n都來此事,眉間心上,無計相回避。", "第五首","千秋歲\n作者:張先\n","數聲[是鳥][夫鳥],又報芳菲歇。\n惜春更選殘紅折,雨輕風色暴,梅子青時節。\n永豐柳,無人盡日花飛雪。莫把幺弦撥,怨極弦能說。\n天不老,情難絕,心似雙絲網,中有千千結。\n夜過也,東窗未白孤燈滅。", "第六首","菩薩蠻\n作者:張先\n","哀箏一弄《湘江曲》,聲聲寫盡湘波綠。\n纖指十三弦,細將幽恨傳。 當筵秋水慢,玉柱斜飛雁。\n彈到斷腸時,春山眉黛低。 醉垂鞭 張先雙蝶繡羅裙,東池宴初相見。朱粉不深勻,閑花淡淡春。\n細看諸處好,人人道柳腰身。昨日亂山昏,來時衣上云。" } }; public EBookMIDlet() { display = Display.getDisplay(this); alert = new Alert("E-Book啟動中",null,null,AlertType.INFO); gauge = new Gauge(null,false,5,1); alert.setIndicator(gauge); alert.setTimeout(6000); firstTime = System.currentTimeMillis(); image = createImage("/flag.png"); list = new List("書目",Choice.IMPLICIT,bookName,new Image[]{image, image}); list.addCommand(cmdEnter); list.addCommand(cmdExit); list.setCommandListener(this); new Thread(this).start(); //啟動線程,將在之后的章節具體介紹 } private Image createImage(String file){ Image image = null; try{ image = Image.createImage(file); }catch(Exception e){ e.printStackTrace(); } return image; } protected void destroyApp(boolean arg0){ } protected void pauseApp() { } protected void startApp(){ display.setCurrent(alert); } /** * 控制進度提示 */ public void run() { // TODO Auto-generated method stub while(true){ int time = (int)(System.currentTimeMillis() - firstTime); gauge.setValue(time/1000); if(time >= alert.getTimeout()){ display.setCurrent(list); alert.setIndicator(null); break; } } } /** * 創建每首詩詞顯示在Form中的Item * @param label * @param text * @return */ private Item createItem(String label,String text){ Item item = new StringItem(label,text,Item.PLAIN); item.addCommand(cmdEnter); item.setItemCommandListener(this); return item; } /** * 創建顯示詩詞信息的Form * @param bookIndex * @return */ private Form createForm(int bookIndex){ Form form = new Form(bookName[bookIndex]); for(int i=0; i<text[bookIndex].length/3; i++){ form.append(createItem(text[bookIndex][i*3+0],text[bookIndex] [i*3+1])); } form.addCommand(cmdBack); form.setCommandListener(this); return form; } /** * 創建詩詞顯示的TextBox * @param title * @param text * @return */ private TextBox createTextBox(String title,String text){ TextBox textBox = new TextBox(title,text,200,TextField.ANY); textBox.addCommand(cmdBack); textBox.setCommandListener(this); return textBox; } /** * 各個窗體事件 */ public void commandAction(Command command, Displayable displayable) { if(command == cmdEnter){ if(displayable.equals(list)){ curBookIndex = list.getSelectedIndex(); form = createForm(curBookIndex); display.setCurrent(form); } }else if(command == cmdBack){ if(displayable.equals(form)){ display.setCurrent(list); }else if(displayable.equals(textBox)){ form = createForm(curBookIndex); display.setCurrent(form); } }else if(command == cmdExit){ notifyDestroyed(); destroyApp(true); } } /** * 得到當前所選的詩詞索引號 * @param indexText * @return */ public int getIndex(String indexText){ for(int i=0; i<text[curBookIndex].length/3; i++){ if(indexText.equals(text[curBookIndex][i*3+0])) return i; } return -1; } /** * ItemCommandListener事件,顯示當前所選詩詞的內容 */ public void commandAction(Command command, Item item) { if(command == cmdEnter){ int num = getIndex(item.getLabel()); if(num == -1) return; textbox = createTextBox(text[curBookIndex][num*3+0]+text [curBookIndex][num*3+1], text[curBookIndex][num*3+1]+text[curBookIndex][num*3+2]); display.setCurrent(textBox); } } }
執行效果如圖3-33所示。

圖3-33 電子書效果圖
3.6.6 字母拼圖
1.游戲功能
啟動界面出現4×4的字母塊,單擊“開始”按鈕,將字母塊打亂,通過上、下、左、右方向鍵將字母塊拼回到起始界面,顯示勝利的信息。
2.程序的構成
整個程序由3個類構成,分別是:
·mainMidlet類:程序的入口,調用MyCanvas對象;
·StringBlock類:定義字母塊的結構,包括坐標,字母內容及是否反顯;
·myCanvas類:程序的主要類,實現字母的初始化、字母的顯示、鍵盤響應、字母的移動。
(1)mainMidlet類。
import javax.microedition.lcdui.Display; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; public class mainMidlet extends MIDlet { private static mainMidlet instance; public mainMidlet() { instance=this; } protected void destroyApp(boolean arg0) { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { Display.getDisplay(this).setCurrent(new myCanvas()); } public static void quit(){ instance.destroyApp(false); instance.notifyDestroyed(); instance=null; } }
(2)StringBlock類。
public class StringBlock { int ox,oy; int x,y; char word; boolean inv; }
(3)myCanvas類。
import java.util.Random; import javax.microedition.lcdui.*; //Canvas類的子類,負責手機畫面的內容和響應邏輯 public class myCanvas extends Canvas implements Runnable, CommandListener { int scrW,scrH; //屏幕的寬和高 Thread th; //線程類 StringBlock sb[],blank; //字母塊及空白塊 boolean winstate; //是否勝利 /* * 負責初始化變量 */ public myCanvas() { scrW=getWidth(); scrH=getHeight(); String sbstring="J2MEJAVAVC++SQL "; sb=new StringBlock[16]; //利用循環生成4×4的字母塊 for(int i=0;i<16;i++){ sb[i]=new StringBlock(); sb[i].ox=i%4; //字母塊的行數 sb[i].oy=i/4; //字母塊的列數 sb[i].x=sb[i].ox; sb[i].y=sb[i].oy; if(sb[i].oy>=2) sb[i].inv=true; else sb[i].inv=false; sb[i].word=sbstring.charAt(i); } blank=sb[15]; blank.inv=false; winstate=false; addCommand(new Command("Exit",Command.EXIT,1)); addCommand(new Command("Start",Command.OK,1)); setCommandListener(this); th=new Thread(this); } /* * 負責繪制屏幕內容 */ protected void paint(Graphics g) { //清屏三句話 g.setColor(255,255,255); g.fillRect(0,0,scrW,scrH); g.setColor(0); //具體繪制內容 Font ft=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font. SIZE_MEDIUM); int wordw=ft.charWidth('M'); int wordh=ft.getHeight(); int pad=4; int gpad=2; int allw=(wordw+pad*2)*4+gpad*5; int allh=(wordh+pad*2)*4+gpad*5; //繪制外框線 g.setColor(0); g.drawRect((scrW-allw)/2, (scrH-allh)/2, allw,allh); //繪制具體內容 int x,y,dx,dy; for(int i=0;i<16;i++){ x=sb[i].x;y=sb[i].y; dx=(scrW-allw)/2+(x+1)*gpad+x*(wordw+pad*2); dy=(scrH-allh)/2+(y+1)*gpad+y*(wordh+pad*2); if(sb[i].inv){ g.setColor(0); g.fillRect(dx,dy,wordw+pad*2,wordh+pad*2); dx+=pad; dy+=pad; g.setColor(0xffffff); g.drawChar(sb[i].word,dx,dy,20); } else { g.setColor(0); g.drawRect(dx,dy,wordw+pad*2,wordh+pad*2); dx+=pad; dy+=pad; g.drawChar(sb[i].word,dx,dy,20); } } //當勝利時繪制勝利信息 if(winstate){ g.setColor(0xff); g.drawString("You Win!",scrW/2,scrH-20,20); } } /* * 負責鍵盤響應 */ protected void keyPressed(int key) { //把輸入的鍵盤碼轉換成游戲碼 int k=getGameAction(key); //對轉換的游戲碼進行分析 switch(k) { case UP: //如果是按下向上鍵有什么反應 moveBlock(0); break; case DOWN: moveBlock(1); break; case LEFT: moveBlock(2); break; case RIGHT: moveBlock(3); break; } if(isSolved()) winstate=true; repaint(); //千萬不要忘了重繪命令 } //判斷是否所有字母塊都歸位 private boolean isSolved() { int i=0; while(i<16) { if((sb[i].ox==sb[i].x)&&sb[i].oy==sb[i].y) i++; else return false; } return true; } //移動字母塊,根據方向讓字母塊和空白塊交換 private void moveBlock(int i) { StringBlock temp = null; switch(i){ case 0: temp=findBlock(blank.x,blank.y+1); break; case 1: temp=findBlock(blank.x,blank.y-1); break; case 2: temp=findBlock(blank.x+1,blank.y); break; case 3: temp=findBlock(blank.x-1,blank.y); break; } if(temp==null)return; swapblock(temp,blank); } private void swapblock(StringBlock a, StringBlock b) { int x,y; x=a.x; y=a.y; a.x=b.x; a.y=b.y; b.x=x; b.y=y; } private StringBlock findBlock(int x, int y) { StringBlock temp=null; for(int i=0;i<16;i++) { if(sb[i].x==x&&sb[i].y==y) { temp=sb[i]; break; } } return temp; } public void run() { while(true){ repaint(); try { Thread.sleep(200); } catch (InterruptedException e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } } } public void commandAction(Command cmd, Displayable arg1) { switch(cmd.getCommandType()) { case Command.EXIT: mainMidlet.quit(); break; case Command.OK: winstate=false; daluan(); break; } } //將字母塊的順序打亂 private void daluan() { int j; Random rd=new Random(); StringBlock temp; for(int i=0;i<140;i++){ j=Math.abs(rd.nextInt())%4; moveBlock(j); } while(blank.x<3) moveBlock(2); while(blank.y<3) moveBlock(0); repaint(); } }
3.執行效果如圖3-34所示

圖3-34 字母拼圖效果圖
- 電力自動化實用技術問答
- 智能傳感器技術與應用
- Drupal 7 Multilingual Sites
- TIBCO Spotfire:A Comprehensive Primer(Second Edition)
- WOW!Illustrator CS6完全自學寶典
- 來吧!帶你玩轉Excel VBA
- 數控銑削(加工中心)編程與加工
- Mastering Elastic Stack
- 具比例時滯遞歸神經網絡的穩定性及其仿真與應用
- Ruby on Rails敏捷開發最佳實踐
- PVCBOT機器人控制技術入門
- 人工智能:語言智能處理
- 中文版Photoshop情境實訓教程
- Getting Started with Tableau 2019.2
- 單片機原理、應用與PROTEUS仿真