Java笔记_10(项目阶段----拼图游戏)

news2025/1/16 13:49:52

项目阶段

  • 页面搭建
    • 创建窗口
  • 界面设置和菜单搭建
    • 创建菜单
  • 添加图片
    • 图片对象
  • 打乱图片
    • 用一维数组添加值到二维数组中
  • 事件
  • 美化页面
  • 移动图片
  • 查看完整图片,作弊器,判断胜利
  • 计步器和菜单业务的实现
    • 弹窗创建
  • 更换图片和登陆页面的建立
    • 表单
  • 所有源码的实现
    • 游戏规则
    • 工具类
    • 登录窗口
    • 注册窗口(些许功能目前难以实现)
    • 游戏窗口
    • 进入游戏的入口

页面搭建

创建窗口

  • 使用 JFrame JavaBean类
  • 调用格式
    • JFrame 名称 = new JFrame();
  • 相关属性:
    • 宽高的设置
      • 名称.setSize(宽(px),高(px))
    • 界面的显示
      • 名称.setVisible(布尔值)
    • 界面的标题
      • 名称.setTitle(String)
    • 界面置顶
      • 名称.setAlwaysOnTop(布尔值)
    • 界面居中
      • 名称.setLocationRelativeTo(null)
    • 设置关闭模式
      • 名称.setDefaultCloseOperation(number)
      • 每一种数字都是一种关闭模式
    • 取消窗口默认居中放置,只有取消了才能按照XY轴的方式添加组件
      • 名称.setLayout(null)
    • 在窗口中添加组件
      • 名称.setgetContentPane().add(组件名称)
    • 清除已经出现的组件
      • 窗口名称.getContentPane().removeAll()
    • 重新刷新界面
      • 窗口名称.getContentPane().repaint()
    • 关闭运营
      • System.exit(0);
        在这里插入图片描述
package smulll.ui;

import javax.swing.*;

public class GameJFrame extends JFrame {
    //跟游戏相关的界面
    public GameJFrame (){
        this.setSize(603,680);
        this.setVisible(true);
    }
}
package smulll.ui;

import javax.swing.*;

public class LoginJFrame extends JFrame {
    //跟登录相关的界面
    public LoginJFrame (){
        this.setSize(488,430);
        this.setVisible(true);
    }
}
package smulll.ui;

import javax.swing.*;

public class RegisterFrame extends JFrame {
    //跟注册相关的代码
    public RegisterFrame (){
        this.setSize(488,500);
        this.setVisible(true);
    }
}

界面设置和菜单搭建

创建菜单

  • 给整个窗口界面设置一个菜单
    • 窗口名称.setJMenuBar(菜单名称)
  • 菜单对象
    • JMenuBar 名称 = new JMenuBar();
    • 添加选项的属性
      • 名称.add(选项名称);
  • 菜单中的选项
    • JMenu 名称 = new JMenu(String);
    • 添加条目对象的属性
      • 名称.add(条目对象名称);
  • 选项下的条目对象
    • JMenuItem 名称 = new JMenuItem();
package smulll.ui;

import javax.swing.*;

public class GameJFrame extends JFrame {
    //跟游戏相关的界面
    public GameJFrame() {
        //初始化界面
        initJFrame();
        //初始化菜单
        initJFrameBar();

        this.setVisible(true);
    }
    private void initJFrame() {
        this.setSize(603, 680);
        //设置页面标题
        this.setTitle("拼图游戏 v1.0");
        //设置页面在页面顶层
        this.setAlwaysOnTop(true);
        //页面居中
        this.setLocationRelativeTo(null);
        //设置关闭模式
        this.setDefaultCloseOperation(3);
    }
    private void initJFrameBar(){
        //创建一个菜单
        JMenuBar jMenuBar = new JMenuBar();
        //创建菜单选项
        JMenu functionJMenu = new JMenu("功能");
        JMenu aboutJMenu = new JMenu("关于我们");
        //创建选项下面的条目对象
        JMenuItem replayItem = new JMenuItem("重新游戏");
        JMenuItem reloginItem = new JMenuItem("重新登录");
        JMenuItem closeItem = new JMenuItem("关闭游戏");

        JMenuItem accountItem = new JMenuItem("公众号");
        //添加到项目之下
        functionJMenu.add(replayItem);
        functionJMenu.add(reloginItem);
        functionJMenu.add(closeItem);

        aboutJMenu.add(accountItem);
        //添加选项到菜单中
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);
        //添加菜单
        this.setJMenuBar(jMenuBar);

    }
}

添加图片

图片对象

  • 创建一个图片对象
    • ImageIcon 名称 = new ImageIcon (文件的完整路径)
  • 创建一个图片管理容器对象
    • JLabel 名称 = new JLabel(图片对象名称)
  • 把管理容器添加到界面中
    • 窗口名称.getContentPane().add(管理容器名称)
  • 图片放置位置
    • 图片管理容器名称.setBounds(x轴位置,y轴位置,宽,高)

打乱图片

用一维数组添加值到二维数组中

打乱一维数组中的数据,添加到二维数组中

public static void main(String[] args) {
        int[] tempArr = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
        
        Random r = new Random();
        for (int i = 0; i < tempArr.length; i++) {
            int index = r.nextInt(tempArr.length);

            int temp = tempArr[i];
            tempArr[i] = tempArr[index];
            tempArr[index] = temp;
        }
        for (int i = 0; i < tempArr.length; i++) {
            System.out.print(tempArr[i]+" ");
        }
        System.out.println();

        int[][] data = new int[4][4];
		//将一维数组中的数据添加到二维数组中
        for (int i = 0; i < tempArr.length; i++) {
            data[i/4][i%4] = tempArr[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 initData() {
        int[] tempArr = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
        //打乱图片的顺序
        Random r = new Random();
        for (int i = 0; i < tempArr.length; i++) {
            int index = r.nextInt(tempArr.length);

            int temp = tempArr[i];
            tempArr[i] = tempArr[index];
            tempArr[index] = temp;
        }
        //把一维数组的数添加到二维数组中
        for (int i = 0; i < tempArr.length; i++) {
            data[i/4][i%4] = tempArr[i];
        }

    }

事件

  • 事件源:按钮 图片 窗体…
  • 事件:某些操作
    如:鼠标单击,鼠标划入…
  • 绑定监听:当事件源上发生了某个事件,则执行某段代码

常用的监听事件

  • 键盘监听:KeyListener
  • 鼠标监听:MouseListener
  • 动作监听:ActionListener
  • 按钮对象
    • JButten 名称 = new JButton(按钮里面显示的文本);
    • 设置按钮宽高
      • 按钮名称.setBounds(X轴位置,Y轴位置,宽,高);
    • e.getSource()
      • 获取当前被操作的按钮对象

鼠标监听机制-MouseListener

Modifier and Type方法描述
voidmouseClicked (MouseEvent e)在组件上单击(按下并释放)鼠标按钮时调用。
voidmouseEntered (MouseEvent e)当鼠标进去组件时调用
voidmouseExited (MouseEvent e)当鼠标退出组件时调用
voidmousePressed (MouseEvent e)在组件上按下鼠标按钮时调用
voidmouseReleased (MouseEvent e)在组件上释放鼠标按钮时调用

键盘监听机制-KeyListener

Modifier and Type方法描述
voidkeyPressed (KeyEvent e)按下键时调用
voidkeyReleased (KeyEvent e)当键已被释放时调用
voidkeyTyped (KeyEvent e)键入键时调用
  • 设置键盘监听事件如果设置了按下事件不松,会重复的调用该事件
  • e.getKeyCode()
    • 获取键盘上每一个按键的编号
    • a=65其他字母按顺序排序

美化页面

  1. 调整图片的位置,使其在窗口的中下方,通过给每个图片添加坐标像素来完成
  2. 给图片添加边框
    • .setBorder(new 类名)
      • BevelBorder类,控制突起和凹入的边框
      • 具体类名通过API文档查询
  3. 添加背景图片需要在最后进行添加,前面添加的图片会覆盖后面添加的图片
private void initImage() {


        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int number = data[i][j];
                //创建一个图片对象
                //创建一个图片管理容器
                JLabel jLabel1 = new JLabel(new ImageIcon("project__one\\pintu_game\\David_Tao\\image\\two\\I-‘m-ok_"+number+".jpg"));
                //指定图片位置
                jLabel1.setBounds(105 * j+83, 105 * i+134, 105, 105);
                //给图片加上一个边框
                jLabel1.setBorder(new BevelBorder(1));
                //把容器添加到界面中
                this.getContentPane().add(jLabel1);
                //背景图片在后面添加


            }
        }
    }

移动图片

在这里插入图片描述

public void keyPressed(KeyEvent e) {

        int code = e.getKeyCode();
        if(code==37){
            if (y==3){
                return;
            }
            System.out.println("向左移动");
            data[x][y] = data[x][y+1];
            data[x][y+1] = 0;
            y++;
            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++;
            initImage();
        } else if (code==39) {
            if (y==0){
                return;
            }
            System.out.println("向右移动");
            data[x][y] = data[x][y-1];
            data[x][y-1] = 0;
            y--;
            initImage();
        } else if (code==40) {
            if (x==0){
                return;
            }
            System.out.println("向下移动");
            data[x][y] = data[x-1][y];
            data[x-1][y] = 0;
            x--;
            initImage();
        }
    }

查看完整图片,作弊器,判断胜利

设置一个键盘监听事件

public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if(code==65){
            //删除原来的图片
            this.getContentPane().removeAll();
            //创建一个图片容器
            JLabel jLabel2 = new JLabel(new ImageIcon(project+"\\all.jpg"));
            //设置图片出现的位置
            jLabel2.setBounds(83,134,420,420);
            this.getContentPane().add(jLabel2);

            this.getContentPane().repaint();
        }

    }

作弊码通过修改data数组的值来完成

if (code==87) {
            data = new int[][]{
                    {1,2,3,4},
                    {5,6,7,8},
                    {9,10,11,12},
                    {13,14,15,0}
            };

判断胜利,先定义一个函数

private boolean victory (int[][] win,int[][] data){
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++){
                if(data[i][j]!=win[i][j]){
                    return false;
                }
            }
        }
        return true;
    }

当胜利以后,创建一个图片窗口存放胜利的图片(由于没有按图片,直接以代码形式略过)
并且在键盘事件事件中加一个return防止结束以后继续运行

if(victory(win,data)){
            return;
        }

计步器和菜单业务的实现

弹窗创建

  • 创建弹窗对象
    • JDialog 名称 = new JDialog();
  • 设置弹窗的大小
    • 弹窗对象名称.setSize(宽度,高度)
  • 弹窗不关闭则无法操作下面的界面
    • 弹窗对象名称.setModal(true)

添加ActionListener事件

public void actionPerformed(ActionEvent e) {
        Object obj =  e.getSource();
        if(obj == replayItem){
            //先将原来的界面清除
            this.getContentPane().removeAll();
            //步数清零
            step = 0;
            //重新打乱图片排序
            initData();
            //重新加载图片
            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 gongzhong = new JDialog();
            //设置弹窗的宽高
            gongzhong.setSize(300,300);
            //弹窗不关闭则无法操作下面的界面
            gongzhong.setModal(true);
            //使弹窗居中显示
            gongzhong.setLocationRelativeTo(null);
            //使弹窗置顶
            gongzhong.setAlwaysOnTop(true);
            //添加弹窗
            gongzhong.setVisible(true);
        }

更换图片和登陆页面的建立

表单

  • 输入框
    • JTextField 名称 = new JTextField;
  • 密码框
    • JPasswordField 名称 = new JPasswordField;
  • 按钮对象
    • JButton 名称 = new JButton;
    • 去除按钮边框
      • 按钮名称.setBoderPainted(false);
    • 去除按钮背景
      • 按钮名称.setContentAreaFilled(false);
    • 给按钮添加图片
      • 按钮名称.setIcon();

更换图片

else if (obj==Jay) {
            //更换杰伦的图片
            this.getContentPane().removeAll();
            //改变图片路径
            project = "D:\\Java\\IDEA\\代码文件\\Project_one\\project__one\\pintu_game\\Jay_chou\\image";
            //更换number2 的值来改变图片
            Random r = new Random();
            int ran = r.nextInt(2)+1;
            number2 = ran;
            initData();
            initImage();
        }else if (obj==David) {
            //更换陶喆的图片
            project = "D:\\Java\\IDEA\\代码文件\\Project_one\\project__one\\pintu_game\\David_Tao\\image";
            //更换number2 的值来改变图片
            Random r = new Random();
            int ran = r.nextInt(2)+1;
            number2 = ran;
            initData();
            initImage();
        }

所有源码的实现

游戏规则

  1. 进入游戏必须先登录账号(账号密码在下面集合里面)
  2. 通过上下左右键在移动图片
  3. 长按A键可以查看完整图片
  4. 点击W键可以一键完成游戏
  5. 游戏完成后则不能继续进行游戏
  6. 许多附属功能在菜单的功能栏目有体现

工具类

package smulll.ui;

import java.util.Random;

public class CodeUtil {
    private CodeUtil(){}

    public static String getCOde(){
        //创建一个数组,存放大小写字母
        char[]arr= new char[52];

        for (int i = 0; i < 52; i++) {
            if(i<=25){
                //添加小写字母
                arr[i]= (char)(97+i);
            }else {
                //添加大写字母
                arr[i]=(char)(65+i-26);
            }
        }
        int[] arr2= {1,2,3,4,5,6,7,8,9,0};

        String code = "";
        //创建以一个随机数,使得抽取数组里面的数字以及字母加到字符串上
        Random r = new Random();
        for (int i = 0; i < 3; i++) {
            int index =  r.nextInt(arr.length);
            code = arr[index] + code;
        }
        System.out.println(code);
        for (int i = 0; i < 2; i++) {
            int index =  r.nextInt(arr2.length);
            code = arr2[index] + code;
        }
        System.out.println(code);
        //将字符串转换为字符数组,以便于打乱字符串的顺序
        char[] codeArr = code.toCharArray();

        for (int i = 0; i < codeArr.length; i++) {
            int index = r.nextInt(codeArr.length);

            if(index!=i){
                char c = codeArr[i];
                codeArr[i] = codeArr[index];
                codeArr[index] = c;
            }
        }
        //将字符数组再次转化为字符串,并且导出
        String code2 =  new String(codeArr);
        return code2;
    }
}

登录窗口

package smulll.ui;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Array;
import java.sql.SQLOutput;
import java.util.ArrayList;

public class LoginJFrame extends JFrame implements MouseListener {


    //跟登录相关的界面
    //创建事件条目对象
    JButton btn1 = new JButton("登录");
    JButton btn2 = new JButton("注册");
    JTextField username = new JTextField();
    JPasswordField jPasswordField = new JPasswordField();
    JTextField j1 = new JTextField();
    JLabel rightcode = new JLabel();
    String code = CodeUtil.getCOde();
    public LoginJFrame (){
        this.setSize(488,430);
        //设置页面标题
        this.setTitle("拼图游戏 登录界面");
        //设置页面在页面顶层
        this.setAlwaysOnTop(true);
        //页面居中
        this.setLocationRelativeTo(null);
        //设置关闭模式
        this.setDefaultCloseOperation(3);
        this.setLayout(null);
        initView();

        this.setVisible(true);
    }
    public class User{
        private String usernames ;
        private String password;
        public User() {
        }
        public User(String username, String password) {
            this.usernames = username;
            this.password = password;
        }
        public String getUsername() {
            return usernames;
        }
        public void setUsername(String username) {
            this.usernames = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }

        public String toString() {
            return "User{username = " + usernames + ", password = " + password + "}";
        }
    }
    private void initView(){
        JLabel usernameT = new JLabel("用户名:");
        usernameT.setBounds(116,105,200,30);
        this.getContentPane().add(usernameT);
        //创建用户名输入框

        username.setBounds(116,135,200,30);
        this.getContentPane().add(username);

        JLabel PasswordT = new JLabel("密码:");
        PasswordT.setBounds(116,170,200,30);
        this.getContentPane().add(PasswordT);
        //创建密码输入框

        jPasswordField.setBounds(116,196,200,30);
        this.getContentPane().add(jPasswordField);


        //创建验证码输入框

        j1.setBounds(116,250,70,30);
        this.getContentPane().add(j1);
        //创建验证码

        //System.out.println(code);
        //将验证码插入窗口

        //将生成的验证码添加给JLabel
        rightcode.setText(code);
        rightcode.setBounds(200,250,70,30);
        this.getContentPane().add(rightcode);

        //创建两个按钮

        btn1.setBounds(116,300,60,30);
        //去除按钮背景
        //btn1.setContentAreaFilled(flase);
        //去除按钮边框
        //btn1.setBorderPainted(false);
        this.getContentPane().add(btn1);


        btn2.setBounds(260,300,60,30);
        //去除按钮背景
        //btn2.setContentAreaFilled(flase);
        //去除按钮边框
        //btn2.setBorderPainted(false);
        this.getContentPane().add(btn2);

        //给两个按钮添加事件
        btn1.addMouseListener(this);
        btn2.addMouseListener(this);
        //给验证码窗口添加鼠标事件
        rightcode.addMouseListener(this);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        //通过集合的方式装载用户信息
        ArrayList<User> user2 = new ArrayList<>();
        User u1 = new User("Smulll","123456");
        User u2 = new User("laohuang","112233");

        user2.add(u1);
        user2.add(u2);
        //建立两个数组在装在集合成员信息
        String[] userNamearr = new String[user2.size()];
        String[] userPassword = new String[user2.size()];

        for (int i = 0; i < user2.size(); i++) {
            userNamearr[i] = user2.get(i).usernames;
        }
        for (int i = 0; i < user2.size(); i++) {
            userPassword[i] = user2.get(i).password;
        }

        String password = new String(jPasswordField.getPassword());

        //获取用户点击事件焦点
        Object c = e.getSource();
        if(c == btn1){
            //点击了登录按钮
            System.out.println("点击了登录按钮");
            if(!(j1.getText().equals(code))){
                viewError("验证码输入错误");
                rightcode.removeAll();
                code = CodeUtil.getCOde();
                j1.setText("");
                initView();
                return;
            } else if ((userError(username.getText(),userNamearr))) {
                System.out.println(username.getText());
                viewError("用户名输入错误");
                username.setText("");
                jPasswordField.setText("");
                return;
            } else if ((userError(password,userPassword))) {
                viewError("密码输入错误");
                jPasswordField.setText("");
                return;
            }
            this.dispose();

            new GameJFrame();

        } else if (c == btn2) {
            //点击了注册按钮
            System.out.println("点击了注册按钮");
            
        }else if(c==rightcode){
            //点击了验证码
            System.out.println("点击了验证码");
            rightcode.removeAll();
            code = CodeUtil.getCOde();
            j1.setText("");
            initView();
        }
    }
    @Override
    public void mousePressed(MouseEvent e) {

    }
    @Override
    public void mouseReleased(MouseEvent e) {

    }
    @Override
    public void mouseEntered(MouseEvent e) {

    }
    @Override
    public void mouseExited(MouseEvent e) {

    }
    //弹窗显示函数
    public static void viewError(String count){
        JDialog gongzhong = new JDialog();
        //设置弹窗的宽高
        gongzhong.setSize(100,60);
        //弹窗不关闭则无法操作下面的界面
        gongzhong.setModal(true);
        //使弹窗居中显示
        gongzhong.setLocationRelativeTo(null);
        //使弹窗置顶
        gongzhong.setAlwaysOnTop(true);
        //创建一个窗口
        JLabel jLabel = new JLabel(count);
        //设置窗口大小
        jLabel.setBounds(0,0,100,30);
        //添加窗口到弹窗中
        gongzhong.getContentPane().add(jLabel);
        //弹窗显现
        gongzhong.setVisible(true);
    }
    public static boolean userError(String user, String[] arr){
        for (int i = 0; i < arr.length; i++) {
            if(!(user.equals(arr[i]))){
                return false;
            }
        }
        return true;
    }
}

注册窗口(些许功能目前难以实现)

  • 目前以几个的增减进行用户的管理
package smulll.ui;

import javax.swing.*;

public class RegisterFrame extends JFrame {


    //跟注册相关的代码
    public RegisterFrame (){
        this.setSize(488,500);
        //设置页面标题
        this.setTitle("拼图游戏 注册界面");
        //设置页面在页面顶层
        this.setAlwaysOnTop(true);
        //页面居中
        this.setLocationRelativeTo(null);
        //设置关闭模式
        this.setDefaultCloseOperation(3);
        this.setVisible(true);
    }
}

游戏窗口

package smulll.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.time.temporal.Temporal;
import java.util.Random;

public class GameJFrame extends JFrame implements KeyListener, ActionListener {
    //跟游戏相关的界面
    //创建一个二维数组
    int[][] data = new int[4][4];
    //设置胜利时的图片下标索引
    int[][] win= {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    //找到0索引位置的图片
    int x = 0;
    int y = 0;
    //设置要放置的图片
    String project = "D:\\Java\\IDEA\\代码文件\\Project_one\\project__one\\pintu_game\\David_Tao\\image";
    //创建一个计步器
    int step = 0;
    //创建图片切换的number2
    int number2=1;
    //创建选项下面的条目对象
    JMenuItem replayItem = new JMenuItem("重新游戏");
    JMenuItem reloginItem = new JMenuItem("重新登录");
    JMenuItem closeItem = new JMenuItem("关闭游戏");
    JMenuItem accountItem = new JMenuItem("公众号");
    JMenuItem Jay = new JMenuItem("Jay");
    JMenuItem David = new JMenuItem("David");
    public GameJFrame() {
        //初始化界面
        initJFrame();
        //初始化菜单
        initJFrameBar();
        //打乱图片
        initData();
        //初始化图片
        initImage();
        //使窗口显示出来
        this.setVisible(true);
    }

    private void initData() {
        int[] tempArr = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
        //打乱图片的顺序
        Random r = new Random();
        for (int i = 0; i < tempArr.length; i++) {
            int index = r.nextInt(tempArr.length);

            int temp = tempArr[i];
            tempArr[i] = tempArr[index];
            tempArr[index] = temp;
        }
        //把一维数组的数添加到二维数组中
        for (int i = 0; i < tempArr.length; i++) {
            if(tempArr[i]==0){
                x = i/4;
                y = i%4;
            }
                data[i / 4][i % 4] = tempArr[i];
        }
    }

    private void initImage() {
            //清除原先存在的图片
            this.getContentPane().removeAll();
            //判断是否胜利
            if(victory(win,data)){
                System.out.println("你胜利了");
            }
            //创建一个显示并步数的窗口
        JLabel j2 = new JLabel("步数:"+step);
            j2.setBounds(50,30,100,20);

            this.getContentPane().add(j2);


        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int number = data[i][j];
                //创建一个图片对象
                //创建一个图片管理容器
                JLabel jLabel1 = new JLabel(new ImageIcon(project+"\\"+number2+"\\"+number+".jpg"));
                //指定图片位置
                jLabel1.setBounds(105 * j+83, 105 * i+134, 105, 105);
                //给图片加上一个边框
                jLabel1.setBorder(new BevelBorder(1));
                //把容器添加到界面中
                this.getContentPane().add(jLabel1);
                //背景图片在后面添加
                this.getContentPane().repaint();
            }
        }
    }

    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);
    }
    private void initJFrameBar(){
        //创建一个菜单
        JMenuBar jMenuBar = new JMenuBar();
        //创建菜单选项
        JMenu functionJMenu = new JMenu("功能");
        JMenu aboutJMenu = new JMenu("关于我们");
        JMenu replacement = new JMenu("更换图片");

        //添加到功能项目之下
        functionJMenu.add(replacement);
        functionJMenu.add(replayItem);
        functionJMenu.add(reloginItem);
        functionJMenu.add(closeItem);
        //添加更换图片目录
        replacement.add(Jay);
        replacement.add(David);
        //添加关于我们目录
        aboutJMenu.add(accountItem);
        //添加选项到菜单中
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);

        //给菜单选项添加事件
        replayItem.addActionListener(this);
        reloginItem.addActionListener(this);
        closeItem.addActionListener(this);
        accountItem.addActionListener(this);
        Jay.addActionListener(this);
        David.addActionListener(this);
        //添加菜单
        this.setJMenuBar(jMenuBar);

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    @Override
    public void keyReleased(KeyEvent e) {
        //如果胜利了直接写return,使整个方法结束
        if(victory(win,data)){
            return;
        }
        int code = e.getKeyCode();
        if(code==37){
            if (y==3){
                return;
            }
            System.out.println("向左移动");
            data[x][y] = data[x][y+1];
            data[x][y+1] = 0;
            y++;
            //每走一步就会给步数加1
            step=step+1;
            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++;
            //每走一步就会给步数加1
            step=step+1;
            initImage();
        } else if (code==39) {
            if (y==0){
                return;
            }
            System.out.println("向右移动");
            data[x][y] = data[x][y-1];
            data[x][y-1] = 0;
            y--;
            //每走一步就会给步数加1
            step=step+1;
            initImage();
        } else if (code==40) {
            if (x==0){
                return;
            }
            System.out.println("向下移动");
            data[x][y] = data[x-1][y];
            data[x-1][y] = 0;
            x--;
            //每走一步就会给步数加1
            step=step+1;
            initImage();
        } else if (code==65) {
            initImage();
        } else if (code==87) {
            data = new int[][]{
                    {1,2,3,4},
                    {5,6,7,8},
                    {9,10,11,12},
                    {13,14,15,0}
            };
            initImage();
        }
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if(code==65){
            //删除原来的图片
            this.getContentPane().removeAll();
            //创建一个图片容器
            JLabel jLabel2 = new JLabel(new ImageIcon(project+"\\all.jpg"));
            //设置图片出现的位置
            jLabel2.setBounds(83,134,420,420);
            this.getContentPane().add(jLabel2);

            this.getContentPane().repaint();
        }

    }

    private boolean victory (int[][] win,int[][] data){
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; 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){
            //先将原来的界面清除
            this.getContentPane().removeAll();
            //步数清零
            step = 0;
            //重新打乱图片排序
            initData();
            //重新加载图片
            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 gongzhong = new JDialog();
            //设置弹窗的宽高
            gongzhong.setSize(300,300);
            //弹窗不关闭则无法操作下面的界面
            gongzhong.setModal(true);
            //使弹窗居中显示
            gongzhong.setLocationRelativeTo(null);
            //使弹窗置顶
            gongzhong.setAlwaysOnTop(true);
            //添加弹窗
            gongzhong.setVisible(true);
        } else if (obj==Jay) {
            //更换杰伦的图片
            this.getContentPane().removeAll();
            //改变图片路径
            project = "D:\\Java\\IDEA\\代码文件\\Project_one\\project__one\\pintu_game\\Jay_chou\\image";
            //更换number2 的值来改变图片
            Random r = new Random();
            int ran = r.nextInt(2)+1;
            number2 = ran;
            initData();
            initImage();
        }else if (obj==David) {
            //更换陶喆的图片
            project = "D:\\Java\\IDEA\\代码文件\\Project_one\\project__one\\pintu_game\\David_Tao\\image";
            //更换number2 的值来改变图片
            Random r = new Random();
            int ran = r.nextInt(2)+1;
            number2 = ran;
            initData();
            initImage();
        }
    }
}

进入游戏的入口

import com.sun.source.tree.NewArrayTree;
import smulll.ui.GameJFrame;
import smulll.ui.LoginJFrame;
import smulll.ui.RegisterFrame;

public class App {
    public static void main(String[] args) {
        new LoginJFrame();
        //new GameJFrame();
        //new RegisterFrame();
    }
}

效果展示
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

es7.x集群部署-多台物理机部署-docker环境部署-docker-compose管理

es集群部署文档 部署es服务的三台服务器的ip和host分分别是&#xff1a; iphost_name192.168.1.2web02192.168.1.3storage02192.168.1.4Storage03 这个配置需要在服务器上编写对应的hosts文件&#xff0c;然后才可以使用host进行配置。 本次部署没有外挂配置文件&#xff0…

容器内无tcpdump,如何在宿主机上抓容器的包

抓包的容器里&#xff0c;没有安装tcpdump 命令&#xff0c;我们可以去容器所在宿主机上&#xff0c;使用 nsenter 命令切换网络命名空间后&#xff0c;使用宿主机上的tcpdump 命令&#xff0c;对容器进行抓包分析。 此例中&#xff0c;我要抓取容器中端口是5240的包&#xff…

react3:受控组件(表单默认变成受控)-组件通信 - typescript项目(表单,tabbar)

受控组件&#xff1a;表单 非受控组件表单元素值不受所在组件状态的控制, 我们将这样的表单元素称作: 非受控组件. 受控组件受控组件 : 值受到 React 组件状态控制的表单元素一般是通过 defaultValue 属性, onChange 事件配合将非受控组件变为受控组件. 多表单元素操作 &#…

Unity中GPUInstance详解

为什么要用GPUInstance 在没有GPUInstance此技术之前&#xff0c;对于像草地、树木&#xff0c;割草游戏&#xff0c;它们往往是数据量很大&#xff0c;但同时又只存在微小的差别如位置、旋转、颜色等。如果像常规物体那样进行渲染&#xff0c;所使用的绘制指令必然很多…

3.3 向量与矩阵的范数

学习目标&#xff1a; 要学习向量与矩阵的范数&#xff0c;我会采取以下几个步骤&#xff1a; 了解基本概念&#xff1a;首先&#xff0c;我会了解向量和矩阵的范数的基本概念和定义&#xff0c;以及它们的性质和特点&#xff0c;这是理解和掌握范数的基础。 学习具体算法&am…

Nacos简介、基本概念、基本架构、安装部署

官网&#xff1a;https://nacos.io/zh-cn/ 官方文档&#xff1a; 什么是 Nacos Github&#xff1a;https://github.com/alibaba/nacos&#xff0c;阿里巴巴开源项目。 简介 什么是Nacos&#xff1f; Nacos&#xff1a;(Dynamic) Naming and Configuration Service&#xf…

空间相关性----地理探测器--学习记录

目录 相关教程--软件及数据准备 R语言数据分析1、R包、数据准备、GD综合代码2、分异及因子探测---q值 gd3、交互作用探测---评估因子gdinteract4、风险区探测--显著性--gdrisk()5、生态探测---交叉影响--gdeco() 数据准备注意&#xff1a;使用Arcgis首先创建.gdb&#xff08;本…

数学建模第二天:数学建模工具课之MATLAB绘图操作

目录 一、前言 二、二维绘图 1、曲线图、散点图plot 2、隐函数、显函数与参数方程的绘图 ①ezplot ②fplot 三、三维绘图 1、单曲线plot3 2、多曲线plot3 3、曲面 ①实曲面surf ②网格曲面mesh 四、特殊的二维、三维图 1、极坐标图polar 2、平面散点图scatter …

学网络安全都是一群什么人?

大家好呀&#xff0c;我是知了姐&#xff0c;又是一期学员故事栏目~ 3月下旬知了堂信安方向开新班&#xff0c;知了姐跟着去采访&#xff0c;了解到新学员们的求学故事&#xff0c;嘿你别说&#xff0c;虽然大家出身专业不同、经历背景不同&#xff0c;如今却在同一个地点相遇…

CAMX大气臭氧来源解析模拟

查看原文>>>基于CAMX大气臭氧来源解析模拟与臭氧成因分析实践技术应用 随着我国经济快速发展&#xff0c;我国面临着日益严重的大气污染问题。大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果&#xff0c;同时气象因素是控制大气污染的关键自然因…

【微信小程序】生命周期,插槽和组件间通信

一、组件的生命周期 1.1 组件全部的生命周期函数 小程序组件可用的全部生命周期如下表所示 生命周期函数参数描述说明created无在组件实例刚刚被创建时执行attached无在组件实例进入页面节点树时执行ready无在组件在视图层布局完成后执行moved无在组件实例被移动到节点树另一…

实战案例|聚焦攻击面管理,腾讯安全威胁情报守护头部券商资产安全

金融“活水”润泽千行百业&#xff0c;对金融客户来说&#xff0c;由于业务场景存在特殊性和复杂性&#xff0c;网络安全必然是一场“持久战”。如何在事前做好安全部署&#xff0c;构建威胁情报分析的防护体系至为重要&#xff0c;实现更为精准、高效的动态防御。 客户名片 …

Flink系列-8、Flink DataStream的简介和API开发

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 大数据系列文章目录 官方网址&#xff1a;https://flink.apache.org/ 学习资料&#xff1a;https://flink-learning.org.cn/ 目录 流处理的介…

开放式耳机真的比封闭式强很多吗?推荐几款主流的开放式耳机

​开放式耳机&#xff0c;顾名思义&#xff0c;就是通过骨头振动来传导声音的耳机。相比于传统耳机&#xff0c;它的声音传输更加开放&#xff0c;不会对耳膜造成压迫感&#xff0c;也不会对耳膜旁的内毛细胞造成损害。因此开放式耳机既是运动蓝牙耳机&#xff0c;又是音乐蓝牙…

MAC 通过 brew安装 redis 并且设置开机启动

一.安装 mysql 1.安装 mysql 1.安装 redis brew install redis2.查看 redis 安装目录 brew list redis 记住安装目录 3.启动 redis 进入到安装目录下面 cd /opt/homebrew/Cellar/redis/7.0.11 cd bin ./redis-server 二.设置开机启动 上面安装好之后,redis 虽然能正常…

个性化的客户服务策略(二)

继续上次的策略&#xff0c;今天我们继续分享接下来的几点提供更加个性化的客户服务的方法。 6&#xff09;利用社交媒体发挥自己的优势 请求进入社交媒体渠道原因有很多。例如&#xff0c;愤怒的客户可能会对帖子发送直接消息或评论&#xff0c;因为它感觉更直接&#xff0c;…

【刷题之路Ⅱ】LeetCode 3381.搜索旋转排序数组ⅠⅡ

【刷题之路Ⅱ】LeetCode 33&81.搜索旋转排序数组Ⅰ&Ⅱ 一、题目描述二、解题1、方法1——暴力法1.1、思路分析1.2、代码实现 2、方法2——二分法2.1、思路分析2.2、代码实现2.3、升级到81题2.3.1、改进思路分析2.3.1、改进代码实现 3、改进二分法3.1、思路分析3.2、代码…

STM32F407ZIT6 国产替代者NS32F407ZIT6 NS32F407ZGT6 软硬件通用 无需修改任何程序代码

NS32F407ZIT6 NS32F407ZGT6 器件基于高性能的 ARM Cortex-M4 32位 RISC 内核&#xff0c;工作频率高达 168MHz。 Cortex-M4 内核带有单精度浮点运算单元(FPU)&#xff0c;支持所有 ARM 单精度数据处理指令和数据类型。它还 具有一组DSP指令和提高应用安全性的一个存储器保护…

Windows环境下调试DAB-DETR与Deformable-DETR

先前都是在服务器上运行DETR的相关程序&#xff0c;服务器使用的是Linux&#xff0c;所以运行较为简单&#xff0c;但如果想要简单的debug的话就没必要使用服务器了&#xff0c;今天便来在Winodws环境下调试DETR类项目&#xff0c;这里以Deformable-DETR与DAB-DETR为例。 首先是…

深度测评全新大模型「天工」,这些AI体验太香了

ChatGPT火了后&#xff0c;很多人都在关注“国产ChatGPT”的名号究竟花落谁家。 事实上&#xff0c;名号不重要&#xff0c;体验才是王道。ChatGPT能够火成“史上增长最快的消费者应用”&#xff0c;关键在于把体验提升到了新层次。毕竟对于用户来说&#xff0c;并不清楚产品背…