1. 人员分工
组员 | 职务 | 分工 |
---|---|---|
潘鋆祥 | 组长 | 顶层格子的代码设计,界面UI设计 |
覃小杰 | 组员 | 扫雷素材的搜集,底层雷的代码设计 |
2.前期调查
游戏详情
以windows 7自带扫雷为例。游戏区包括雷区、地雷计数器和计时器,确定大小的矩形雷区中随机布置一定数量的地雷(初级为99个方块10个雷,中级为1616个方块40个雷,高级为16*30个方块99个雷),玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷。
游戏的基本操作包括左键单击、右键单击、双击三种。其中左键用于打开安全的格子,推进游戏进度;右键用于标记地雷,以辅助判断,或为接下来的双击做准备;双击在一个数字周围的地雷标记完时,相当于对数字周围未打开的方块均进行一次左键单击操作:
左键单击:
在判断出不是雷的方块上按下左键,可以打开该方块。如果方块上出现数字,则该数字表示其周围3×3区域中的地雷数(一般为8个格子,对于边块为5个格子,对于角块为3个格子。所以扫雷中最大的数字为8);如果方块上为空(相当于0),则可以递归地打开与空相邻的方块;如果不幸触雷,则游戏结束。
右键单击:
在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。重复操作可取消标记
双击:
同时按下左键和右键完成双击。当双击位置周围已标记雷数等于该位置数字时操作有效,相当于对该数字周围未打开的方块均进行一次左键单击操作。地雷未标记完全时使用双击无效。若数字周围有标错的地雷,则游戏结束,标错的地雷上会显示一个“ ×”。
3.需求分析
3.1系统数据分析
扫雷雷区是一个二维区间,所以需要一个二维数组进行存储数据,而其中又分为了底层跟上层,底层用于存储雷跟数字,上层用于翻开格子,插旗等操作。
若翻开的格子下是雷,则判定失败;若全局中未翻开的格子数(包括插旗的格子)等于雷数,则默认将所有未翻开的格子插旗,且判定胜利。
3.2系统操作分析
进行左键右键操作的时候,我们需要对鼠标进行监听,若鼠标左键或右键点击,则读取鼠标的横纵坐标,然后通过换算之后,换算成鼠标点击的对应格子的二维数组坐标,然后在二维数组中对其进行操作。因为双击的操作过于繁琐,我们用右键进行替代,若右键点击到的是已被翻开的格子,则判定原本扫雷中的双击操作;若右键点击的是未翻开的格子,则进行插旗操作。
3.3系统界面分析
需要有能进行难度选择的按钮,难度选择后能确确实实地改变雷数与格子数,且窗口的大小能根据难度的变化进行相应的变大缩小,需要有能实时变化的地雷计数器和计时器,且能给与出随时重置游戏的按钮。
4.流程图
5.游戏运行截图
难度选择
简单难度
成功判定
失败判定
普通难度
困难难度
6.关键代码
主页面代码(包括鼠标监听)
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();
}
}
底层雷区绘制文章来源:https://www.toymoban.com/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:
}
}
}
顶层方格的绘制文章来源地址https://www.toymoban.com/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);
}
}
}
}
}
到了这里,关于Java课程设计——扫雷游戏程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!