暑期实习成果保留(一)day09
初步使用Java GUI编程,实现了简易的拼图游戏。功能很简单,只实现了图片的移动和拼接,另外附加一个步数累计label控制步数。
1、初步实现界面布局设计
上半部分:窗体左上角显示参照图片,右上角依次为“换一张图片”“步数累计”“开始游戏”三个提示界面。
下半部分:分为4*4的网格,每个网格存放一张原图碎片或空白格。与空白格相邻的格子可以点击移动。
2、完善游戏过关功能
当所有碎片回归原位后,提示“恭喜过关,是否继续?”
点击“是”则重新打开下一张图片,继续游戏。
点击“否”或者直接关闭主窗口即可退出游戏。
private JLabel modeLabel;//上半部分的控件,在左上角显示参照图片 (游戏控制控件的设计不对用户开放,设置为私有)
private int num = 0;// 表示参照图片序号
private JPanel centerJPanel;//下半部分,游戏区的控件画板
private JButton emptyButton;//表示空白格
private String[][] res;//保存移动后的格子的坐标
private JLabel timeLabel;//步数累计控件label
private int step=0;//保存走过的步数
private boolean start=false;//开始标志
public static void main(String[] args) {
PuzzleGameMain gameMain = new PuzzleGameMain();
gameMain.setVisible(true);
}
// 重写构造函数,实现游戏界面设计
public PuzzleGameMain() {
this.setResizable(false);// 设置窗体大小不可变
this.setTitle("PuzzleGame");
this.setBounds(500, 300, 370, 525);// 设置窗体位置及大小
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体点击关闭窗口的同时关闭进程
// 创建上面的面板,设置布局
JPanel topPanel = new JPanel();//上半部分画板
topPanel.setBorder(new TitledBorder(null, "",
TitledBorder.DEFAULT_JUSTIFICATION,
TitledBorder.DEFAULT_POSITION, null, null));//设置边框格式
topPanel.setLayout(new BorderLayout());
this.getContentPane().add(topPanel, BorderLayout.NORTH);//添加该画板到窗口北面(最上方)
// 在面板上添加控件
modeLabel = new JLabel();//显示参照图的label
modeLabel.setIcon(new ImageIcon("image/" + num + "model.jpg"));//将参照图添加到label中
topPanel.add(modeLabel, BorderLayout.WEST);//将参照图label添加到上半部分画板的西面(左侧)
// 在topPanel的右边添加一个新的panel,存放两个控制按钮和步数累计label
JPanel topPanelR = new JPanel();
topPanel.add(topPanelR, BorderLayout.CENTER);//将新的画板添加到上半部分画板的中间
topPanelR.setLayout(new BorderLayout());
// 向新的panel添加按钮控件
JButton button1 = new JButton();
button1.setText("换一张图片");
topPanelR.add(button1, BorderLayout.NORTH);
button1.addActionListener(new button1ActionListener());
JButton button2 = new JButton();
button2.setText("开始游戏");
button2.setBackground(Color.cyan);
topPanelR.add(button2, BorderLayout.SOUTH);
button2.addActionListener(new button2ActionListener());
timeLabel = new JLabel();
timeLabel.setText("步数累计:"+step);
timeLabel.setBackground(Color.pink);
timeLabel.setOpaque(true);//将label的背景颜色显示出来
topPanelR.add(timeLabel,BorderLayout.CENTER);
// 绘制游戏主界面
centerJPanel = new JPanel();
centerJPanel.setBorder(new TitledBorder(null, "",
TitledBorder.DEFAULT_JUSTIFICATION,
TitledBorder.DEFAULT_POSITION, null, null));
centerJPanel.setLayout(new GridLayout(4, 0));// 设置为拆分
this.getContentPane().add(centerJPanel, BorderLayout.CENTER);
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
JButton button = new JButton();
button.setName(row + "" + col);
// 设置图片点击移动监听
button.addActionListener(new ImgButtonAction());
// 图片顺序显示
button.setIcon(new ImageIcon("image/" + num + row + col
+ ".jpg"));
centerJPanel.add(button);
}
}
}
// 随机排列图片
private String[][] reorder() {
String[][] order1 = new String[4][4];
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
order1[row][col] = "image/" + num + row + col + ".jpg";
}
}
// 乱序
res = new String[4][4];
// res =order1;
// String temp;
// temp=res[0][0];
//
// res[0][0]=order1[1][0];
// order1[1][0]=temp;
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
while (res[row][col] == null) {
int r = (int) (Math.random() * 4);
int c = (int) (Math.random() * 4);
if (order1[r][c] != null) {
res[row][col] = order1[r][c];
}
order1[r][c] = null;
}
}
}
return res;
}
// 下一张按钮的监听事件实现
class button1ActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
start=false;
int i = 0;
if (num == 5)
num = 0;
else
num++;
modeLabel.setIcon(new ImageIcon("image/" + num + "model.jpg"));
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
JButton button = (JButton) centerJPanel.getComponent(i++);
button.setIcon(new ImageIcon("image/" + num + row + col
+ ".jpg"));
}
}
}
}
// 开始游戏按钮的监听事件实现
class button2ActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
start=true;
int i = 0;
String[][] order = reorder();
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
JButton button = (JButton) centerJPanel.getComponent(i++);
button.setIcon(new ImageIcon(order[row][col]));
if (order[row][col].equals("image/" + num + "00.jpg")) {
emptyButton = button;
}
}
}
}
}
// 图片移动事件实现
class ImgButtonAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if(!start){
JOptionPane.showConfirmDialog(null, "请点击开始游戏后再点击!", "Wrong", JOptionPane.CLOSED_OPTION);
}
String emptyName = emptyButton.getName();
char emptyRow = emptyName.charAt(0);
char emptyCol = emptyName.charAt(1);
JButton clickButton = (JButton) e.getSource();
String clickName = clickButton.getName();
char clickRow = clickName.charAt(0);
char clickCol = clickName.charAt(1);
if (Math.abs(clickCol - emptyCol) + Math.abs(clickRow - emptyRow) == 1) {
Icon clickIcon = clickButton.getIcon();
emptyButton.setIcon(clickIcon);
emptyButton = clickButton;
step++;
// System.out.println(step);
timeLabel.setText("步数:"+step);
if(step>=100){
int YON = JOptionPane.showConfirmDialog(null, "对不起,步数超限,游戏结束!是否要重新开始?", "GameOver", JOptionPane.YES_NO_OPTION);
if(YON!=0){
System.exit(0);;
}else{
step=0;
timeLabel.setText("步数:"+step);
button2ActionListener a=new button2ActionListener();
a.actionPerformed(e);
}
}
String tempString = res[emptyRow-'0'][emptyCol-'0'];
res[emptyRow-'0'][emptyCol-'0'] = res[clickRow-'0'][clickCol-'0'];
res[clickRow-'0'][emptyCol-'0'] = tempString;
clickButton.setIcon(new ImageIcon("image/" + num + "00.jpg"));
}
int rightNum = 0;// 表示在正确位置的图片数
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
if(res[row][col].equals("image/" + num + row + col+".jpg")){
rightNum++;
}
}
}
if(rightNum==16){
int YON =JOptionPane.showConfirmDialog(null, "恭喜过关!是否继续?", "Winner", JOptionPane.YES_NO_OPTION);
if(YON!=0){
System.exit(0);;
}else{
num++;
button1ActionListener a = new button1ActionListener();
a.actionPerformed( e);
button2ActionListener b=new button2ActionListener();
b.actionPerformed(e);
}
}
}
}
}