资源描述
Java课程设计——拼图游戏
班级:信101
学号:2010414126
姓名:孙 杰
指导老师:李红强
基于Java的拼图游戏设计
游戏实现功能解析及界面
游戏规则介绍
1)本游戏是一个Java语言的拼图游戏,有一个格子是空的,其他格子内随机放置由要拿来拼图的图片切割成的若干个小图片,图片的切割按照一定的公式计算,因为,该通过单击任意一个与空格子相邻的方块可以把该方游戏中设有拼图游戏的等级,根据不同的等级,按照公式会切割成不同的小图片块数。
2)在开始游戏之前,可以选择游戏等级后再点击“开始”菜单里的“新游戏”,进行拼图游戏,通过将空格旁边的小图片移入空格子内(不断的移动方块),来实现拼图,直到方块一行一行的按图片的原始样子拼好即可完成该游戏。
3)游戏拼完后,会弹出一个“信息”框,显示你玩游戏所用的步数与时间,点击“确定”后,会弹出一个“输入”框,可以在里面输入游戏者的姓名,单击“确定”后会弹出游戏的记录框。
4)游戏的简单规则在游戏界面的“关于”菜单内的“帮助”信息框内已经简单介绍了。游戏前可以先预览看看。
游戏实现功能
主窗口界面
1) 游戏初始状态
当游戏刚运行时,会出现如下界面,本游戏中已经存在了三张图片,如过游戏者想拼自己感兴趣的图片的话,可以将自己的图片放入到“background”(背景图片)文件夹中,再进行“选择”->“背景图片”中选择你自己的图片,然后选择“等级”->“困难”或“普通”或“简单”,进行等级选择,最后选择“开始”->“新游戏”就可以拼自己想拼的图了。初始窗口如图1所示:
图1 游戏初始窗口
2)游戏进行状态
当游戏者选择好图片与等级后,就可以进行拼图游戏了及进入游戏的进行状态。
3)游戏暂停状态
当游戏者,在游戏过程中半途暂停游戏的话,将出现如图3所示的游戏暂停状态的界面。当游戏者又想继续游戏时,直接单击界面上的“继续”字样,就可以继续游戏了。
图2 游戏暂停状态
主窗口菜单
在游戏的主窗口菜单中包括如下几个菜单:
(1)“开始”菜单。包括了,“新游戏” 、“成绩记录” 、“图片预览” 、“退出游戏” 。如图4所示。
“新游戏” :单击可以开始游戏,如图2所示游戏进行状态。
“成绩记录” :单击可以查看游戏者的游戏成绩记录。如图5所示。初始的成绩记录。
“图片预览” :在游戏过程中可以单击预览图片,对照着拼,如图6所示。
“退出游戏” :游戏者要结束游戏可直接单击退出游戏。
(2)“选择”菜单。包括了,“等级”、“背景图片”。如图7所示。当运行游戏时,如果没有把“background”这个文件夹放入主程序的目录下,在运行游戏选择背景图片时,将没有图片可选,这是可以按照“初始状态”界面上的提示进行操作。若正常的有“background”在主程序路径下的话,运行游戏选择背景图片的话,就可以选择图片了,界面如图3所示。
“等级” :在游戏者开始游戏之前,要进行游戏等级选择,共有困难、普通、简单三种选择。其图片的切割块数,会根据选择的等级不同,而有所不同。
“背景图片” :这里保存了所要拼的所有图片。在游戏前要进行选择。
图3
(3)“关于”菜单。包括了“帮助”、“关于”两个下拉菜单。
“帮助”:在游戏时,可以单击查看游戏的简单规则。
“关于”:可查看该游戏的版本、作者、与作者的Email的相关信息
游戏过程中的出现的相关窗体
(1)提示信息窗口
当游戏者运行游戏时,如果没有把“background”这个文件夹放入主程序的目录下,在运行游戏选择背景图片时,将没有图片可选,若此时直接“开始”->“新游戏”,将会弹出如下提示信息框。界面如图4所示。
图4 提示信息框
(2) 拼图成功界面
若选择abc.jpg图片拼图时,若拼图成功,界面如图5所示。
图5 拼图成功
(3)成绩记录输入框
当游戏者完成拼图游戏后,将出现一个成绩记录框(“输入”框),输入游戏者的姓名。如图6所示。输入后单击确定按钮,将弹出总的成绩记录框。如图7所示。
图6(a) 输入前
图6 (b) 输入后
图7 成绩记录框
游戏程序实现
程序类主要功能介绍
该游戏程序中包括11个类。包括: ButtonClick.class、CardFrame.class、GameOver.class、Data.class 、Grades.class、Matrix.class、MenuFrame.class、 point.class、Puzzle.class、ShowImage.class、Split.class。其中主要的类实现的功能如下:
1) ButtonClick.class
该类主要是实现鼠标事件,让玩家在用鼠标点击能够移动拼图的小图片,移动到周围空格的地方
2) CardFrame.class
该类主要实现,初始界面的相关提示信息。
3)GameOver.class
该类主要实现游戏过程中的计时、暂停、结束等功能,游戏结束时的信息。
4) Data.class
该类主要实现保存游戏者的游戏成绩记录的相关数据。
5)Grades.class
该类主要实现成绩记录的初始化,在拼图成功后可记录游戏者姓名的功能,并直接提取等级、步数与时间等信息的功能。保存成绩记录信息,以便游戏者查看。
6)MenuFrame.class
该类主要实现有主菜单与子菜单的功能。并设置相关的快捷键功能。
7)Puzzle.class
该类是该游戏程序的主程序,从游戏界面大小到游戏过程中出现的所有信息框等相关功能都都到了实现,调用相关类实现其功能。
8)ShowImage.class
该类主要实现图片的提取与切割的功能。
程序的运行
将文件Arg.java,ButtonClick.java,CardFrame.java,GameOver.java,Grades.java,Matrix.java,MenuFrame.java,point.java,Puzzle.java,ShowImage.java,Split.java及background保存到同一个文件夹中。利用javac命令对文件进行编译,使用命令如下:
Javac Puzzle.java
之后,利用java命令执行程序,使用命令如下:
Java Puzzle
便得到拼图程序运行界面。
4 小结
本文是基于JAVA的拼图游戏的程序实现,界面中有一个格子是空的,其他格子内随机放置由要拿来拼图的图片切割成的若干个小图片,图片的切割按照一定的公式计算,因为,该通过单击任意一个与空格子相邻的方块可以把该方游戏中设有拼图游戏的等级,根据不同的等级,按照公式会切割成不同的小图片块数。在开始游戏之前,可以选择游戏等级后再进行拼图游戏,通过将空格旁边的小图片移入空格子内(不断的移动方块),来实现拼图,直到方块一行一行的按图片的原始样子拼好即可完成该游戏。游戏拼完后,会弹出一个信息框,显示你玩游戏所用的步数与时间,点击“确定”后,会弹出一个“输入”框,可以在里面输入游戏者的姓名,单击“确定”后会弹出游戏的记录框。可看到自己的排行。
该游戏最终能够顺利的运行,功能基本都以实现。由于时间与能力有限,该游戏还有很大的优化与扩展空间,还有待改进。
附录:源代码
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("请输入你的图片到");
label.setBounds(10, 15, 190, 30);
panel[0].add(label);
label = new JLabel("\"背景图片\"文件夹。\n");
label.setBounds(10, 30, 190, 45);
panel[0].add(label);
label = new JLabel("单击\"选择->背景图片\"");
label.setBounds(10, 50, 190, 65);
panel[0].add(label);
label = new JLabel("选择图片。\n");
label.setBounds(10, 65, 190, 80);
panel[0].add(label);
label = new JLabel("接着, 单击 \"开始->新游戏\" 可以");
label.setBounds(10, 85, 190, 100);
panel[0].add(label);
label = new JLabel("开始游戏。");
label.setBounds(10, 100, 190, 115);
panel[0].add(label);
panel[1].setLayout(new BorderLayout());
JButton button = new JButton("继 续");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
FrameGetFocus();
}
}
);
panel[1].add(button, BorderLayout.CENTER);
con.add(panel[0], "游戏");
con.add(panel[1], "暂停");
card.show(con, "游戏");
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", "风铃",888888, 666666);
fout.printf("%s %d %d\n", "天使",777777, 444444);
fout.printf("%s %d %d\n", "撒旦",555555, 566666);
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,"你打破了记录!\n请输入你的名字。");
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", "等级", "姓名", "时间", "步数");
String h = "".format("%8s%15s%8d%8d\n", "困难", data[0].name, data[0].time, data[0].step);
String n = "".format("%8s%15s%8d%8d\n", "普通", data[1].name, data[1].time, data[1].step);
String e = "".format("%8s%15s%8d%8d\n", "简单", 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("开始(B)"),
new JMenu("选择(O)"),
new JMenu("关于(A)")
};
private JMenu [] mm = {
new JMenu("等级(L)"),
new JMenu("背景图片(B)")
};
private boolean update;
private int type;
private String filename;
protected ButtonGroup bgrp = new ButtonGroup();
protected ButtonGroup fgrp = new ButtonGroup();
public MenuFrame()
{
super("拼图游戏");
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("困难"))
type = 0;
else if (nm.equals("普通"))
type = 1;
else if (nm.equals("简单"))
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("新游戏(N)"),
new JMenuItem("成绩记录(G)"),
new JMenuItem("退出游戏(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("困难"),
new JRadioButtonMenuItem("普通"),
new JRadioButtonMenuItem("简单")
};
for (int i = 0; i < 3; i++)
{
m
展开阅读全文