幫助界面
幫助界面很簡單,把需要的文字排好寬度放在一個String數組里,然后繪制在屏幕上,假如一屏放不下就增加按鍵響應來翻屏,其實只是重新畫出數組前面或后面的幾個值,源代碼如下:
在MiningCanvas.java中添加如下代碼final String[] strGamehelp =new String[10];public MiningCanvas(MiningMIDlet miningMIDlet){ ... strGamehelp[0]="此PRivate void paintHelpScreen(Graphics g){ g.setColor(0x00FFFFFF); g.fillRect(0,0,canvasW,canvasH); g.setFont(lowFont); g.setColor(0x00000000); for(int i=0;i<strGamehelp.length;i++){ g.drawString(strGamehelp[i],5,5+(lowFont.getHeight()+3)*i,Graphics.TOPGraphics.LEFT); }}在keyPressed方法中的switch結構中添加case GAMESTATE_HELP://假如游戲現在的狀態為幫助狀態,那個不管玩家按哪個鍵都會跳轉到主菜單狀態 gamestate=GAMESTATE_MENU; break;
游戲主界面
主界面的繪制分成幾個部分,一個是雷區棋盤的繪制,根據雷區二位數組中的每一個Bomb對象中的變量值繪出整個棋盤,假如hasFound值為false,畫出
;假如hasFound值為true且isBomb值為false,那么會畫出這個雷位四周的雷數
、
、
、
、
、
、
;假如hasFound值為true且isBomb值為true,那么會畫出這個雷位是哪一個玩家所挖出的,分別是
和
。第二個部分是玩家的選擇框。第三個部分是游戲的信息框,也就是兩個玩家目前的分值,還剩幾顆雷,信息框的圖片為
。最后一個部分是提示當前輪到哪一個玩家掃雷,在雷區的外框用玩家的顏色提示,和在信息框中畫出玩家的旗幟
和
。
這里有幾個注重點:
1.雷區不能全部在屏幕中畫下,所以會通過卷軸滾動。整個雷區是16x16,我們的屏幕預備畫出10x12,用兩個變量(paintX和paintY)來控制當前要畫出的雷區左上角的雷位坐標,例如這兩個變量的值分別為3和4,那么會畫出橫軸3-10,縱軸4-13的雷位,選擇框的坐標(selectedX和selectedY)不用擔心,當他超出了屏幕,只需要增加或減少paintX和paintY的值即可,只要保證選擇框的坐標和paintX/Y坐標值得距離不超過9(10-1)和11(12-1)即可。這里要十分小心的是,我們這里所有的坐標值和雷區的二位數組bombs中的坐標正好相反,也就是選擇框(5,6)是類位bombs[6][5]。
2.在創建雷區二維Bomb數組時,二位數組的大小是18x18(new Bomb[miningMapGrid+2][miningMapGrid+2]),目的是在大小16x16的真正雷區外加一圈雷位,以避免bombOut()方法和其他需要周邊搜索雷位時不會出現超越邊界異常。
3.因為bombs數組中的索引1-16才是真正代表雷區中坐標(1,1)至(16,16)的雷位,所以在整個程序中,所有有關坐標和數組索引值的地方都要十分小心,不要出現位置錯誤
4.消息框中需要繪制的幾個數值的坐標變量(Player1X/Y,Player2X/Y,bombnowX/Y)的值都是相對于整個消息框的左上角的相對坐標,我們也可以為消息框的坐標單獨定義一對變量,這樣就更清楚了。
源代碼如下:
在MiningCanvas.java中添加如下代碼int empty;static final int miningMapGrid=16;//雷區為16格x16格static final int bombNum=52;//共有52顆雷int miningMapLength,miningGridLength;//整個雷區的邊長,每一個雷位格子的邊長int miningMapX,miningMapY;//雷區的左上角坐標int selectedX,selectedY;//選擇框的坐標,是在雷區里的坐標(1-16)int player1Found,player2Found;//兩個玩家的分值,即已經找到的雷數int paintX,paintY;//要畫出的區域的左上角坐標,是在雷區里的坐標(1-16)int bombLeft;//剩下未掃出的雷數static final int Player1X=10,Player1Y=30;//信息框中畫出玩家一分數的坐標位置,相對于信息框左上角static final int Player2X=10,Player2Y=90;//信息框中畫出玩家二分數的坐標位置,相對于信息框左上角static final int bombnowX=8,bombnowY=52;//信息框中畫出剩余雷數的坐標位置,相對于信息框左上角static final int bombMapW=10,bombMapH=12;//屏幕上能繪出的雷位的數量Bomb[][] bombs;boolean isPlayer1;//當前是否輪到玩家一掃雷Alert winAlert;//顯示輸贏信息的Alert對象String winString;//比出輸贏后要輸出的信息boolean sbWon;//是否得出輸贏static final Font font = Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font.SIZE_SMALL); //消息框中使用的字體Image infoImg,splashImage;Image unFoundGroundImg;Image foundGroundImg;Image player1BombImg,player2BombImg,player1TurnImg,player2TurnImg;Image bomb1Img,bomb2Img,bomb3Img,bomb4Img,bomb5Img,bomb6Img,bomb7Img,bomb8Img; //所有要用到的圖片public MiningCanvas(MiningMIDlet miningMIDlet){ ... try{//實例化游戲中需要的Image對象 unFoundGroundImg=Image.createImage("/unfoundGroundbig.png"); foundGroundImg=Image.createImage("/foundGroundbig.png"); player1BombImg=Image.createImage("/player1bombbig.png"); player2BombImg=Image.createImage("/player2bombbig.png"); bomb1Img=Image.createImage("/bomb1big.png"); bomb2Img=Image.createImage("/bomb2big.png"); bomb3Img=Image.createImage("/bomb3big.png"); bomb4Img=Image.createImage("/bomb4big.png"); bomb5Img=Image.createImage("/bomb5big.png"); bomb6Img=Image.createImage("/bomb6big.png"); infoImg=Image.createImage("/info.png"); splashImage=Image.createImage("/occo.png"); player1TurnImg=Image.createImage("/player1turn.png"); player2TurnImg=Image.createImage("/player2turn.png"); }catch(IOException e){} isPlayer1=true;//初始化玩家先后順序 miningGridLength=14;//初始化每一個雷位的邊長 miningMapLength=14*12;//整個掃雷棋盤的邊長 miningMapX=(canvasW-miningMapLength)/2;//屏幕上棋盤左上角的X坐標 miningMapY=(canvasH-miningMapLength)/2;//屏幕上棋盤左上角的Y坐標 selectedX=selectedY=miningMapGrid/2;//初始化選擇框的坐標為 player1Found=player2Found=0;//初始化兩個玩家的得分 paintX=paintY=3;//初始化整個雷區一開始在屏幕上顯示的范圍 sbWon=false;//初始化沒有玩家獲勝 bombLeft=bombNum;//初始化剩余雷數為總雷數 bombs=new Bomb[miningMapGrid+2][miningMapGrid+2]; bombInit();//初始化雷區 }private void paintGameScreen(Graphics g){ paintPlayer(g,isPlayer1); paintMiningMap(g); paintInfo(g); paintSelected(g);}protected void paintInfo(Graphics g){ g.drawImage(infoImg,miningMapX+bombMapW*miningGridLength+1, miningMapY,Graphics.TOPGraphics.LEFT); g.setFont(font); g.setColor(0x00FFFFFF); g.drawString(String.valueOf(bombLeft),miningMapX+bombMapW*miningGridLength+bombnowX, miningMapY+bombnowY,Graphics.TOPGraphics.LEFT); g.drawString(String.valueOf(player1Found),miningMapX+bombMapW*miningGridLength+Player1X, miningMapY+Player1Y,Graphics.TOPGraphics.LEFT); g.drawString(String.valueOf(player2Found),miningMapX+bombMapW*miningGridLength+Player2X, miningMapY+Player2Y,Graphics.TOPGraphics.LEFT); //這個方法中接下來的代碼是用來在信息框中畫出小地圖,也就是屏幕上顯示的地雷區域在整個雷區 中的位置 g.setColor(0x00777777); g.fillRect(miningMapX+bombMapW*miningGridLength+1,miningMapY+8*miningGridLength+1, 2*miningGridLength-2,2*miningGridLength-1); g.setColor(0x00000000); g.drawRect(miningMapX+bombMapW*miningGridLength+1,miningMapY+8*miningGridLength+1, 2*miningGridLength-2,2*miningGridLength-1); g.setColor(0x00BBBBBB); g.fillRect(miningMapX+bombMapW*miningGridLength+4+2*(paintX-1), miningMapY+8*miningGridLength+4+2*(paintY-1),12,17); g.setColor(0x00FFFFFF); g.drawRect(miningMapX+bombMapW*miningGridLength+4+2*(paintX-1), miningMapY+8*miningGridLength+4+2*(paintY-1),12,17);}protected void paintPlayer(Graphics g,boolean isPlayer1){ if(isPlayer1)//在棋盤外圍畫出玩家顏色的外框 g.setColor(0x000000FF); else g.setColor(0x00FF0000); for(int i=1;i<=5;i++){ g.drawRect(miningMapX-i,miningMapY-i,miningMapLength+2*i,miningMapLength+2*i); } if(isPlayer1)//在信息框中畫出代表玩家的旗幟 g.drawImage(player1TurnImg,miningMapX+(bombMapW+1)*miningGridLength+1, miningMapY+11*miningGridLength,Graphics.HCENTERGraphics.VCENTER); else g.drawImage(player2TurnImg,miningMapX+(bombMapW+1)*miningGridLength+1, miningMapY+11*miningGridLength,Graphics.HCENTERGraphics.VCENTER);}public void paintMiningMap(Graphics g){ for(int i=0;i<bombMapH;i++){ for(int j=0;j<bombMapW;j++){//根據每個Bomb對象中的變量值畫出不同的圖片 if(!bombs[i+paintY+1][j+paintX+1].hasFound){ g.drawImage(unFoundGroundImg,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); } else { if(!bombs[i+paintY+1][j+paintX+1].isBomb){ switch(bombs[i+paintY+1][j+paintX+1].bombaround){ case 0: g.drawImage(foundGroundImg,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 1: g.drawImage(bomb1Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 2: g.drawImage(bomb2Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 3: g.drawImage(bomb3Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 4: g.drawImage(bomb4Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 5: g.drawImage(bomb5Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; case 6: g.drawImage(bomb6Img,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; default: g.drawImage(foundGroundImg,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); break; } } else { if(bombs[i+paintY+1][j+paintX+1].isPlayer1){ g.drawImage(player1BombImg,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); } else{ g.drawImage(player2BombImg,miningMapX+j*miningGridLength, miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT); } } } } }}public void paintSelected(Graphics g){ g.setColor(0x00FF0000);//畫出選擇框,注重其與總雷區和能在屏幕上顯示出的區域間的關系 g.drawRoundRect(miningMapX+(selectedX-paintX)*miningGridLength-1, miningMapY+(selectedY-paintY)*miningGridLength-1, miningGridLength+1,miningGridLength+1,2,2);}在keyPressed方法中的switch結構中添加case GAMESTATE_GAMEING:{ if(keyCode==FullCanvas.KEY_SOFTKEY1){ gamestate=GAMESTATE_GAMEMENU; } else if (action == FullCanvas.LEFT ) { selectedX=(--selectedX+miningMapGrid)%(miningMapGrid); } else if (action == FullCanvas.RIGHT) { selectedX=(++selectedX)%(miningMapGrid); } else if (action == FullCanvas.UP) { selectedY=(--selectedY+miningMapGrid)%(miningMapGrid); } else if (action == FullCanvas.DOWN) { selectedY=(++selectedY)%(miningMapGrid); } else if (action == FullCanvas.FIRE) { if(!bombs[selectedY+1][selectedX+1].hasFound){ if(bombs[selectedY+1][selectedX+1].isBomb){ bombs[selectedY+1][selectedX+1].hasFound=true; bombs[selectedY+1][selectedX+1].isPlayer1=this.isPlayer1; if(isPlayer1) player1Found++; else player2Found++; bombLeft--; checkWin();//每次有玩家挖到了雷就監測其是否勝出 } else{ bombOut(selectedY+1,selectedX+1); //假如此雷位及四周都無雷,打開所有與其相連的相同情況的雷位及此區域周邊一圈雷位 isPlayer1=!isPlayer1; } } } //以下幾行代碼是調整顯示在屏幕上的區域的坐標,以免選擇框跑出屏幕范圍 if((selectedX-paintX)<0) paintX=selectedX; else if((selectedX-paintX)>=bombMapW) paintX=selectedX-bombMapW+1; if((selectedY-paintY)<0) paintY=selectedY; else if((selectedY-paintY)>=bombMapH) paintY=selectedY-bombMapH+1; break;}
新聞熱點
疑難解答