一、该游戏一共有五个类
游戏代码下载地址http://download.youkuaiyun.com/detail/gj_user/9737656
1、 MainPictureFrame进行界面初始化
public class MainPictureFrame extends JFrame{
private static final String[] items ={"小狗子"};//下拉框内容初始化
private PreviewPicturePanel picturePanel;//图片预览区
private PlayGamePanel gamePanel;//拼图区
private JComboBox<String> box;//jCombobox下拉框
private JTextField name;//图片名称框
public static JTextField step;//统计游戏步数
private JRadioButton cleanButton;//清除提示
private JButton startButton;//开始游戏按钮
private JPanel panel;
public MainPictureFrame(String gameName){
super(gameName);
init();
view();
addPicture();
}
private void addPicture() {
panel = new JPanel();
//panel.setBackground(Color.pink);
panel.setLayout(new GridLayout(1, 2));//创建面板设置布局为Grid一行两列
gamePanel = new PlayGamePanel();//游戏区设置
gamePanel.setBorder(new TitledBorder("游戏区"));//设置标题框
picturePanel = new PreviewPicturePanel();//游戏区
picturePanel.setBorder(new TitledBorder("预览区"));
//将面板分成两列分别加到panel面板上
panel.add(gamePanel);
panel.add(picturePanel);
this.add(panel);
}
private void view() {
//为上面的按钮区和游戏状态区添加相关部件
JPanel panel=new JPanel();
panel.setLayout(new GridLayout(1, 2));
this.add(panel,BorderLayout.NORTH);
JPanel leftPanel=new JPanel();//左边的按钮区
leftPanel.setBorder(new TitledBorder("按钮区"));
JRadioButton numButton=new JRadioButton("数字提示",false);
numButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
gamePanel.addNumber();
}
});
cleanButton = new JRadioButton("清除提示",true);
cleanButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.clearNumber();//调用该类中的方法
}
});
//ButtonGroup的作用是将JRadioButton按钮只能选择一个
ButtonGroup group=new ButtonGroup();
group.add(cleanButton);
group.add(numButton);
box = new JComboBox<String>(items);
box.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
int n=box.getSelectedIndex();//获取选择的下标,从0开始
PlayGamePanel.pictureID=n+1;
picturePanel.repaint();//当选择图片时进行重新绘制图片
gamePanel.clearNumber();
name.setText("图片名称:"+box.getSelectedItem());
int stepNum=gamePanel.stepNum;
step.setText("步数:"+stepNum);
cleanButton.setSelected(true);
}
});
startButton = new JButton("开始");
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.stepNum=0;
step.setText("步数:"+gamePanel.stepNum);
gamePanel.start();
}
});
leftPanel.add(numButton);
leftPanel.add(cleanButton,BorderLayout.WEST);
leftPanel.add(new JLabel("选择图片"));
leftPanel.add(box);
leftPanel.add(startButton);
JPanel rightPanel=new JPanel();
rightPanel.setBorder(new TitledBorder("游戏状态"));
rightPanel.setLayout(new GridLayout(1,2));
name = new JTextField("图片名称");
step = new JTextField("步数");
rightPanel.add(name);
rightPanel.add(step);
//设置步数和图片名称不可编辑
step.setEditable(false);
name.setEditable(false);
panel.add(leftPanel,BorderLayout.WEST);
panel.add(rightPanel);
}
private void init() {
this.setTitle("拼图游戏");
this.setSize(1000, 720);//454 597
this.setLocation(100,0);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2、PlayGamePanel拼图区的相关方法
public class PlayGamePanel extends JPanel implements MouseListener {
private Cell[] cells;
private ImageIcon icon;
public static int pictureID = 1;//小图片的序号
public static int stepNum = 0;//步数
private boolean hasListener = false;//判断小方格是否有鼠标监听事件
private Rectangle nullcell;//空方格
public PlayGamePanel() {
this.setLayout(null);// 帧布局
cells = new Cell[12];//定义一个有十二张图片的小方格
for (int i = 0; i < 4; i++) {//行数
for (int j = 0; j < 3; j++) {//列数
icon = new ImageIcon("images\\1_" + (i * 3 + j + 1) + ".gif");
cells[3 * i + j] = new Cell(icon);
cells[3 * i + j].setLocation(150 * j + 20, 150 * i + 20);
this.add(cells[3 * i + j]);
//3*i+j+1遍历1-12张图片
}
}
this.remove(cells[11]);//第十二个图片被移除用来交换图片
nullcell = new Rectangle(300 + 20, 450 + 20, 150, 150);//空方格位置大小
}
//添加数字提示
public void addNumber() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
ImageIcon icon = new ImageIcon("images\\1_" + (i * 3 + j + 1)
+ ".gif");
cells[3 * i + j].setIcon(icon);
cells[3 * i + j].setText("" + (3 * i + j + 1));
//显示位置居中
cells[3 * i + j].setHorizontalTextPosition(this.getX());
cells[3 * i + j].setVerticalTextPosition(this.getY() / 2);
}
}
}
//清除数字提示
public void clearNumber() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
ImageIcon icon = new ImageIcon("images\\" + pictureID + "_"
+ (i * 3 + j + 1) + ".gif");
cells[3 * i + j].setIcon(icon);
cells[3 * i + j].setLocation(150 * j + 20, 150 * i + 20);
cells[3 * i + j].setText("");
cells[3*i+j].repaint();
}
}
}
public void start() {
//添加鼠标监听事件
if (!hasListener) {
for (int i = 0; i < 11; i++) {
cells[i].addMouseListener(this);
}
hasListener = true;
}
//当第一个方格不在1,2,4,5就和空方格交换位置
while (cells[0].getBounds().x <= 170 && cells[0].getBounds().y <= 170) {
// 获取到空方格的位置
int nullX = nullcell.getBounds().x;
int nullY = nullcell.getBounds().y;
// 产生一个方向空方格进行互换
// 产生随机数
int dir = (int) (Math.random() * 4);
switch (dir) {
case 0:
nullY-=150;
cellMove(nullX,nullY,"下");
break;
case 1:
nullY+=150;
cellMove(nullX,nullY,"上");
break;
case 2:
nullX-=150;
cellMove(nullX,nullY,"右");
break;
case 3:
nullX+=150;
cellMove(nullX,nullY,"左");
break;
}
}
}
//和空方格交换位置
private void cellMove(int nullX,int nullY,String dir) {
for (int i = 0; i < 11; i++) {
if (cells[i].getBounds().x==nullX&&cells[i] .getBounds().y==nullY){
cells[i].move(dir);
nullcell.setLocation(nullX,nullY);
break;
}
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
//获取点击小方格的坐标
Cell buttenCell=(Cell) e.getSource();
int cellX=buttenCell.getBounds().x;
int cellY=buttenCell.getBounds().y;
//空方格坐标
int nullX=nullcell.getBounds().x;
int nullY=nullcell.getBounds().y;
//是否满足点击交换条件
if (cellX==nullX&&cellY-nullY==150) {
buttenCell.move("上");
}
else if (cellX==nullX&&cellY-nullY==-150) {
buttenCell.move("下");
}
else if (cellX-nullX==150&&cellY==nullY) {
buttenCell.move("左");
}
else if(cellX-nullX==-150&&cellY==nullY){
buttenCell.move("右");
}
else {
return;
}
nullcell.setLocation(cellX,cellY);
this.repaint();
//更新步数
stepNum++;
MainPictureFrame.step.setText("步数:"+stepNum);
if (this.isFinish()) {
JOptionPane.showMessageDialog(this, "哈哈!终于拼成功了\n 所用步数:"+stepNum);
for (int i = 0; i < 11; i++) {
cells[i].removeMouseListener(this);
hasListener=false;
}
}
}
//判断是否完成游戏
private boolean isFinish() {
for (int i = 0; i < 11; i++) {
int x=cells[i].getBounds().x;
int y=cells[i].getBounds().y;
if ((y-20)/150*3+(x-20)/150!=i) {
return false;
}
}
return true;
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
3、PreviewPanel图片预览区的相关方法
public class PreviewPicturePanel extends JPanel{
protected void paintComponent(Graphics g) {
//指定图片路径
String path="images\\"+PlayGamePanel.pictureID+".jpg";
//获取图片
ImageIcon icon=new ImageIcon(path);
Image image=icon.getImage();
//画图
g.drawImage(image,20, 20,480,600,this);
}
}
4、Cell对拼图小方格进行初始化
public class Cell extends JButton {
public Cell(Icon icon) {
super(icon);
this.setSize(155, 150);
}
public Cell(String text, Icon icon) {
super(text, icon);
this.setSize(150, 150);
this.setHorizontalAlignment(CENTER);
this.setVerticalAlignment(CENTER);
}
//四种方格移动位置变化
public void move(String dir) {
switch (dir) {
case "上":
this.setLocation(this.getBounds().x,this.getBounds().y-150);
break;
case "下":
this.setLocation(this.getBounds().x,this.getBounds().y+150);
break;
case "左":
this.setLocation(this.getBounds().x-150,this.getBounds().y);
break;
case "右":
this.setLocation(this.getBounds().x+150,this.getBounds().y);
break;
}
}
}
5、Test启动类
public class Test {
public static void main(String[] args) {
MainPictureFrame frame=new MainPictureFrame("拼图游戏");
frame.setVisible(true);
}
}