前言
利用按钮组件以及图片的嵌入完成基本游戏的搭建,其中按钮事件监听是本代码的难点。以及事先要规划好基本模块,包括游戏的UI窗口、操作模块以及代码逻辑设计。
启动代码:
package API_UI_拼图游戏2;
public class start {
public static void main(String[] args) {
// TODO Auto-generated method stub
new UI_Bulid();
}
}
窗口容器代码:
package API_UI_拼图游戏2;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
class Mid_Panel extends JPanel{ //中部容器
Button_remote[] btn = new Button_remote[25]; //按钮控件 以下默认最大只有5X5规模
ImageIcon[] image = new ImageIcon[25]; //图片库
int cutSize; //行or列规模
int total; //图片总数
int[] squence = new int[25]; //随机顺序
int tag; //空白位置
int Now_Size;
Mid_Panel(String Image_Path,int cutSize) {
Now_Size = 0;
this.setRandomPanel(Image_Path,cutSize);
}
public void setRandomPanel(String Image_Path,int cutSize) {
this.cutSize = cutSize;
this.total = cutSize * cutSize;
this.tag = total-1;
this.removeAll();
this.updateUI();
this.setLayout(new GridLayout(cutSize,cutSize));
this.setRandom();
for(int i=0;i<total;i++) {
btn[i] = new Button_remote();
btn[i].setRow(i / cutSize);
btn[i].setRank(i % cutSize);
btn[i].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
Button_remote button = (Button_remote) e.getSource();
Mid_Panel.this.change(button);
}
});
this.add(btn[i]);
}
for(int i=0;i<total-1;i++) {
image[i] = new ImageIcon(Image_Path+"\\"+(squence[i]+1)+".jpg");
btn[i].setIcon(image[i]);
}
}
public void setRandom() {
Random random = new Random();
boolean[] mark = new boolean[total];
Arrays.fill(mark, true);
for(int i=0,num;i<total-2;i++) {
num = random.nextInt(total-1); //[0,total-1)
if(mark[num]) {
mark[num] = false;
squence[i] = num;
} else {
i--;
}
}
for(int i=0;i<total-1;i++) { //避免最后一个随机很久都没找到
if(mark[i]) {
squence[total-2] = i;
break;
}
}
squence[total-1] = total-1;
}
private boolean Judge(int x,int y,int ax,int ay) {
if(ax == x && Math.abs(ay - y)==1 || ay == y && Math.abs(ax - x)==1) {
return true;
}else {
return false;
}
}
private boolean isWin() {
for(int i=0;i<total-1;i++) {
if(squence[i] != i) {
return false;
}
}
return true;
}
public void change(Button_remote button) {
int x = button.getRow();
int y= button.getRank();
int ax = btn[tag].getRow();
int ay = btn[tag].getRank();
if(Judge(x, y, ax, ay)) {
ImageIcon img = (ImageIcon)button.getIcon();
button.setIcon(null);
btn[tag].setIcon(img);
int temp = x*cutSize+y;
squence[tag]^=squence[temp];
squence[temp]^=squence[tag];
squence[tag]^=squence[temp];
this.tag = temp;
this.Now_Size++;
if(isWin()) {
}
}
}
}
/* * squence[position]:在position位置对应的图片名称 * */
操作界面代码:
package API_UI_拼图游戏2;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
class UI_Bulid extends JFrame {
Mid_Panel panel;
String Image_Path; //图片路径
int cutSize; //图片切割的数量
JMenuBar bar; //菜单的顶层容器
JMenu MenuMain,MenuOther,MenuChange;
JMenuItem ItemRecord,ItemStart,ItemExit,ItemView,ItemBook;
JRadioButtonMenuItem[] Game_Difficult = new JRadioButtonMenuItem[3];
public UI_Bulid() {
this.setTitle("Game");
this.setSize(580,571);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.addWindowListener(new Exit_Query());
this.setMenu();
this.setDifficult();
this.setMenuControl();
panel = new Mid_Panel(Image_Path, cutSize);
this.add(panel);
this.setVisible(true);
}
class Exit_Query extends WindowAdapter {
private UI_Bulid illustrate;
@Override
public void windowClosing(WindowEvent e) { //注意!!这里是要重写windowClosing而不是windowClosed!!一个是点击关闭的事情一个是关闭后的事情 - -
// TODO Auto-generated method stub
super.windowClosed(e);
int chose = JOptionPane.showConfirmDialog(illustrate, "你真的要退出吗?");
if(chose == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
}
public void setPath(String Image_Path) {
this.Image_Path = Image_Path;
}
public void setcutSize(int cutSize) {
this.cutSize = cutSize;
}
public void setDifficult() {
this.Image_Path = "ImageElem\\Elem_1";
this.cutSize = 3;
for(int i=0;i<Game_Difficult.length;i++) {
if(Game_Difficult[i].isSelected()) {
this.Image_Path = "ImageElem\\Elem_"+(i+1);
this.cutSize = i+3;
break;
}
}
}
public void setMenu() {
bar = new JMenuBar();
MenuMain = new JMenu("菜单");
MenuOther = new JMenu("其他");
MenuChange = new JMenu("难度");
ItemRecord = new JMenuItem("纪录");
ItemStart = new JMenuItem("开始");
ItemExit = new JMenuItem("退出");
ItemView = new JMenuItem("答案");
ItemBook = new JMenuItem("关于");
this.setJMenuBar(bar);
bar.add(MenuMain);
bar.add(MenuOther);
MenuMain.add(ItemStart);
MenuMain.add(ItemView);
MenuMain.add(MenuChange);
MenuMain.add(ItemExit);
MenuOther.add(ItemRecord);
MenuOther.add(ItemBook);
ButtonGroup Size_1 = new ButtonGroup(); //添加一组单选关系组
String str;
for (int i = 0; i < Game_Difficult.length; i++) {
switch(i) {
case 0:
str = "Simple";
break;
case 1:
str = "Ordinary";
break;
default:
str = "Hard";
break;
}
Game_Difficult[i] = new JRadioButtonMenuItem(str);
Size_1.add(Game_Difficult[i]);
MenuChange.add(Game_Difficult[i]);
}
Game_Difficult[0].setSelected(true); //默认简单选项
}
public void setMenuControl() {
this.ItemStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
// System.out.println("Restart!");
UI_Bulid.this.setDifficult();
// System.out.println(Image_Path+"\n"+cutSize);
panel.setRandomPanel(Image_Path, cutSize);
}
});
this.ItemExit.addActionListener(new ActionListener() {
private UI_Bulid illustrate;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
int chose = JOptionPane.showConfirmDialog(illustrate, "你真的要退出吗?");
if(chose == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
this.ItemView.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JFrame findMechine = new JFrame("完成图案");
JButton btn = new JButton(new ImageIcon("ImageElem\\Index_01.jpg"));
findMechine.add(btn);
findMechine.setSize(580,571);
findMechine.setResizable(false);
findMechine.setLocationRelativeTo(null);
findMechine.setVisible(true);
}
});
}
}
拼图按钮类:
package API_UI_拼图游戏2;
import javax.swing.JButton;
class Button_remote extends JButton{
private int row; //行
private int rank; //列
/** * @return the row */
public int getRow() {
return row;
}
/** * @param row the row to set */
public void setRow(int row) {
this.row = row;
}
/** * @return the rank */
public int getRank() {
return rank;
}
/** * @param rank the rank to set */
public void setRank(int rank) {
this.rank = rank;
}
}
总结
类梳理
- JFrame用来创建application
- JApplet用来创建applet
- JDialog用来创建对话框
- JPanel提供一个面板
- JScrollPane是具有滚动条的窗格
- JSplitPane是具有拆分功能的窗格
- JTabbedPane是带有若干标签的分类窗格
- JInternalFrame用于创建内嵌于JFrame中的内部框架
- Box提供创建横向/纵向盒子容器的功能
基本组件总结
改进:
- 游戏没有加入多线程部分
- 部分菜单模块的功能还未实现
- 游戏随机生成的拼图模块顺序可能本身存在BUG(永远Accept不了):当出现12345687这种映射状况或者其再组合的情况是无解的,所以随机的同时应该将出现能够重组合得到该情况的序列剪枝