import java.awt.*
import java.awt.event.*
public class Main
{
public static void main(String[] argus)
{
Landmine Zhang = new Landmine()
}
}
//
// Landmine类 主界面
class Landmine extends JFrame
{
static Resources resources = new Resources()
Playing listener = new Playing(this) //主要监听者,监听地雷面板的动作
Help helpListener = new Help(this) //辅助监听者,监听“帮助”、“关于”
JPanel landminePanel = new JPanel() //创建地雷面板
JPanel topPanel = new JPanel() //创建顶部面板
JPanel lowerPanel = new JPanel() //创建底部面板
public static MyButton [][] lei //主区按钮组
public static int numberOfUnflaged //剩余的雷数,显示在topPanel上,用于提示用户
public static int numberOfClicked //已经翻开的格子数,当数字数字到"总格子数—雷数"时,即胜利
public static int usedTime//已用时间
public static JLabel numberOfUnflagedLabel = new JLabel()//创建剩雷数标签
public static JLabel timeLabel = new JLabel()//创建时间标签
public static Timer timer //创建计时
Keylistener keyListener = new Keylistener(this)
public Landmine()
{
super("扫雷__1.2版__小老头") //标题
setBounds(300,90,800,800) //设置窗口位置和大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)//最大化、最小化、关闭按钮
BorderLayout ff = new BorderLayout() //创建布局管理器
setLayout(ff) //关联布局管理器
setResizable(false) //禁止改变窗口大小
/*初始化一些数据*/
numberOfClicked = 0
numberOfUnflaged = 40
usedTime = 0
/*设置顶部面板*/
numberOfUnflagedLabel.setText("剩余雷数:"+numberOfUnflaged)//显示剩余雷数
numberOfUnflagedLabel.setFont(resources.fontOne)//设置剩雷数标签字体
numberOfUnflagedLabel.setIcon(resources.bombIconForLabel)//剩雷数标签图标(地雷形)
topPanel.add(numberOfUnflagedLabel) //剩雷数标签加入topPanel
timeLabel.setText("用时:" + usedTime)//显示剩余时间
timeLabel.setFont(resources.fontOne) //设置时间标签字体
timeLabel.setIcon(resources.clockIcon)//设置时间标签图标
topPanel.add(timeLabel) //时间标签加入topPanel
add(topPanel,BorderLayout.NORTH) //加入主面板上部
timer = new Timer(1000,new TimerListener())//计算器注册监听者
/*设置底部面板*/
JButton aboutJB = new JButton("关于") //创建“关于”按钮
JButton helpJB = new JButton("求救") //创建“求救”按钮
helpJB.addActionListener(helpListener) //"求救"按钮加入监听者
aboutJB.addActionListener(helpListener)//"关于"按钮加入监听者
helpJB.addKeyListener(keyListener)
aboutJB.addKeyListener(keyListener) //注册按键监听
lowerPanel.add(aboutJB) //“关于”按钮加入lowerPanel
lowerPanel.add(helpJB) //“帮助”按钮加入lowerPanel
add(lowerPanel,BorderLayout.SOUTH)
/*设置地雷面板*/
GridLayout dd = new GridLayout(16,16)
landminePanel.setLayout(dd) //布局管理
lei = new MyButton[18][18]
for(int i=0i<18++i)
{//创建下标0—17的按钮,18*18矩阵
for(int j=0j<18++j)
{
lei[i][j] = new MyButton(i,j)
}
}
for(int i=1i<17++i)
{//将下标1-16的按钮,加入面板、设置图标、翻开标记为假、加入监听者
for(int j=1j<17++j)
{
landminePanel.add(lei[i][j]) //按钮加入地雷面板
lei[i][j].setIcon(resources.smallIcon) //设置按钮图标
lei[i][j].isClicked = false //翻开标记设置为 假lei[i][j].setIcon(dead)
lei[i][j].addActionListener(listener) //加入监听者
lei[i][j].addMouseListener(listener) //加入鼠标事件监听者
lei[i][j].addKeyListener(keyListener) //按钮注册按键监听,当焦点在按钮上是能监听按键
}
}
add(landminePanel,BorderLayout.CENTER) //landminePanel加入主框架中央
addLandmine() //布雷
timer.start() //启动计时器
setVisible(true)//显示之
}
/*布雷*/
public static void addLandmine()
{//随机将40的按钮的是否为雷的标记isBomb设为真
for(int count = 0count<40/*blank*/)
{
int i = (int)(Math.random()*100 % 16 +1 )
int j = (int)(Math.random()*100 % 16 +1 )
if(lei[i][j].isBomb == false)
{
lei[i][j].isBomb = true
count++
}
}
}
class TimerListener implements ActionListener
{//内部类,时间监听
public void actionPerformed(ActionEvent e)
{
usedTime++
timeLabel.setText("用时:" + usedTime)
}
}
}
//
// Playing类 执行主要游戏 *** 作
class Playing implements ActionListener,MouseListener
{
static Resources resources = new Resources()
public static Landmine gui
public Playing(Landmine in )
{
gui = in
}
public void actionPerformed(ActionEvent event)
{
MyButton receive = (MyButton)event.getSource()
if(receive.isBomb)
{//如果翻到了雷。。
for(int i=1i<17++i)
{//将所有的雷图标设为 “地雷”
for(int j=1j<17++j)
{
if(gui.lei[i][j].isBomb)
gui.lei[i][j].setIcon(resources.bombIcon)
}
}
receive.setIcon(resources.deadIcon)//将踩到的地雷图标设为 “衰”
gui.timer.stop() //停止计时器
JOptionPane.showMessageDialog(null,"小朋友,你挂了…","失败!",
JOptionPane.INFORMATION_MESSAGE,
resources.deadIcon)//提示失败
int yourChose = JOptionPane.showConfirmDialog(null,"你可能是一不小心点错了,再来一局?" )
if(yourChose == JOptionPane.OK_OPTION)
{//点击“是”时
replay()
}
else
{//点击 “否” 或 “取消” 时退出程序
System.exit(0)
}
}
else if(receive.isClicked ==false)
{//未翻到雷
showBombNumber(receive)
}
}
public static void showBombNumber(MyButton in)
{//翻开点击的按钮
int numberOfLandmine = 0//记录雷的个数
in.isClicked = true //翻开标记设为真
/*检测周围8个方块是否为雷*/
if(gui.lei[in.num_x-1][in.num_y-1].isBomb == true) numberOfLandmine++//左上
if(gui.lei[in.num_x][in.num_y-1].isBomb == true) numberOfLandmine++ //上
if(gui.lei[in.num_x+1][in.num_y-1].isBomb == true) numberOfLandmine++//右上
if(gui.lei[in.num_x+1][in.num_y].isBomb == true) numberOfLandmine++ //右
if(gui.lei[in.num_x+1][in.num_y+1].isBomb == true) numberOfLandmine++//右下
if(gui.lei[in.num_x][in.num_y+1].isBomb == true) numberOfLandmine++ //下
if(gui.lei[in.num_x-1][in.num_y+1].isBomb == true) numberOfLandmine++//左下
if(gui.lei[in.num_x-1][in.num_y].isBomb == true) numberOfLandmine++ //左
in.setIcon(new ImageIcon("images/"+numberOfLandmine+".png"))//根据周围的雷数显示数字图标
gui.numberOfClicked++//翻开格子数+1
if(gui.numberOfClicked==216)
{//翻开216个格子时游戏成功,用户选择是否再来一局
int yourChoice = JOptionPane.showConfirmDialog(null,"恭喜你成功了!再来一盘吗?")
if(yourChoice == JOptionPane.OK_OPTION)
replay()
else
System.exit(0)
}
if(numberOfLandmine==0)
{//如果周围无雷,则将周围未翻开格子的全部翻开
if(gui.lei[in.num_x-1][in.num_y-1].isClicked == false)
showBombNumber(gui.lei[in.num_x-1][in.num_y-1])
if(gui.lei[in.num_x][in.num_y-1].isClicked == false)
showBombNumber(gui.lei[in.num_x][in.num_y-1])
if(gui.lei[in.num_x+1][in.num_y-1].isClicked == false)
showBombNumber(gui.lei[in.num_x+1][in.num_y-1])
if(gui.lei[in.num_x+1][in.num_y].isClicked == false)
showBombNumber(gui.lei[in.num_x+1][in.num_y])
if(gui.lei[in.num_x+1][in.num_y+1].isClicked == false)
showBombNumber(gui.lei[in.num_x+1][in.num_y+1])
if(gui.lei[in.num_x][in.num_y+1].isClicked == false)
showBombNumber(gui.lei[in.num_x][in.num_y+1])
if(gui.lei[in.num_x-1][in.num_y+1].isClicked == false)
showBombNumber(gui.lei[in.num_x-1][in.num_y+1])
if(gui.lei[in.num_x-1][in.num_y].isClicked == false)
showBombNumber(gui.lei[in.num_x-1][in.num_y])
}
}
public static void replay()
{//重新开始
gui.dispose() //释放框架资源
gui.timer.stop() //终止计时器
Landmine ff = new Landmine()//重新创建一个主类的实例
//这几条语句实现了重新开始————关闭上一个窗口,重新开启一个
//但是这种方法会造成内存的浪费,一个改进的方法是不关闭当年窗口,而是将当前窗口重新初始化
}
public void mousePressed(MouseEvent e)
{//当鼠标右键点击时自动调用此函数
int mods = e.getModifiers()
MyButton receive = (MyButton)e.getSource()
if((mods &InputEvent.BUTTON3_MASK) != 0)
{//鼠标右键
if(receive.isClicked == false)
{
receive.isRight = receive.isRight ? false : true//改变receive.isRight的值
if(receive.isRight)
{//如果添加标记,则剩余雷数-1,设置标签为“旗帜”
gui.numberOfUnflaged--
receive.setIcon(resources.flagIcon)
}
else
{//如果清除标记,则剩余雷数+1,设置标签为“未翻开”
gui.numberOfUnflaged++
receive.setIcon(resources.smallIcon)
}
gui.numberOfUnflagedLabel.setText("剩余雷数:"+gui.numberOfUnflaged)
//更新剩余雷数标签
}
}
}
public void mouseReleased(MouseEvent e){}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
}
//
// Help类,响应“关于”、“求救”
class Help implements ActionListener
{
static Resources resources = new Resources()
public static Landmine gui
public Help(Landmine in)
{
gui = in
}
public void actionPerformed(ActionEvent event)
{
if(event.getActionCommand()=="关于")
JOptionPane.showMessageDialog(null,"扫雷1.2版。。小老头出品")
if(event.getActionCommand()=="求救")
help()
}
public static void help()
{//求救
int stopNumber = (int)(Math.random() * gui.numberOfUnflaged + 1 )
int count = 0
for(int i=1i<17++i )
{
for(int j=1j<17++j)
{
if( gui.lei[i][j].isBomb && !gui.lei[i][j].isClicked &&!gui.lei[i][j].isRight )
{
count++
}
if(count == stopNumber)
{
gui.lei[i][j].setIcon(resources.badIcon)
return
}
}
}
}
}
//
// Keylistener类,响应键盘事件
class Keylistener implements KeyListener
{
static Resources resources = new Resources()
Landmine gui
public Keylistener(Landmine in)
{
gui = in
}
public void keyPressed(KeyEvent e)
{//有键按下时自动执行该方法
if(e.getKeyCode() == KeyEvent.VK_UP)
{//按键为 向上 时,将所有未标记的地雷显示出
for(int i=1i<17++i)
{
for(int j=1j<17++j)
{
if(gui.lei[i][j].isBomb &&!gui.lei[i][j].isRight)
gui.lei[i][j].setIcon(resources.badIcon)
}
}
}
if(e.getKeyCode() == KeyEvent.VK_DOWN)
{//按键为 向下 时,将所有未标记的地雷恢复为未点击的图标
for(int i=1i<17++i)
{
for(int j=1j<17++j)
{
if(gui.lei[i][j].isBomb &&!gui.lei[i][j].isRight)
gui.lei[i][j].setIcon(resources.smallIcon)
}
}
}
}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
}
//
// 按钮类 MyBtton
class MyButton extends JButton
{
public int num_x,num_y //第几号方块
public boolean isBomb //是否为雷
public boolean isClicked //是否被点击
public int BombFlag //探雷标记
public boolean isRight //是否点击右键
public MyButton(int x, int y)
{
BombFlag = 0
num_x = x
num_y = y
isBomb = false
isClicked = true
isRight = false
}
}
//
// 资源类 其他类中用到的图标,字体等
class Resources
{
public static ImageIcon deadIcon
public static ImageIcon smallIcon
public static ImageIcon clockIcon
public static ImageIcon bombIcon
public static ImageIcon flagIcon
public static ImageIcon badIcon
public static ImageIcon bombIconForLabel
public static Font fontOne
public Resources()
{
deadIcon = new ImageIcon("images/dead.gif")
smallIcon = new ImageIcon("images/smallIcon.png")
clockIcon = new ImageIcon("images/clock2.png")
bombIcon = new ImageIcon("images/bomb.png")
flagIcon = new ImageIcon("images/flag_2.png")
badIcon = new ImageIcon("images/bad.gif")
bombIconForLabel = new ImageIcon("images/bombForLabel.gif")
fontOne = new Font("null",Font.BOLD,20)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)