1. 人員分工
組員 | 職務(wù) | 分工 |
---|---|---|
潘鋆祥 | 組長(zhǎng) | 頂層格子的代碼設(shè)計(jì),界面UI設(shè)計(jì) |
覃小杰 | 組員 | 掃雷素材的搜集,底層雷的代碼設(shè)計(jì) |
2.前期調(diào)查
游戲詳情
以windows 7自帶掃雷為例。游戲區(qū)包括雷區(qū)、地雷計(jì)數(shù)器和計(jì)時(shí)器,確定大小的矩形雷區(qū)中隨機(jī)布置一定數(shù)量的地雷(初級(jí)為99個(gè)方塊10個(gè)雷,中級(jí)為1616個(gè)方塊40個(gè)雷,高級(jí)為16*30個(gè)方塊99個(gè)雷),玩家需要盡快找出雷區(qū)中的所有不是地雷的方塊,而不許踩到地雷。
游戲的基本操作包括左鍵單擊、右鍵單擊、雙擊三種。其中左鍵用于打開(kāi)安全的格子,推進(jìn)游戲進(jìn)度;右鍵用于標(biāo)記地雷,以輔助判斷,或?yàn)榻酉聛?lái)的雙擊做準(zhǔn)備;雙擊在一個(gè)數(shù)字周?chē)牡乩讟?biāo)記完時(shí),相當(dāng)于對(duì)數(shù)字周?chē)创蜷_(kāi)的方塊均進(jìn)行一次左鍵單擊操作:
左鍵單擊:
在判斷出不是雷的方塊上按下左鍵,可以打開(kāi)該方塊。如果方塊上出現(xiàn)數(shù)字,則該數(shù)字表示其周?chē)?×3區(qū)域中的地雷數(shù)(一般為8個(gè)格子,對(duì)于邊塊為5個(gè)格子,對(duì)于角塊為3個(gè)格子。所以掃雷中最大的數(shù)字為8);如果方塊上為空(相當(dāng)于0),則可以遞歸地打開(kāi)與空相鄰的方塊;如果不幸觸雷,則游戲結(jié)束。
右鍵單擊:
在判斷為地雷的方塊上按下右鍵,可以標(biāo)記地雷(顯示為小紅旗)。重復(fù)操作可取消標(biāo)記
雙擊:
同時(shí)按下左鍵和右鍵完成雙擊。當(dāng)雙擊位置周?chē)褬?biāo)記雷數(shù)等于該位置數(shù)字時(shí)操作有效,相當(dāng)于對(duì)該數(shù)字周?chē)创蜷_(kāi)的方塊均進(jìn)行一次左鍵單擊操作。地雷未標(biāo)記完全時(shí)使用雙擊無(wú)效。若數(shù)字周?chē)袠?biāo)錯(cuò)的地雷,則游戲結(jié)束,標(biāo)錯(cuò)的地雷上會(huì)顯示一個(gè)“ ×”。
3.需求分析
3.1系統(tǒng)數(shù)據(jù)分析
掃雷雷區(qū)是一個(gè)二維區(qū)間,所以需要一個(gè)二維數(shù)組進(jìn)行存儲(chǔ)數(shù)據(jù),而其中又分為了底層跟上層,底層用于存儲(chǔ)雷跟數(shù)字,上層用于翻開(kāi)格子,插旗等操作。
若翻開(kāi)的格子下是雷,則判定失敗;若全局中未翻開(kāi)的格子數(shù)(包括插旗的格子)等于雷數(shù),則默認(rèn)將所有未翻開(kāi)的格子插旗,且判定勝利。
3.2系統(tǒng)操作分析
進(jìn)行左鍵右鍵操作的時(shí)候,我們需要對(duì)鼠標(biāo)進(jìn)行監(jiān)聽(tīng),若鼠標(biāo)左鍵或右鍵點(diǎn)擊,則讀取鼠標(biāo)的橫縱坐標(biāo),然后通過(guò)換算之后,換算成鼠標(biāo)點(diǎn)擊的對(duì)應(yīng)格子的二維數(shù)組坐標(biāo),然后在二維數(shù)組中對(duì)其進(jìn)行操作。因?yàn)殡p擊的操作過(guò)于繁瑣,我們用右鍵進(jìn)行替代,若右鍵點(diǎn)擊到的是已被翻開(kāi)的格子,則判定原本掃雷中的雙擊操作;若右鍵點(diǎn)擊的是未翻開(kāi)的格子,則進(jìn)行插旗操作。
3.3系統(tǒng)界面分析
需要有能進(jìn)行難度選擇的按鈕,難度選擇后能確確實(shí)實(shí)地改變雷數(shù)與格子數(shù),且窗口的大小能根據(jù)難度的變化進(jìn)行相應(yīng)的變大縮小,需要有能實(shí)時(shí)變化的地雷計(jì)數(shù)器和計(jì)時(shí)器,且能給與出隨時(shí)重置游戲的按鈕。
4.流程圖
5.游戲運(yùn)行截圖
難度選擇
簡(jiǎn)單難度
成功判定
失敗判定
普通難度
困難難度
6.關(guān)鍵代碼
主頁(yè)面代碼(包括鼠標(biāo)監(jiān)聽(tīng))
public class GameWin extends JFrame{
int wide = 2*GameUtil.offset + GameUtil.wide*GameUtil.squareLength;
int high = 2*GameUtil.offset + GameUtil.high*GameUtil.squareLength;
Image offScreenImage = null;
Map map = new Map();
MapTop mapTop = new MapTop();
GameSelect gameSelect = new GameSelect();
boolean begin=false;
void mainPage() {
GameUtil.start_time=System.currentTimeMillis();
this.setVisible(true);
if(GameUtil.state==3)
{
this.setSize(500,500);
}
else
{
this.setSize(wide,high);
}
this.setTitle("掃雷游戲");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
super.mouseClicked(e);
switch(GameUtil.state)
{
case 0: if(e.getButton()==1)
{
GameUtil.Mouse_x=e.getX();
GameUtil.Mouse_y=e.getY();
GameUtil.left = true;
}
if(e.getButton()==3)
{
GameUtil.Mouse_x=e.getX();
GameUtil.Mouse_y=e.getY();
GameUtil.right = true;
}
case 1:
case 2:
if(e.getButton()==1)
{
if(e.getX()>GameUtil.offset +GameUtil.squareLength*(GameUtil.wide/2)&&
e.getX()<GameUtil.offset +GameUtil.squareLength*(GameUtil.wide/2)+GameUtil.squareLength*2
&&e.getY()>GameUtil.offset/3
&&e.getY()<GameUtil.offset+GameUtil.squareLength)
{
map.reGame();
mapTop.reGame();
GameUtil.flag_num=0;
GameUtil.start_time=System.currentTimeMillis();
GameUtil.state =0;
}
}
break;
case 3:
if(e.getButton()==1)
{
GameUtil.Mouse_x=e.getX();
GameUtil.Mouse_y=e.getY();
begin = gameSelect.hard();
}
default :
}
}
});
while(true)
{
repaint();
begin();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
void begin()
{
if(begin)
{
begin=false;
gameSelect.hard(GameUtil.level);
dispose();
GameWin gameWin = new GameWin();
GameUtil.start_time = System.currentTimeMillis();
GameUtil.flag_num=0;
map.reGame();
mapTop.reGame();
gameWin.mainPage();
}
}
public void paint(Graphics g)
{
if(GameUtil.state==3)
{
g.setColor(Color.white);
g.fillRect(0,0,500,500);
gameSelect.paintSelf(g);
}
else
{
offScreenImage = this.createImage(wide,high);
Graphics gImage = offScreenImage.getGraphics();
map.paintMap(gImage);
mapTop.paintMap(gImage);
g.drawImage(offScreenImage,0,0,null);
}
}
public static void main(String[] args)
{
GameWin gameWin = new GameWin();
gameWin.mainPage();
}
}
底層雷區(qū)繪制文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-770668.html
public class Map {
BottomMine bottomMine = new BottomMine();
BottomNum bottomNum = new BottomNum();
{
bottomMine.newMines();
bottomNum.newNum();
}
void reGame()
{
for(int i = 1;i <=GameUtil.wide;i++)
{
for(int j = 1; j<=GameUtil.high; j++)
{
GameUtil.bottom[i][j]=0;
}
}
bottomMine.newMines();
bottomNum.newNum();
}
void paintMap(Graphics g)
{
for(int i=0;i<=GameUtil.wide;i++)
{
g.setColor(Color.white);
g.drawLine(GameUtil.offset+i*GameUtil.squareLength,
GameUtil.offset,
GameUtil.offset+i*GameUtil.squareLength,
GameUtil.offset+GameUtil.high*GameUtil.squareLength);
}
for(int i = 0;i<=GameUtil.high;i++)
{
g.setColor(Color.white);
g.drawLine(GameUtil.offset,
GameUtil.offset+i*GameUtil.squareLength,
GameUtil.offset+GameUtil.wide*GameUtil.squareLength,
GameUtil.offset+i*GameUtil.squareLength);
}
for(int i = 1;i<=GameUtil.wide;i++)
{
for(int j=1;j<=GameUtil.high;j++)
{
if(GameUtil.bottom[i][j]==-1) {
g.drawImage(GameUtil.Mine,
GameUtil.offset+(i-1)*GameUtil.squareLength+1,
GameUtil.offset+(j-1)*GameUtil.squareLength+1,
GameUtil.squareLength-2,
GameUtil.squareLength-2,
null);
}
if(GameUtil.bottom[i][j]>=0) {
g.drawImage(GameUtil.images[GameUtil.bottom[i][j]],
GameUtil.offset+(i-1)*GameUtil.squareLength+1,
GameUtil.offset+(j-1)*GameUtil.squareLength+1,
GameUtil.squareLength-2,
GameUtil.squareLength-2,
null);
}
}
}
GameUtil.drawWord(g, ""+(GameUtil.Mine_max-GameUtil.flag_num), GameUtil.offset+GameUtil.squareLength*(GameUtil.wide-1),
GameUtil.offset/2, 30, Color.black);
GameUtil.drawWord(g, ""+(GameUtil.end_time-GameUtil.start_time)/1000 , GameUtil.offset, GameUtil.offset/2, 30, Color.black);
switch (GameUtil.state) {
case 0 :
GameUtil.end_time=System.currentTimeMillis();
g.drawImage(GameUtil.face,
GameUtil.offset+GameUtil.squareLength*(GameUtil.wide/2),
GameUtil.offset/3,
null);
break;
case 1 :
g.drawImage(GameUtil.win,
GameUtil.offset+GameUtil.squareLength*(GameUtil.wide/2),
GameUtil.offset/3,
null);
break;
case 2:
g.drawImage(GameUtil.over,
GameUtil.offset+GameUtil.squareLength*(GameUtil.wide/2),
GameUtil.offset/3,
null);
break;
default:
}
}
}
頂層方格的繪制文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-770668.html
import java.awt.Color;
import java.awt.Graphics;
import java.security.KeyManagementException;
public class MapTop {
int temp_x;
int temp_y;
void reGame()
{
for(int i = 1;i <=GameUtil.wide;i++)
{
for(int j = 1; j<=GameUtil.high; j++)
{
GameUtil.Data[i][j]=0;
}
}
}
void logic()
{
temp_x = 0;
temp_y = 0;
if (GameUtil.Mouse_x>GameUtil.offset&&GameUtil.Mouse_y>GameUtil.offset)
{
temp_x = (GameUtil.Mouse_x-GameUtil.offset)/GameUtil.squareLength+1;
temp_y = (GameUtil.Mouse_y-GameUtil.offset)/GameUtil.squareLength+1;
}
if(temp_x>=1&&temp_x<=GameUtil.wide
&&temp_y>=1&&temp_y<=GameUtil.high)
{
if(GameUtil.left)
{
if(GameUtil.Data[temp_x][temp_y]==0)
{
GameUtil.Data[temp_x][temp_y]=-1;
}
spaceOpen(temp_x,temp_y);
GameUtil.left = false;
}
if(GameUtil.right)
{
if(GameUtil.Data[temp_x][temp_y]==0)
{
GameUtil.Data[temp_x][temp_y]=1;
GameUtil.flag_num++;
}
else if(GameUtil.Data[temp_x][temp_y]==1)
{
GameUtil.Data[temp_x][temp_y]=0;
GameUtil.flag_num--;
}
else if(GameUtil.Data[temp_x][temp_y]==-1)
{
numOpen(temp_x,temp_y);
}
GameUtil.right = false;
}
}
boom();
victory();
}
boolean victory()
{
int count = 0;
for(int i = 1; i<=GameUtil.wide; i++)
{
for(int j = 1; j<=GameUtil.high;j++)
{
if(GameUtil.Data[i][j]!=-1)
{
count++;
}
}
}
if(count==GameUtil.Mine_max)
{
GameUtil.state=1;
for(int i = 1; i<=GameUtil.wide; i++)
{
for(int j = 1;j<=GameUtil.high;j++)
{
if(GameUtil.Data[i][j]==0)
{
GameUtil.Data[i][j]=1;
}
}
}
return true;
}
return false;
}
void seeBoom()
{
for(int i = 1; i<=GameUtil.wide; i++)
{
for(int j = 1; j<=GameUtil.high;j++)
{
if(GameUtil.bottom[i][j]==-1&&GameUtil.Data[i][j]!=1)
{
GameUtil.Data[i][j]=-1;
}
if(GameUtil.bottom[i][j]!=-1&&GameUtil.Data[i][j]==1)
{
GameUtil.Data[i][j]=2;
}
}
}
}
boolean boom()
{
for(int i = 1; i<=GameUtil.wide; i++)
{
for(int j = 1; j<=GameUtil.high;j++)
{
if(GameUtil.bottom[i][j]==-1&&GameUtil.Data[i][j]==-1)
{
GameUtil.state=2;
seeBoom();
return true;
}
}
}
return false;
}
void numOpen(int x, int y)
{
int count=0;
if(GameUtil.bottom[x][y]>0)
{
for(int i = x-1; i<=x+1;i++)
{
for(int j=y-1;j<=y+1;j++)
{
if(GameUtil.Data[i][j]==1)
{
count++;
}
}
}
if(count==GameUtil.bottom[x][y])
{
for(int i = x-1; i<=x+1;i++)
{
for(int j=y-1;j<=y+1;j++)
{
if(GameUtil.Data[i][j]!=1)
{
GameUtil.Data[i][j]=-1;
}
if(i>=1&&j>=1&&i<=GameUtil.wide&&j<=GameUtil.high)
{
spaceOpen(i,j);
}
}
}
}
}
}
void spaceOpen(int x,int y)
{
if(GameUtil.bottom[x][y]==0)
{
for(int i = x-1; i<=x+1;i++)
{
for(int j=y-1;j<=y+1;j++)
{
if(GameUtil.Data[i][j]!=-1)
{
if(GameUtil.Data[i][j]==1)
{
GameUtil.flag_num--;
}
GameUtil.Data[i][j]=-1;
if(i>=1&&j>=1&&i<=GameUtil.wide&&j<=GameUtil.high)
{
spaceOpen(i,j);
}
}
}
}
}
}
void paintMap(Graphics g)
{
logic();
for(int i = 1;i<=GameUtil.wide;i++)
{
for(int j=1;j<=GameUtil.high;j++)
{
if(GameUtil.Data[i][j]==0) {
g.drawImage(GameUtil.unknown,
GameUtil.offset+(i-1)*GameUtil.squareLength+1,
GameUtil.offset+(j-1)*GameUtil.squareLength+1,
GameUtil.squareLength-2,
GameUtil.squareLength-2,
null);
}
if(GameUtil.Data[i][j]==1) {
g.drawImage(GameUtil.flag,
GameUtil.offset+(i-1)*GameUtil.squareLength+1,
GameUtil.offset+(j-1)*GameUtil.squareLength+1,
GameUtil.squareLength-2,
GameUtil.squareLength-2,
null);
}
if(GameUtil.Data[i][j]==2) {
g.drawImage(GameUtil.noflag,
GameUtil.offset+(i-1)*GameUtil.squareLength+1,
GameUtil.offset+(j-1)*GameUtil.squareLength+1,
GameUtil.squareLength-2,
GameUtil.squareLength-2,
null);
}
}
}
}
}
到了這里,關(guān)于Java課程設(shè)計(jì)——掃雷游戲程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!