Java小專案_拼圖遊戲_基本功能實現
阿新 • • 發佈:2018-12-23
前言
利用按鈕元件以及圖片的嵌入完成基本遊戲的搭建,其中按鈕事件監聽是本程式碼的難點。以及事先要規劃好基本模組,包括遊戲的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這種對映狀況或者其再組合的情況是無解的,所以隨機的同時應該將出現能夠重組合得到該情況的序列剪枝