//Puzzle.java |
-------------------------------------------------------------------------- |
import java.awt.image.BufferedImage; |
import javax.swing.JButton; |
import javax.swing.ImageIcon; |
import javax.swing.JOptionPane; //弹出标准对话框 |
import javax.swing.JRadioButtonMenuItem; //一个单选按钮菜单项的实现 |
public class Puzzle extends CardFrame //卡片布局框架 |
{ |
private boolean start; |
private int fWidth = this .getWidth(); |
private int fHeight = this .getHeight(); |
private GameOver gOver; |
private boolean index = true ; |
public Puzzle() |
{ |
start = false ; |
ImageIcon icon = new ImageIcon( "icon/OK.png" ); //图像图标 |
this .setSize(200 + fWidth, 200 + fHeight); |
this .setIconImage(icon.getImage()); |
this .setVisible( true ); |
} |
private void startGame() |
{ |
if (start) |
return ; |
start = true ; |
updateMenuBegin(); |
} |
public void endGame() |
{ |
updateMenuBegin(); |
initMenuBackground(); |
start = false ; |
JOptionPane.showMessageDialog(null, |
"Time:" + gOver.getTime() + "s\n" + |
"Step:" + gOver.getStep() |
); |
Grades g = new Grades( this ); |
g.set(( int )gOver.getTime(), gOver.getStep()); |
} |
protected void FrameLostFocus() |
{ |
if (start && index) |
{ |
nextCard(); |
if (gOver != null) gOver.pause(); |
index = false ; |
} |
} |
protected void FrameGetFocus() |
{ |
nextCard(); |
if (gOver != null) gOver.pause(); |
index = true ; |
} |
public void menuNewClick() |
{ |
Split sp = Split.get(); |
BufferedImage [][] image; |
//BufferedImage 子类描述具有可访问图像数据缓冲区的 Image |
if (!sp.set(getFilename()) || (image = sp.divid(getType())) == null) |
{ |
JOptionPane.showMessageDialog(null, "File " +getFilename()+ " not exists!\nPlease select again~" ); |
return ; |
} |
startGame(); |
this .setSize(fWidth, fHeight); |
this .setVisible( true ); |
int len = Split.level[getType()]; |
int row = image.length; |
int cal = image[0].length; |
gOver = new GameOver( this ); |
JButton [][] button = new JButton[row][cal]; |
Matrix matrix = new Matrix(button, panel[0], len, gOver); |
matrix.init(image); |
this .setSize(cal * len + fWidth, row * len + fHeight); |
this .setVisible( true ); |
} |
public void menuGradesClick() |
{ |
Grades g = new Grades( this ); |
g.show(); |
} |
public void menuShowClick() |
{ |
new ShowImage(getFilename()); |
} |
public void menuExitClick() |
{ |
System. exit (0); |
} |
public void menuHelpClick() |
{ |
String help0 = "Move the small pictures to make it become the original image.\n\n" ; |
String help1 = "(1)touch the small picture around the blank block to make it move toward to the blank block." ; |
JOptionPane.showMessageDialog(null, help0 + help1); |
} |
public void menuAboutClick() |
{ |
String version = "Version: 0.0.2 beta 1\n" ; |
String author = "Author: Write by ZJGSU redraiment\n" ; |
String email = "E-mail: redraiment@126.com" ; |
JOptionPane.showMessageDialog(null, version + author + email); |
} |
public static void main(String [] argv) |
{ |
Puzzle app = new Puzzle(); |
} |
} |
|
|
//Arg.java |
public interface Arg |
{ |
public static final String path = "background" ; |
public static final String rc = "Game.rc" ; |
} |
|
|
//ButtonClick.java |
-------------------------------------------------------------------- |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import javax.swing.JButton; |
import javax.swing.JOptionPane; |
public class ButtonClick implements ActionListener //实现接口..事件监听 |
{ |
private JButton [][] button; //按钮 |
private point pint; |
private int row; |
private int cal; |
private int [][] matrix; |
private GameOver gOver; |
private boolean end; |
public ButtonClick(JButton [][] b, point p, int [][] m, int r, int c, GameOver g) |
{ |
button = b; |
pint = p; |
matrix = m; //矩阵 |
row = r; |
cal = c; |
gOver = g; |
end = false ; |
} |
public void actionPerformed(ActionEvent e) //发生操作事件时,调用此方法 |
{ |
//执行 |
if (end || !pint.neighbor(row, cal)) |
return ; |
int r = pint.getRow(); |
int c = pint.getCal(); |
button[r][c].setIcon(button[row][cal].getIcon()); |
button[row][cal].setIcon(null); |
pint.set(row, cal); |
int t = matrix[r][c]; |
matrix[r][c] = matrix[row][cal]; |
matrix[row][cal] = t; |
end = gOver.judge(); |
} |
} |
|
|
|
//CardFrame.java |
----------------------------------------------------------------- |
import java.awt.BorderLayout; |
import java.awt.CardLayout; |
import java.awt.Container; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.awt.event.WindowEvent; |
import java.awt.event.WindowAdapter; |
import javax.swing.JButton; //按钮 |
import javax.swing.JLabel; //标签 |
import javax.swing.JPanel; //容器面板 |
public abstract class CardFrame extends MenuFrame |
{ |
private CardLayout card; |
private Container con; |
protected JPanel [] panel = { |
new JPanel(), new JPanel() |
}; |
public CardFrame() |
{ |
con = this .getContentPane(); //返回默认的空白面板容器 |
card = new CardLayout(); //卡片布局管理器 |
con.setLayout(card); |
panel[0].setLayout(null); |
JLabel label; |
label = new JLabel( "Please put you image to the" ); |
label.setBounds(10, 15, 190, 30); //左边,右边坐标。宽度,高度 |
panel[0].add(label); |
label = new JLabel( "" background "directory.\n" ); |
label.setBounds(10, 30, 190, 45); |
panel[0].add(label); |
label = new JLabel( "Click " Option->Background "" ); |
label.setBounds(10, 50, 190, 65); |
panel[0].add(label); |
label = new JLabel( "to select the picture.\n" ); |
label.setBounds(10, 65, 190, 80); |
panel[0].add(label); |
label = new JLabel( "Last, click " Begin->New " to" ); |
label.setBounds(10, 85, 190, 100); |
panel[0].add(label); |
label = new JLabel( "start the game." ); |
label.setBounds(10, 100, 190, 115); |
panel[0].add(label); |
panel[1].setLayout( new BorderLayout()); |
JButton button = new JButton( "Continue" ); |
button.addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
FrameGetFocus(); //重新获得焦点,继续游戏 |
} |
} |
); |
panel[1].add(button, BorderLayout.CENTER); |
con.add(panel[0], "Game" ); |
con.add(panel[1], "Pause" ); |
card.show(con, "Game" ); |
this .addWindowListener( new WindowAdapter() |
{ |
public void windowDeactivated(WindowEvent e) |
{ |
FrameLostFocus(); //失去焦点,暂停游戏 |
} |
} |
); |
} |
protected void nextCard() |
{ |
card.next(con); |
} |
protected abstract void FrameLostFocus(); |
protected abstract void FrameGetFocus(); |
} |
|
|
|
|
//GameOver.java |
---------------------------------------------------------------------------- |
import java.util.Date; |
public class GameOver |
{ |
private boolean gameOver; |
private boolean stop; |
private int [][] matrix; |
private Puzzle Main; |
private int step; |
private long now; |
private long countTime; |
public GameOver (Puzzle frm) |
{ |
Main = frm; |
} |
public void start( int [][] m) |
{ |
gameOver = false ; |
matrix = m; |
step = 0; |
Date d = new Date(); |
now = d.getTime(); |
stop = false ; |
countTime = 0; |
} |
public boolean judge() |
{ |
if (gameOver) |
return true ; |
step++; |
int c = 1; |
for ( int i = 0; i < matrix.length; i++) |
for ( int j = 0; j < matrix[i].length; j++) |
if (matrix[i][j] != (c++)) |
return false ; |
Date d = new Date(); |
countTime += d.getTime() - now; |
Main.endGame(); |
return (gameOver = true ); |
} |
public void pause() |
{ |
Date d = new Date(); |
if (stop) |
now = d.getTime(); |
else |
countTime += d.getTime() - now; |
stop = !stop; |
} |
public int getStep() |
{ |
return step; |
} |
public long getTime() |
{ |
return countTime / 1000; |
} |
} |
|
|
|
//Grades.java |
---------------------------------------------------------------- |
import java.io.File; |
import java.io.PrintStream; |
import java.util.Scanner; |
import javax.swing.JOptionPane; //发出通知的标准对话框 |
class Data |
{ |
public String name; |
public int time ; |
public int step; |
} |
public class Grades |
{ |
private Puzzle app; |
private Data [] data = { |
new Data(), |
new Data(), |
new Data() |
}; |
public Grades(Puzzle m) |
{ |
app = m; |
} |
private void creatData() |
{ |
try |
{ |
File file = new File(Arg.rc); |
if (file.exists()) |
return ; |
file.createNewFile(); |
PrintStream fout = new PrintStream(Arg.rc); |
fout. printf ( "%s %d %d\n" , "name" , 999999, 999999); |
fout. printf ( "%s %d %d\n" , "name" , 999999, 999999); |
fout. printf ( "%s %d %d\n" , "name" , 999999, 999999); |
fout.close(); |
} |
catch (Exception e) |
{ |
JOptionPane.showMessageDialog(null, Arg.rc + " has broken!" ); |
return ; |
//标准对话框 |
} |
} |
private void readData() |
{ |
try |
{ |
File file = new File(Arg.rc); |
Scanner cin = new Scanner(file); |
data[0].name = cin.next(); |
data[0]. time = cin.nextInt(); |
data[0].step = cin.nextInt(); |
data[1].name = cin.next(); |
data[1]. time = cin.nextInt(); |
data[1].step = cin.nextInt(); |
data[2].name = cin.next(); |
data[2]. time = cin.nextInt(); |
data[2].step = cin.nextInt(); |
} |
catch (Exception e) |
{ |
JOptionPane.showMessageDialog(null, Arg.rc + " can't read!" ); |
} |
} |
public void set( int t, int s) |
{ |
int type = app.getType(); |
creatData(); |
readData(); |
if (t > data[type]. time || (t == data[type]. time && s >= data[type].step)) |
return ; |
data[type].name = JOptionPane.showInputDialog(null, |
"You broke the record!\nPlease input your name." |
); |
data[type]. time = t; |
data[type].step = s; |
try |
{ |
PrintStream f = new PrintStream(Arg.rc); |
f. printf ( "%s %d %d\n" , data[0].name, data[0]. time , data[0].step); |
f. printf ( "%s %d %d\n" , data[1].name, data[1]. time , data[1].step); |
f. printf ( "%s %d %d\n" , data[2].name, data[2]. time , data[2].step); |
f.close(); |
} |
catch (Exception e) |
{ |
JOptionPane.showMessageDialog(null, Arg.rc + " has broken!" ); |
} |
show(); |
} |
public void show() |
{ |
try |
{ |
creatData(); |
readData(); |
String title = "" .format( "%8s%15s%8s%8s\n" , "Level" , "Name" , "Time" , "Step" ); |
String h = "" .format( "%8s%15s%8d%8d\n" , "Hard" , data[0].name, data[0]. time , data[0].step); |
String n = "" .format( "%8s%15s%8d%8d\n" , "Normal" , data[1].name, data[1]. time , data[1].step); |
String e = "" .format( "%8s%15s%8d%8d\n" , "Easy" , data[2].name, data[2]. time , data[2].step); |
JOptionPane.showMessageDialog(null, title+h+n+e); |
} |
catch (Exception e) |
{ |
JOptionPane.showMessageDialog(null, Arg.rc + " has broken!" ); |
} |
} |
} |
|
|
|
//..Matrix.java |
------------------------------------------------------- |
import java.awt.image.BufferedImage; |
import javax.swing.JPanel; |
import javax.swing.JButton; |
import javax.swing.ImageIcon; |
public class Matrix |
{ |
private JButton [][] button; |
private JPanel panel; |
private int row; |
private int cal; |
private int [][] matrix; |
private GameOver gOver; |
public Matrix(JButton [][] b, JPanel p, int len, GameOver g) |
{ |
this .button = b; |
this .panel = p; |
this .gOver = g; |
row = b.length; |
cal = b[0].length; |
matrix = new int [row][cal]; |
matrix[row-1][cal-1] = row * cal; |
gOver.start(matrix); |
panel.removeAll(); |
point pint = new point(row-1, cal-1); |
for ( int i = 0; i < row; i++) |
for ( int j = 0; j < cal; j++) |
{ |
button[i][j] = new JButton(); |
button[i][j].setBounds(j*len, i*len, len, len); |
button[i][j].addActionListener( new ButtonClick(button, pint, matrix, i, j, gOver)); |
panel.add(button[i][j]); |
} |
} |
public void init(BufferedImage [][] image) |
{ |
if (button == null || image == null) |
return ; |
ImageIcon icon; |
int r, c, rad, d, m; |
boolean [] visit = new boolean[row*cal-1]; |
for ( int i = 0; i < row*cal - 1; i++) |
{ |
r = i / cal; |
c = i % cal; |
rad = ( int )(Math.random()*(row*cal-1-i)); |
for (d = m = 0; d < row*cal - 1 && m <= rad; d++) |
if (!visit[d]) |
m++; |
matrix[i/cal][i%cal] = d; |
visit[--d] = true ; |
icon = new ImageIcon(image[d/cal][d%cal]); |
button[i/cal][i%cal].setIcon(icon); |
} |
} |
} |
|
|
|
|
//MenuFrame.java |
---------------------------------------------------------------------------- |
import java.io.File; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import javax.swing.JFrame; |
import javax.swing.JMenu; |
import javax.swing.JMenuBar; |
import javax.swing.JMenuItem; |
import javax.swing.JRadioButtonMenuItem; //一个单选按钮菜单项的实现 |
import javax.swing.ButtonGroup; |
import javax.swing.KeyStroke; |
public abstract class MenuFrame extends JFrame |
{ |
public final static int heightTitle = 30; |
public final static int widthTitle = 6; |
public final static int heightMenu = 27; |
private JMenu [] m = { //菜单,弹出窗口 |
new JMenu( "Begin(B)" ), |
new JMenu( "Option(O)" ), |
new JMenu( "About(A)" ) |
}; |
private JMenu [] mm = { |
new JMenu( "Level(L)" ), |
new JMenu( "Background(B)" ) |
}; |
private boolean update; |
private int type; |
private String filename; |
protected ButtonGroup bgrp = new ButtonGroup(); |
protected ButtonGroup fgrp = new ButtonGroup(); |
public MenuFrame() |
{ |
super( "Puzzle" ); |
addMenu(); |
this .setResizable( false ); |
this .setDefaultCloseOperation(EXIT_ON_CLOSE); |
this .setSize(widthTitle, heightTitle+heightMenu); |
this .setLocation( |
this .getToolkit().getScreenSize().width/3 - this .getWidth()/3, |
this .getToolkit().getScreenSize().height/3 - this .getHeight()/3 |
); |
} |
private void addMenu() |
{ |
JMenuBar mBar = new JMenuBar(); //菜单栏的实现 |
this .setJMenuBar(mBar); |
mBar.add(m[0]); |
mBar.add(m[1]); |
mBar.add(m[2]); |
m[0].setMnemonic( 'B' ); |
m[1].setMnemonic( 'O' ); |
m[2].setMnemonic( 'A' ); |
initMenuBegin(); |
initMenuOption(); |
initMenuAbout(); |
update = false ; |
} |
public abstract void menuNewClick(); |
public abstract void menuGradesClick(); |
public abstract void menuShowClick(); |
public abstract void menuExitClick(); |
private void menuLevelClick(String nm) |
{ |
type = 3; |
if (nm.equals( "Hard" )) |
type = 0; |
else if (nm.equals( "Normal" )) |
type = 1; |
else if (nm.equals( "Easy" )) |
type = 2; |
} |
private void menuBackgroundClick(String nm) |
{ |
filename = nm; |
} |
public abstract void menuHelpClick(); |
public abstract void menuAboutClick(); |
public int getType() |
{ |
return type; |
} |
public String getFilename() |
{ |
return filename; |
} |
private void initMenuBegin() |
{ |
JMenuItem [] mI = { |
new JMenuItem( "New(N)" ), |
new JMenuItem( "Grades(G)" ), |
new JMenuItem( "Exit(E)" ) |
}; |
mI[0].setMnemonic( 'N' ); |
mI[1].setMnemonic( 'G' ); |
mI[2].setMnemonic( 'E' ); |
mI[0].setAccelerator(KeyStroke.getKeyStroke( "ctrl N" )); |
mI[2].setAccelerator(KeyStroke.getKeyStroke( "ctrl W" )); |
mI[0].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuNewClick(); |
} |
} |
); |
mI[1].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuGradesClick(); |
} |
} |
); |
mI[2].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuExitClick(); |
} |
} |
); |
m[0].add(mI[0]); |
m[0].add(mI[1]); |
m[0].add(mI[2]); |
m[0].insertSeparator(2); |
} |
private void initMenuOption() |
{ |
mm[0].setMnemonic( 'L' ); |
mm[1].setMnemonic( 'B' ); |
m[1].add(mm[0]); |
m[1].add(mm[1]); |
initMenuLevel(); |
initMenuBackground(); |
} |
private void initMenuLevel() |
{ |
JRadioButtonMenuItem [] mi = { |
new JRadioButtonMenuItem( "Hard" ), |
new JRadioButtonMenuItem( "Normal" ), |
new JRadioButtonMenuItem( "Easy" ) |
}; |
for ( int i = 0; i < 3; i++) |
{ |
mi[i].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
JRadioButtonMenuItem mi = (JRadioButtonMenuItem)e.getSource(); |
menuLevelClick(mi.getText()); |
} |
} |
); |
bgrp.add(mi[i]); |
mm[0].add(mi[i]); |
} |
mi[1].setSelected( true ); |
menuLevelClick(mi[1].getText()); |
} |
public void initMenuBackground() |
{ |
mm[1].removeAll(); |
File bkg = new File(Arg.path); |
if (!bkg.exists()) |
return ; |
File [] list = bkg.listFiles(); |
JRadioButtonMenuItem mi; |
int j = 0; |
for ( int i = 0; i < list.length; i++) |
{ |
if (!list[i].isFile() || list[i].isHidden()) |
continue ; |
mi = new JRadioButtonMenuItem(list[i].getName()); |
mi.addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
JRadioButtonMenuItem mi = (JRadioButtonMenuItem)e.getSource(); |
menuBackgroundClick(mi.getText()); |
} |
} |
); |
fgrp.add(mi); |
mm[1].add(mi); |
mi.setSelected(j == 0); |
if (j == 0) |
menuBackgroundClick(mi.getText()); |
j++; |
} |
} |
private void initMenuAbout() |
{ |
JMenuItem [] mI = { |
new JMenuItem( "Help(H)" ), |
new JMenuItem( "About(A)" ) |
}; |
mI[0].setMnemonic( 'H' ); |
mI[1].setMnemonic( 'A' ); |
mI[0].setAccelerator(KeyStroke.getKeyStroke( "F1" )); |
mI[0].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuHelpClick(); |
} |
} |
); |
mI[1].addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuAboutClick(); |
} |
} |
); |
m[2].add(mI[0]); |
m[2].add(mI[1]); |
} |
public void updateMenuBegin() |
{ |
update = !update; |
if (!update) |
{ |
m[0]. remove (2); |
return ; |
} |
JMenuItem mi = new JMenuItem( "Show(S)" ); |
mi.setMnemonic( 'S' ); |
mi.addActionListener( new ActionListener() |
{ |
public void actionPerformed(ActionEvent e) |
{ |
menuShowClick(); |
} |
} |
); |
m[0].insert(mi, 2); |
} |
} |
|
|
//point.java |
---------------------------------------------------------------------------- |
public class point |
{ |
int row; |
int cal; |
public point( int r, int c) |
{ |
row = r; |
cal = c; |
} |
public void set( int r, int c) |
{ |
row = r; |
cal = c; |
} |
public int getRow() |
{ |
return row; |
} |
public int getCal() |
{ |
return cal; |
} |
public boolean neighbor( int r, int c) |
{ |
int n = Math. abs (row - r) + Math. abs (cal - c); |
return n == 1; |
} |
} |
|
|
//ShowImage.java |
-------------------------------------------------------------------------- |
import java.awt.Container; |
import java.awt.FlowLayout; |
//流布局用于安排有向流中的组件,这非常类似于段落中的文本行 |
import javax.swing.ImageIcon; |
import javax.swing.JLabel; |
import javax.swing.JFrame; |
public class ShowImage extends JFrame |
{ |
public ShowImage(String fn) |
{ |
super( "Picture" ); |
Container c = getContentPane(); |
c.setLayout( new FlowLayout()); |
String path = Arg.path + "/" + fn; |
ImageIcon image = new ImageIcon(path); |
c.add( new JLabel(image)); |
setDefaultCloseOperation(HIDE_ON_CLOSE); |
setSize(image.getIconWidth()+10, image.getIconHeight()+30); |
setVisible( true ); |
} |
} |
|
//Split.java |
------------------------------------------------------------------- |
import java.awt.image.BufferedImage; |
import java.io.File; |
import javax.imageio.ImageIO; |
//Singleton class |
public class Split |
{ |
public static final int HARD = 0; |
public static final int NORMAL = 1; |
public static final int EASY = 2; |
public static final String pvo = "png" ; |
public static final int [] level = { |
20, 40, 60 |
}; |
private static Split Ob; |
private String filename; |
private String path; |
private Split() {} |
public static Split get() |
{ |
if (Ob == null) |
Ob = new Split(); |
return Ob; |
} |
public boolean set(String fn) |
{ |
filename = fn; |
path = Arg.path + "/" + filename; |
File file = new File(path); |
return file.exists(); |
} |
public BufferedImage[][] divid( int type) |
{ |
//BufferedImage 子类描述具有可访问图像数据缓冲区的 Image |
try |
{ |
if (filename == null) |
return null; |
BufferedImage image = ImageIO.read( new File(path)); |
int len = level[type]; |
int cal = image.getWidth() / len; |
int row = image.getHeight() / len; |
BufferedImage [][] subimage = new BufferedImage[row][cal]; |
for ( int i = 0; i < row; i++) |
for ( int j = 0; j < cal; j++) |
subimage[i][j] = image.getSubimage(j*len, i*len, len, len); |
return subimage; |
} |
catch (Exception e) |
{ |
return null; |
} |
} |
} |