基于java的連連看游戲_第1頁
基于java的連連看游戲_第2頁
基于java的連連看游戲_第3頁
基于java的連連看游戲_第4頁
基于java的連連看游戲_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

基于JAVA的《連連看》游戲一引言《連連看》游戲在網(wǎng)上種類非常多,比如《水果連連看》,《寵物連連看》等等,雖然版本各種各樣,但是其基本玩法,或者說基本算法是相同的,就是顯示一些圖標(biāo),讓用戶依次去點擊兩個圖標(biāo),如果這兩個圖標(biāo)相同,并且這兩個圖標(biāo)通過直線可以相連,或者通過直角相連,或者通過雙折線相連就可以消掉,消掉所有圖標(biāo)即為勝利。如圖1所示:圖SEQ圖表\*ARABIC1正在進(jìn)行中的連連看游戲通過該游戲的制作,我們可以對Java的基礎(chǔ)語法、Java圖形界面以及簡單的算法設(shè)計有一個比較全面的了解。二設(shè)計要求為了避免敘述的繁瑣,我們只實現(xiàn)連連看游戲的基本功能,如下:制作如圖1所示的游戲界面,盡量做到美觀大方,使用方便當(dāng)兩個圖標(biāo)相同,且通過直線相連、直角相連、雙折線相連時,能夠消掉圖標(biāo)能夠讓游戲隨時暫停,然后繼續(xù)當(dāng)游戲進(jìn)行到一定程度,無法消除剩余圖標(biāo)時,要能夠提供重排功能對圖標(biāo)進(jìn)行重排,從而讓游戲繼續(xù)進(jìn)行三實現(xiàn)思路我們先講一下程序中的幾個難點,主要是說清楚具體的實現(xiàn)思路,具體的代碼會在文后給出,大家可以參考。界面設(shè)計需要實現(xiàn)如圖2所示的界面:圖SEQ圖表\*ARABIC2連連游戲界面整個界面分為三個區(qū)域:菜單區(qū)、功能區(qū)、游戲區(qū)。首先在窗體上放置三個面板JPanel,分別存放三個區(qū)域,如圖3所示:圖SEQ圖表\*ARABIC3界面的設(shè)計系統(tǒng)菜單區(qū)放置菜單即可,用戶游戲區(qū)放置一個8*9的按鈕數(shù)組來構(gòu)成游戲界面,用戶交互區(qū)放置開始,暫停等功能按鈕以及提示信息。生成游戲區(qū)運行程序后,游戲區(qū)并不顯示按鈕數(shù)組,當(dāng)點擊開始按鈕后,再自動生成。在生成按鈕時要求按鈕上的圖案是隨機(jī)的,且每個圖案必須是偶數(shù),否則會出現(xiàn)無法消除的按鈕。如何實現(xiàn)呢?我們可以這樣考慮:假設(shè)有12個圖片,把圖片名字按照數(shù)字序號從0到11命名;假設(shè)游戲區(qū)共72個按鈕,那么產(chǎn)生36個12以內(nèi)的隨機(jī)數(shù)字(每個隨機(jī)數(shù)字代表一個圖片),放入一個ArrayList中,最后使用ArrayList的addAll方法對已經(jīng)產(chǎn)生的36個隨機(jī)數(shù)字復(fù)制一份,這樣就獲得了72個隨機(jī)數(shù)字,并且是成對的。因為一個數(shù)字對應(yīng)一個圖片,所以72個按鈕需要的圖片就生成了。代碼如下:Randomrandom=newRandom();intimagenum=ROW*COL;for(inti=0;i<imagenum/2;i++){ imageIndex.add(random.nextInt(12)+"");//生成隨機(jī)數(shù)索引放入集合} imageIndex.addAll(imageIndex);//連接集合使每個索引都是成偶數(shù)的聯(lián)通消除點擊相連且圖片相同的兩個按鈕可以把兩個按鈕消除掉。相連有三種情況:直線相連,直角相連,雙折線相連。要消掉相同圖標(biāo)的按鈕,首先要想辦法判斷兩個按鈕的圖標(biāo)是否相同,這里提示大家一個方法:按鈕有個setActionCommand方法和getActionCommand,把圖標(biāo)名字設(shè)置為一個按鈕的ActionCommand,然后通過對比兩個按鈕的ActionCommand就可以知道是否具有相同的圖標(biāo)。消除按鈕就要判斷兩個按鈕是否連通,連通有三種情況,對應(yīng)三種算法,下面詳細(xì)說明。算法判斷兩個點是否連通,那如何跟兩個按鈕建立聯(lián)系呢?按鈕的位置就可以視作一個點(java中用Point類表示一個點)。這樣用一個點代表按鈕位置,用ActionCommand代表按鈕上的圖標(biāo)。就很容易操作了。下面我們先說清楚實現(xiàn)原理,具體代碼一會在給出。(1)直線相連:只要兩點之間橫坐標(biāo)或縱坐標(biāo)相同,即表示兩點在同行或同列;然后判斷兩點之間有沒有障礙,無則聯(lián)通。(2)直角相連:兩個點的坐標(biāo)可以生成一個新的點,如果兩點都可以與該新點聯(lián)通,則說明聯(lián)通。注意:新點有兩個,如圖所示一個,另外喇叭圖標(biāo)處也可以生成一個,但是因為喇叭圖標(biāo)處不是空點,因此不用該點。但在實際中,新點的兩種可能都要考慮到,那個能用用那個。(3)雙折線相連:在單擊的第一點處,向四個方向搜索有無空點,如果有則生成一個新點,如果該新點與另一個按鈕聯(lián)通(直角聯(lián)通),則說明聯(lián)通。如果該新點不能與按鈕連通,則繼續(xù)向該新點的方向前進(jìn)一個位置,再次判斷該位置是否為空點,是否可以和另一個按鈕連通,以此類推。重排當(dāng)游戲進(jìn)行到一定程度,剩余的按鈕無法消掉,這時就需要對按鈕位置進(jìn)行重新排列,從而讓游戲繼續(xù)進(jìn)行。解決這一問題的思路如下:首先對所有按鈕進(jìn)行搜索,把剩余按鈕的ActionCommand(ActionCommand和該按鈕顯示的圖片序號一致,如果按鈕被消掉則ActionCommand為空)放入一個集合內(nèi);然后依次搜索剩余按鈕,找到一個剩余按鈕后,保持按鈕的位置不動,從集合中隨機(jī)取出一個ActionCommand賦給該按鈕,這樣就完成了對剩余按鈕的重排。四具體實現(xiàn)打開Eclipse,新建一個類LinkGame,該類繼承自JFrame,并且需要實現(xiàn)ActionListener方法。publicclassLinkGameextendsJFrameimplementsActionListener{}在該類中添加如下變量和方法,見表1和表2。表SEQ表格\*ARABIC1LinkGame類中的成員變量變量類型變量名說明finalstaticintROW游戲區(qū)8行9列共72個按鈕finalstaticintCOLJPanelfunctionPanel功能區(qū)面板JPanelgamePanel游戲區(qū)面板JButton[][]dots按鈕數(shù)組JLabeltimestr內(nèi)容是“剩余時間”JLabeltimecount計時TimertimerJButtonstart開始按鈕JButtonpause暫停JButtonconti繼續(xù)JButtonhint重排staticintcount記錄鼠標(biāo)單擊次數(shù)staticinttime記錄游戲剩余時間Pointp1,p2保存兩個被單擊按鈕的坐標(biāo)LinkedList<Point>list按鈕坐標(biāo)集合ArrayList<String>imageIndex存放圖像索引LinkedList<String>linklist重排時存放按鈕表SEQ表格\*ARABIC2LinkGame類中的方法方法名方法功能publicvoidaddmyMenu()添加菜單 publicvoidaddFunctionPanel()添加功能區(qū) publicvoidaddGamePanel()添加游戲區(qū) privateclassButtonEventsimplementsActionListener游戲區(qū)按鈕被單擊publicbooleanlineCheck(Pointp1,Pointp2)是否直線聯(lián)通 publicbooleansecendLine(Pointp1,Pointp2)是否直角聯(lián)通 publicbooleantriLine(Pointp1,Pointp2)是否雙折線聯(lián)通publicvoidreSet()當(dāng)剩余按鈕無法消除時進(jìn)行重排 publicvoidactionPerformed(ActionEvente)功能區(qū)按鈕被單擊時上述方法的具體實現(xiàn)如下:1、構(gòu)造方法//構(gòu)造方法建立游戲界面 publicLinkGame(){ this.setSize(780,500); this.setTitle("連連看游戲"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addmyMenu();//添加菜單 addFunctionPanel();//添加功能區(qū) this.setVisible(true); }2、菜單菜單的功能均沒有實現(xiàn),讀者可以自行添加。//添加菜單 publicvoidaddmyMenu(){ JMenuBarmenuBar=newJMenuBar(); this.setJMenuBar(menuBar); JMenumenuGame=newJMenu("游戲"); JMenumenuSet=newJMenu("設(shè)置"); JMenumenuHelp=newJMenu("幫助"); menuBar.add(menuGame); menuBar.add(menuSet); menuBar.add(menuHelp); menuGame.add(newJMenuItem("打開")); menuGame.add(newJMenuItem("保存")); menuGame.add(newJMenuItem("退出")); menuSet.add(newJCheckBoxMenuItem("音樂開關(guān)")); JMenuchoice=newJMenu("難度選擇"); menuSet.add(choice); menuSet.add(newJMenuItem("背景色")); menuSet.add(newJMenuItem("提示")); menuHelp.add(newJMenuItem("關(guān)于",newImageIcon("image/2.gif"))); menuHelp.addSeparator(); menuHelp.add(newJMenuItem("幫助")); ButtonGroupgroup=newButtonGroup(); JRadioButtonMenuItemrbm1=newJRadioButtonMenuItem("初級難度"); JRadioButtonMenuItemrbm2=newJRadioButtonMenuItem("中級難度"); JRadioButtonMenuItemrbm3=newJRadioButtonMenuItem("高級難度"); group.add(rbm1); group.add(rbm2); group.add(rbm3); choice.add(rbm1); choice.add(rbm2); choice.add(rbm3); }3、功能區(qū)和游戲區(qū)的界面//添加功能區(qū) publicvoidaddFunctionPanel(){ start.setPreferredSize(newDimension(150,50)); pause.setPreferredSize(newDimension(150,50)); conti.setPreferredSize(newDimension(150,50)); hint.setPreferredSize(newDimension(150,50)); timecount.setPreferredSize(newDimension(150,50)); timestr.setPreferredSize(newDimension(150,50)); timestr.setFont(newFont("隸書",Font.BOLD,28)); timecount.setFont(newFont("隸書",Font.BOLD,28)); timecount.setForeground(Color.yellow); timestr.setForeground(Color.yellow); start.addActionListener(this); pause.addActionListener(this); conti.addActionListener(this); hint.addActionListener(this); functionPanel.setPreferredSize(newDimension(200,500)); functionPanel.setBackground(Color.BLUE); functionPanel.setLayout(newFlowLayout(FlowLayout.CENTER,5,20)); functionPanel.add(timestr); functionPanel.add(timecount); functionPanel.add(start); functionPanel.add(pause); functionPanel.add(conti); functionPanel.add(hint); this.add(functionPanel,BorderLayout.EAST); } //添加游戲區(qū) publicvoidaddGamePanel(){ gamePanel.setPreferredSize(newDimension(580,500)); gamePanel.setLayout(newGridLayout(ROW,COL)); gamePanel.setBackground(Color.RED); Randomrandom=newRandom(); intimagenum=ROW*COL; for(inti=0;i<imagenum/2;i++){ imageIndex.add(random.nextInt(12)+"");//生成隨機(jī)數(shù)索引放入集合 } imageIndex.addAll(imageIndex);//連接集合使每個索引都是成偶數(shù)的 intnum=0; //記錄從集合中取出的圖標(biāo)做引數(shù) for(inti=0;i<ROW;i++){ for(intj=0;j<COL;j++){ StringnewNumber=imageIndex.get(num++); dots[i][j]=newJButton("",newImageIcon("image/"+newNumber +".png")); dots[i][j].addActionListener(newButtonEvents());//事件監(jiān)聽注冊 dots[i][j].setActionCommand(newNumber);//設(shè)置按鈕的actioncommand名 gamePanel.add(dots[i][j]); } } this.add(gamePanel,BorderLayout.WEST); } 4、單擊游戲區(qū)按鈕激發(fā)的事件//事件類,監(jiān)聽按鈕單擊事件 privateclassButtonEventsimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ count++; for(inti=0;i<ROW;i++){ for(intj=0;j<COL;j++){ if(e.getSource()==dots[i][j]){ Pointp=newPoint(i,j);//單擊按鈕則把按鈕位置封入p中 list.add(p);//點p放入集合list中 } } } if(count%2==0){//如果是偶數(shù)次單擊按鈕 p1=list.getFirst();//從集合中取出代表兩個按鈕的點 p2=list.getLast(); //如果兩次點擊的是同一個按鈕 if(p1.x==p2.x&&p1.y==p2.y){ list.clear(); return; } //這兩個點是否可以消掉 if(lineCheck(p1,p2)||secendLine(p1,p2)||triLine(p1,p2)){ dots[p1.x][p1.y].setVisible(false); dots[p2.x][p2.y].setVisible(false); dots[p1.x][p1.y].setActionCommand(""); dots[p2.x][p2.y].setActionCommand(""); } list.clear();//清空集合 count=0; } } }5、判斷兩個按鈕相連的三種算法//是否直線聯(lián)通 publicbooleanlineCheck(Pointp1,Pointp2){ intabsDistance=0;//兩點之間的距離 intspaceCount=0;//兩點之間空按鈕的數(shù)量 //如果兩個按鈕的圖標(biāo)不相同 if(!dots[p1.x][p1.y].getActionCommand().equals( dots[p2.x][p2.y].getActionCommand())){ returnfalse; } if(p1.x==p2.x||p1.y==p2.y){ if(p1.x==p2.x&&p1.y!=p2.y){ //絕對距離(中間隔著的空格數(shù)) absDistance=Math.abs(p1.y-p2.y)-1; //正負(fù)值 intzf=(p1.y-p2.y)>0?-1:1; for(inti=1;i<=absDistance;i++){ if(dots[p1.x][p1.y+i*zf].getActionCommand().equals("")){ //空格數(shù)加1 spaceCount+=1; }else break;//遇到阻礙就不用再探測了 } }elseif(p1.y==p2.y&&p1.x!=p2.x){ absDistance=Math.abs(p1.x-p2.x)-1; intzf=(p1.x-p2.x)>0?-1:1; for(inti=1;i<=absDistance;i++){ if(dots[p1.x+i*zf][p1.y].getActionCommand().equals("")){ spaceCount+=1; }else break; } } if(spaceCount==absDistance){ //可聯(lián)通 returntrue; }else{ returnfalse; } }else{ //不是同行同列的情況所以直接返回false; returnfalse; } } //是否直角聯(lián)通 publicbooleansecendLine(Pointp1,Pointp2){ //第一個直角檢查點,如果這里為空則賦予相同值供檢查 PointcheckP1=newPoint(p1.x,p2.y); //第二個直角檢查點,如果這里為空則賦予相同值供檢查 PointcheckP2=newPoint(p2.x,p1.y); //第一個直角點檢測 if(dots[checkP1.x][checkP1.y].getActionCommand().equals("")){ dots[checkP1.x][checkP1.y].setActionCommand(dots[p1.x][p1.y] .getActionCommand()); if(this.lineCheck(p1,checkP1)&&this.lineCheck(checkP1,p2)){ dots[checkP1.x][checkP1.y].setActionCommand(""); returntrue; }else{ dots[checkP1.x][checkP1.y].setActionCommand(""); } } //第二個直角點檢測 if(dots[checkP2.x][checkP2.y].getActionCommand().equals("")){ dots[checkP2.x][checkP2.y].setActionCommand(dots[p2.x][p2.y] .getActionCommand()); if(this.lineCheck(p1,checkP2)&&this.lineCheck(checkP2,p2)){ dots[checkP2.x][checkP2.y].setActionCommand(""); returntrue; }else{ dots[checkP2.x][checkP2.y].setActionCommand(""); } } returnfalse; } //是否雙折線聯(lián)通 publicbooleantriLine(Pointp1,Pointp2){ inti; PointcheckP=newPoint(p1.x,p1.y); //四向探測開始 for(i=4-1;i>=0;i--){ checkP.x=p1.x; checkP.y=p1.y; //向右 if(i==3){ while((++checkP.x<dots.length) &&dots[checkP.x][checkP.y].getActionCommand().equals( "")){ dots[checkP.x][checkP.y].setActionCommand(dots[p1.x][p1.y] .getActionCommand()); if(secendLine(checkP,p2)){ dots[checkP.x][checkP.y].setActionCommand(""); returntrue; }else{ dots[checkP.x][checkP.y].setActionCommand(""); } } }//向下 elseif(i==2){ while((++checkP.y<dots[checkP.x].length) &&dots[checkP.x][checkP.y].getActionCommand().equals( "")){ dots[checkP.x][checkP.y].setActionCommand(dots[p1.x][p1.y] .getActionCommand()); if(secendLine(checkP,p2)){ dots[checkP.x][checkP.y].setActionCommand(""); returntrue; }else{ dots[checkP.x][checkP.y].setActionCommand(""); } } }//向左 elseif(i==1){ while((--checkP.x>=0) &&dots[checkP.x][checkP.y].getActionCommand().equals( "")){ dots[checkP.x][checkP.y].setActionCommand(dots[p1.x][p1.y] .getActionCommand()); if(secendLine(checkP,p2)){ dots[checkP.x][checkP.y].setActionCommand(""); returntrue; }else{ dots[checkP.x][checkP.y].setActionCommand(""); } } }//向上 elseif(i==0){ while((--checkP.y>=0) &&dots[checkP.x][checkP.y].getActionCommand().equals( "")){ dots[checkP.x][checkP.y].setActionCommand(dots[p1.x][p1.y] .getActionCommand()); if(secendLine(checkP,p2)){ dots[checkP.x][checkP.y].setActionCommand(""); returntrue; }e

溫馨提示

  • 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

提交評論