接上篇
9.1)计步功能
定义一个成员变量用来计步
在initImage
中添加计步图标
在keyReleased
方法中每摁一个上下左右键就自增一次
9.2)菜单业务实现
重新开始
1.给重新游戏绑定点击事件ActionListener
2.重新打乱二维数组中的数字
3.加载图片
4.计步器清零
(obj == replayItem){
System.out.println("重新游戏");
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}
重新登录
else if(obj == reLoginItem){
System.out.println("重新登录");
//关闭当前界面
this.setVisible(false);
//打开登录界面
new LoginJFrame();
}
关闭游戏
1.给关闭游戏绑定事件
2.结束虚拟机,关闭所有
else if(obj == closeItem){
System.out.println("关闭游戏");
//直接关闭虚拟机即可
System.exit(0);
}
关于我们
弹出公众号 弹窗JDialog
else if(obj == accountItem){
System.out.println("优快云");
//创建一个弹框对象
JDialog jDialog = new JDialog();
//创建一个管理图片的容器对象
JLabel jLabel = new JLabel(new ImageIcon("image\\优快云.jpg"));
jLabel.setBounds(0,0,258,258);
//添加图片到弹框
jDialog.getContentPane().add(jLabel);
jDialog.setSize(344,344);
//置顶,居中
jDialog.setAlwaysOnTop(true);
jDialog.setLocationRelativeTo(null);
//弹框不关闭无法操作下面界面
jDialog.setModal(true);
//显示出来
jDialog.setVisible(true);
更换图片
- 在成员变量中创建更换图片选项,
- 再创建三个选项表示要更换的图片类型,
- 把三个小选项添加到更换图片下,
- 给三个选项设置动作监听,
- 并在actionPerformed下添加各自的事件
else if(obj == ysItem){
System.out.println("更换ys照片");
Random r = new Random();
int index = r.nextInt(pathMore.length);
path = pathMore[index];
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}else if(obj == animalItem){
System.out.println("更换动物图片");
path = "image\\sc\\4.cat\\";
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}else if(obj == mrlItem){
System.out.println("恢复默认图片");
path = "image\\sc\\1.red\\";
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}
10)登录界面
实现步骤:
- 对主界面进行设置
- 在主界面添加用户名和密码以及登录,注册按钮
- 对登录按钮绑定鼠标事件
主界面设置:
设置大小
设置居中
设置置顶
设置关闭模式
取消内部布局
让界面可见
添加组件
创建JLabel添加用户名文字
对用户名文字设置位置和宽高:116, 135, 51, 19
创建用户名的文本输入框:JTextField
对用户名的文本输入框设置位置和宽高:195, 134, 200, 30
创建JLabel添加密码文字
对密码文字设置位置和宽高:130, 195, 35, 18
创建密码的文本输入框:JTextField
对密码的文本输入框设置位置和宽高:195, 195, 200, 30
创建登录的按钮:JButton
利用setIcon方法给登录按钮设置背景色
对登录的按钮设置位置和宽高:133, 260, 90, 40
创建注册的按钮:JButton
利用setIcon方法给注册按钮设置背景色
对登录的按钮设置位置和宽高:256, 260, 90, 40
创建背景色:JLabel
给背景色设置位置和宽高:0, 0, 470, 390
将上面7个组件添加到主界面的中心面板中
绑定事件:
给登录按钮绑定鼠标事件
当按下不松的时候:利用setIcon方法,修改登录按钮的背景色为蓝色
当松开的时候:利用setIcon方法,将按钮的背景色修改为红色
当点击的时候:校验用户输入的用户名和密码是否正确。
mouseClicked方法详解:
先判断当前按下的是否为登录按钮。
如果是登录按钮,获取输入框中的用户名和密码
判断1:是否为空,如果为空,提示:用户名和密码为空
判断2:判断用户名和密码是否为zhangsan,123456,如果正确隐藏登录界面,进入游戏界面。
判断3:判断用户吗和密码,如果错误,就展示弹框,提示:用户名和密码错误
展示弹框步骤:
成员位置创建JDialog对象
利用isVisible方法判断弹框是否存在,如果不存在则进行下面操作:
设置弹框的宽和高:100,100
设置弹框居中
设置弹框置顶
移除弹框中所有文本
创建一个JLabel去编写文本内容
把文本JLabel添加到弹框当中
把弹框展示出来
(代码部分请看黑马程序员Java课程资料)
11)把游戏打包成exe
GameJFrame·完整代码
package com.r.ui;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.security.Key;
import java.util.Random;
public class GameJFrame extends JFrame implements KeyListener , ActionListener {
int[][] data = new int[4][4];//随机数组
int x = 0,y = 0;//记录空白在数组中的位置
int step = 0;//统计步数
//定义一个变量记录当前展示图片的路径
String path = "image\\sc\\1.red\\";
String[] pathMore = {"image\\sc\\2.TV\\","image\\sc\\3.sport\\","image\\sc\\5.ride\\","image\\sc\\6.d&y\\"};
//判断胜利数组
int[][] win = {
{16,15,14,13},
{12,11,10,9},
{8,7,6,5},
{4,3,2,0}
};
//创建选项下的条目
JMenu rePictureMenu = new JMenu("更换图片");
JMenuItem ysItem = new JMenuItem("鱼");
JMenuItem animalItem = new JMenuItem("动物");
JMenuItem mrlItem = new JMenuItem("恢复默认");
JMenuItem replayItem = new JMenuItem("重新游戏");
JMenuItem reLoginItem = new JMenuItem("重新登录");
JMenuItem closeItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("优快云");
//初始化
public GameJFrame(){
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化数据(打乱)
initData();
//初始化图片
initImage();
//让界面显示出来,建议写在最后
this.setVisible(true);
}
//生成一个随机数组
private void initData() {
int[] temArr = {0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
Random r = new Random();
for (int i = 0; i < temArr.length; i++) {
int index = r.nextInt(temArr.length);
int tem = temArr[i];
temArr[i] = temArr[index];
temArr[index] = tem;
}
for (int i = 0; i < temArr.length; i++) {
System.out.print(temArr[i] + ",");
}
System.out.println();
for (int i = 0; i < temArr.length; i++) {
if(temArr[i] == 0){
x = i / 4;
y = i % 4;
data[x][y] = 0;
}
else{
data[i / 4][i % 4] = temArr[i];
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(data[i][j] + ",");
}
System.out.println();
}
}
//初始化图片
private void initImage() {
//清空原本已经出现的所有图片
this.getContentPane().removeAll();
if(victory()){
//显示胜利图标
JLabel winJLabel = new JLabel(new ImageIcon("E:\\r\\r1\\idea\\game\\image\\win.png"));
winJLabel.setBounds(203, 283, 197, 73);
this.getContentPane().add(winJLabel);
}
JLabel stepCount = new JLabel("步数:" + step);
stepCount.setBounds(50, 30, 100, 20);
this.getContentPane().add(stepCount);
//先加载的图片在上方 后加载的图片在下方
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
//获取当前要加载图片的序号(已打乱)
int num = data[i][j];
//创建一个JLabel的对象(管理容器)
JLabel jLabel = new JLabel(new ImageIcon(path + num + ".jpg"));
//指定图片位置
jLabel.setBounds(105*j + 83,105*i + 134,105,105);//x y 宽度 高度
//给图片添加边框
//0:表示让图片凸起来
//1:表示让图片凹下去
jLabel.setBorder(new BevelBorder(0));
//把管理容器添加到界面中
this.getContentPane().add(jLabel);//先获取隐藏容器再把图片添加进去
//刷新一下界面
this.getContentPane().repaint();
}
}
//添加背景图片
JLabel background = new JLabel(new ImageIcon("image\\background.png"));
background.setBounds(40,40,508,560);
//把背景添加到页面内
this.getContentPane().add(background);
}
//初始化菜单
private void initJMenuBar() {
//创建整个的菜单对象
JMenuBar jMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//将选项下的条目添加到选项下
functionJMenu.add((rePictureMenu));
functionJMenu.add(replayItem);
functionJMenu.add(reLoginItem);
functionJMenu.add(closeItem);
//把选项放到更换图片选项下
rePictureMenu.add(ysItem);
rePictureMenu.add(animalItem);
rePictureMenu.add(mrlItem);
aboutJMenu.add(accountItem);
//给条目绑定事件
replayItem.addActionListener(this);
reLoginItem.addActionListener(this);
closeItem.addActionListener(this);
accountItem.addActionListener(this);
//给ys 动物和恢复默认绑定事件
ysItem.addActionListener(this);
animalItem.addActionListener(this);
mrlItem.addActionListener(this);
//将菜单里的两个选项添加到菜单中
jMenuBar.add(functionJMenu);
jMenuBar.add(aboutJMenu);
//给整个界面设置菜单
this.setJMenuBar(jMenuBar);
}
//初始化界面
private void initJFrame() {
//设置界面宽高
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置关闭模式
this.setDefaultCloseOperation(3);
//取消默认的居中放置
this.setLayout(null);
//给整个界面添加键盘监听事件
this.addKeyListener(this);
}
@Override
public void keyPressed(KeyEvent e) {
//按下不松时调用这个方法
int code = e.getKeyCode();
if(code == 65){
//把界面中所有的图片全部删除
this.getContentPane().removeAll();
//加载第一张完整的图片
JLabel all = new JLabel(new ImageIcon(path + "all.jpg"));
all.setBounds(83,134,420,420);
this.getContentPane().add(all);
//加载背景图片
JLabel background = new JLabel(new ImageIcon("image\\background.png"));
background.setBounds(40,40,508,560);
//把背景添加到页面内
this.getContentPane().add(background);
//刷新页面
this.getContentPane().repaint();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
//判断游戏是否胜利,若胜利此方法结束不能再继续执行下面操作
if(victory()){
return;//结束方法
}
//对上下左右进行判断
//左37 上38 右39 下40
int code = e.getKeyCode();
if(code ==37){
System.out.println("向左移动");
if(y == 3){
return;
}
//空白方块右方数字左移
data[x][y] = data[x][y + 1];
data[x][y + 1] = 0;
y++;
//每移动一次步数自增一次
step++;
//调用方法加载图片
initImage();
}else if(code ==38){
System.out.println("向上移动");
if(x == 3){
return;
}
//把空白方块下方数字上移
data[x][y] = data[x + 1][y];
data[x + 1][y] = 0;
x++;
//每移动一次步数自增一次
step++;
//调用方法加载图片
initImage();
}else if(code ==39){
System.out.println("向右移动");
if(y == 0){
return;
}
//空白方块左方数字右移
data[x][y] = data[x][y - 1];
data[x][y - 1] = 0;
y--;
//每移动一次步数自增一次
step++;
//调用方法加载图片
initImage();
}else if(code ==40){
System.out.println("向下移动");
if(x == 0){
return;
}
//空白方块上方数字下移
data[x][y] = data[x - 1][y];
data[x - 1][y] = 0;
x--;
//每移动一次步数自增一次
step++;
//调用方法加载图片
initImage();
}else if(code == 65){
initImage();
}else if(code == 87){
data = new int[][]{
{16,15,14,13},
{12,11,10,9},
{8,7,6,5},
{4,3,2,0}
};
initImage();
}
}
//判断data是否跟win一样
public boolean victory(){
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(data[i][j] != win[i][j]){
return false;
}
}
}
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
//获取当前被点击的条目对象
Object obj = e.getSource();
if(obj == replayItem){
System.out.println("重新游戏");
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}else if(obj == reLoginItem){
System.out.println("重新登录");
//关闭当前界面
this.setVisible(false);
//打开登录界面
new LoginJFrame();
}else if(obj == closeItem){
System.out.println("关闭游戏");
//直接关闭虚拟机即可
System.exit(0);
}else if(obj == accountItem){
System.out.println("优快云");
//创建一个弹框对象
JDialog jDialog = new JDialog();
//创建一个管理图片的容器对象
JLabel jLabel = new JLabel(new ImageIcon("image\\优快云.jpg"));
jLabel.setBounds(0,0,258,258);
//添加图片到弹框
jDialog.getContentPane().add(jLabel);
jDialog.setSize(344,344);
//置顶,居中
jDialog.setAlwaysOnTop(true);
jDialog.setLocationRelativeTo(null);
//弹框不关闭无法操作下面界面
jDialog.setModal(true);
//显示出来
jDialog.setVisible(true);
}else if(obj == ysItem){
System.out.println("更换ys照片");
Random r = new Random();
int index = r.nextInt(pathMore.length);
path = pathMore[index];
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}else if(obj == animalItem){
System.out.println("更换动物图片");
path = "image\\sc\\4.cat\\";
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}else if(obj == mrlItem){
System.out.println("恢复默认图片");
path = "image\\sc\\1.red\\";
//再次打乱二维数组
initData();
//计步器清零
step = 0;
//重新加载图片
initImage();
}
}
}