📄 game.java
字号:
/**
@version 1.0 2008-01-05
@author 赵勇
*/
import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.prefs.Preferences;
import javax.swing.*;
import java.io.InputStream;
/**
Only for start.
*/
public class Game
{
public static void main(String[] args)
{
GameFrame frame = new GameFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
}
}
/**
The main class for almost all the things.
It has a inner class and 4 methods.
*/
class GameFrame extends JFrame
{
public GameFrame()
{
setTitle("Game");
// Initiative the icon class for save and get the icon informations.
gameicon = new GameIcon();
// Initiatives all the action listener for menu.
initlistener();
// Initiatives the new GamePanel for all the state.
gamepanel = new GamePanel();
// Build and fill the menu bar.
addmenu();
// Display the game panel.
add(gamepanel);
pack();
}
/**
The method is just Build and fill the menu bar.
It's not has to write as a method.
*/
private void addmenu()
{
JMenu filemenu = new JMenu("游戏");
JMenuItem newgameitem = new JMenuItem("新游戏");
newgameitem.addActionListener(newgamelistener);
filemenu.add(newgameitem);
filemenu.addSeparator();
JMenuItem lv1item = new JMenuItem("初级");
lv1item.addActionListener(lv1listener);
filemenu.add(lv1item);
JMenuItem lv2item = new JMenuItem("中级");
lv2item.addActionListener(lv2listener);
filemenu.add(lv2item);
JMenuItem lv3item = new JMenuItem("高级");
lv3item.addActionListener(lv3listener);
filemenu.add(lv3item);
JMenuItem lv_orderitem = new JMenuItem("自定义");
lv_orderitem.addActionListener(lv_orderlistener);
filemenu.add(lv_orderitem);
filemenu.addSeparator();
JMenuItem exititem = new JMenuItem("退出");
exititem.addActionListener(exitlistener);
filemenu.add(exititem);
JMenu aboutmenu = new JMenu("关于");
JMenuItem aboutitem = new JMenuItem("关于本软件");
aboutitem.addActionListener(aboutlistener);
aboutmenu.add(aboutitem);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
menuBar.add(filemenu);
menuBar.add(aboutmenu);
}
/**
The method used for initiatives a new game.
It's has to write as a method , because the inner action listeners need it.
It removed the old panel first , then initiatives the panel , and add the new panel at last.
*/
private void newgame()
{
// Remove the old panel .
remove(gamepanel);
// Change the old panel become a new panel.
gamepanel = new GamePanel();
// Add the new panel.
add(gamepanel);
// add the menu bar. maybe it's not useful.
addmenu();
pack();
}
/**
The method is just Build the menu's action listener.
It's not has to write as a method.
*/
private void initlistener()
{
// New action listener for new game.
newgamelistener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
newgame();
}
};
// New action listener for level1 game.
lv1listener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
setpanelsize(10,8,-1);
newgame();
}
};
// New action listener for level2 game.
lv2listener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
setpanelsize(20,16,-1);
newgame();
}
};
// New action listener for level3 game.
lv3listener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
setpanelsize(40,32,-1);
newgame();
}
};
// New action listener for level_order game.
lv_orderlistener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (choosedialog == null) // first time
choosedialog = new ChooseDialog(null);
choosedialog.setVisible(true);
}
};
// New action listener for exit button.
exitlistener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
};
// New action listener for about button.
aboutlistener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (aboutdialog == null) // first time
aboutdialog = new AboutDialog(null);
aboutdialog.setVisible(true);
}
};
}
/**
A modal dialog that displays a message and waits for the user to input the data.
*/
class ChooseDialog extends JDialog
{
public ChooseDialog(JFrame owner)
{
super(owner, "Please choose the size", true);
// Initiatives panel .
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(4, 2));
// labels and inputs .
JLabel xlabel = new JLabel("水平");
final JFormattedTextField xfield = new JFormattedTextField(NumberFormat.getIntegerInstance());
xfield.setValue(new Integer(20));
JLabel ylabel = new JLabel("垂直");
final JFormattedTextField yfield = new JFormattedTextField(NumberFormat.getIntegerInstance());
yfield.setValue(new Integer(16));
JLabel bomblabel = new JLabel("雷数");
final JFormattedTextField bombfield = new JFormattedTextField(NumberFormat.getIntegerInstance());
bombfield.setValue(new Integer(80));
// YES and NO button closes the dialog
JButton yes = new JButton("确定");
ActionListener yeslistener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int x = Integer.parseInt(xfield.getValue().toString());
int y = Integer.parseInt(yfield.getValue().toString());
int bomb = Integer.parseInt(bombfield.getValue().toString());
setpanelsize(x,y,bomb);
choosedialog.setVisible(false);
newgame();
}
};
yes.addActionListener(yeslistener);
JButton no = new JButton("取消");
ActionListener nolistener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
choosedialog.setVisible(false);
}
};
no.addActionListener(nolistener);
// add all in the panel .
panel.add(xlabel);
panel.add(xfield);
panel.add(ylabel);
panel.add(yfield);
panel.add(bomblabel);
panel.add(bombfield);
panel.add(yes);
panel.add(no);
add(panel, BorderLayout.CENTER);
setSize(250, 150);
}
}
/**
A modal dialog that displays a message and waits for the user to click the YES and NO button.
*/
class AboutDialog extends JDialog
{
public AboutDialog(JFrame owner)
{
super(owner, "About the game", true);
String text = "<html><h3>此软件完全由本人制作,本人享有本软件的所有版权。向所有JAVA学习者提供此软件的完全源代码,如有需要,请加QQ21064173,注意注明加Q理由。</h3></html>";
add(new JLabel(text) , BorderLayout.CENTER);
setSize(250, 150);
}
}
/**
A modal dialog that displays a message and waits for the user to input the data.
*/
class SignDialog extends JDialog
{
public SignDialog(JFrame owner)
{
super(owner, "Please enter your name", true);
// Initiatives panel .
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2, 2));
// labels and inputs .
JLabel namelabel = new JLabel("姓名");
final JTextField namefield = new JTextField();
// YES and NO button closes the dialog
JButton yes = new JButton("确定");
ActionListener yeslistener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
signdialog.setVisible(false);
}
};
yes.addActionListener(yeslistener);
JButton no = new JButton("取消");
ActionListener nolistener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
signdialog.setVisible(false);
}
};
no.addActionListener(nolistener);
// add all in the panel .
panel.add(namelabel);
panel.add(namefield);
panel.add(yes);
panel.add(no);
add(panel, BorderLayout.CENTER);
setSize(250, 80);
}
}
/**
@param x
@param y
@param bomb
The method for reset the panel size.
Use the x , y change the num_x and num_y;
Write it as a method , so when the inner class want to do this thing , won't change the data by itself.
*/
private void setpanelsize(int x,int y,int bomb)
{
if(x<5) x=5;
if(x>50) x=50;
if(y<3) y=3;
if(y>40) y=40;
if(bomb>x*y) bomb=x*y;
num_x = x ;
num_y = y ;
if (bomb < 0)
num_bomb = (int) (x*y*0.2);
else
num_bomb = bomb;
}
/**
Create the class GamePanel as a inner class so that the GamePanel can used all the private data and methods.
It used for initiatives all the game informations which is need by running the game.
*/
private class GamePanel extends JPanel
{
public GamePanel()
{
// Set the panel use the BorderLayout to get the same size label.
setLayout(new BorderLayout());
// Set the BorderLayout with num_y and num_x , add the action listener for panel.
panel = new JPanel();
panel.setLayout(new GridLayout(num_y, num_x));
panel.addMouseListener(new MouseHandler());
// Set the inner panel use the Box layout.
b = Box.createHorizontalBox();
// Initiatives a label to display total time,set the total time to 5000 seconds at the same.
totaltime = new TimeLabel();
totaltime.settime(5000);
// Initiatives a button as start button .
// Use the image as the icon , set the size as the image and add the action listener newgamelistener.
ImageIcon newgameicon = gameicon.geticon("newgame.gif");
JButton newgame = new JButton();
newgame.setIcon(newgameicon);
newgame.setBorder(null);
newgame.addActionListener(newgamelistener);
// Initiatives a label to display used times , set the total time to 0 seconds at the same.
usedtime = new TimeLabel();
usedtime.settime(0);
// Initiatives a time listener to get the used time.
// If the used time is more than the max time , show game lost.
ActionListener timelistener = new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(usedtime.gettime()+1 >= maxtime)
showlost();
else
usedtime.settime(usedtime.gettime()+1);
}
};
// Initiatives a timer , alive the time listener for every seconds.
counttime = new Timer(1000,timelistener);
// Add all the labels and buttons , use the glue for get the good look.
b.add(totaltime);
b.add(Box.createGlue());
b.add(newgame);
b.add(Box.createGlue());
b.add(usedtime);
// Add the panel and box into the panel used border layout.
add(panel, BorderLayout.CENTER);
add(b ,BorderLayout.NORTH );
// Initiatives the state[][] and choose[][].
initstate();
// Display the panel.
displayallstate();
// Initiatives the bomb.
buildbomb();
// Reset the state[][] with bomb state.
fillallstate();
//display all the state[][] state if need.mostly for debug.
//display state ;
}
/**
Add the mode for debug . Delete it after done.
Show all the label in panel list.
*/
private void displaystate()
{
int r=0;
for (JLabel l: panellist)
{
l.setText(""+state[(r-r%num_x)/num_x][r%num_x]);
r++;
}
}
/**
Initiatives the state of state[][] with 8 ,choose[][] with 0 , and add all labels.
The arrays state[][],choose[][] used a larger number than the number in fact.
When add the label , used the num_x and num_y , so the number is the same as the fact.
*/
private void initstate()
{
for(int i=0;i<100;i++)
for(int j=0;j<80;j++)
{
state[i][j] = 8;
choose[i][j] = 0;
}
for(int i=0;i<num_x*num_y;i++)
{
ImageIcon buttonicon = gameicon.geticon("8.gif");
label = new JLabel(buttonicon);
panel.add(label);
panellist.add(label);
}
}
/**
Create the bomb in the state[][] , use number -1 instead bomb.
Count the bomb number if equals num_bomb , close the method.
If the new bomb and the old bombs are in the same place , recreate it.
*/
private void buildbomb()
{
int i,r;
for(i=0;i<num_bomb;)
{
r = (int) (Math.random()*(num_x*num_y));
if(!(state[(r-r%num_x)/num_x][r%num_x] == -1))
{
state[(r-r%num_x)/num_x][r%num_x] = -1;
i++;
}
}
}
/**
Reset the state[][] with bomb state.
If the place is not bomb , reset the place state.
*/
private void fillallstate()
{
for(int i=0;i<num_y;i++)
for(int j=0;j<num_x;j++)
{
if(state[i][j]!=-1)
state[i][j] = get(i,j);
}
}
/**
@param x
@param y
@return
Count the all the state[][] which next to this place which want to reset.
If the next place is in the state[][] , check it .
Check the next place ,if it's state equals -1.
If the state is -1 , count add 1.
*/
private int get(int x,int y)
{
int count = 0;
for(int i=-1;i<2;i++)
for(int j=-1;j<2;j++)
if(!(i==0&&j==0))
if(check(x+i,y+j,-1))
count++;
return count;
}
/**
@param i
@param j
@return
Check the number i j . If is in the size ,return true.
*/
private boolean check(int i,int j)
{
if(i>=0&&i<num_y&&j>=0&&j<num_x)
return true;
else
return false;
}
/**
*
* @param x
* @param y
* @param value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -