首页 > 编程语言 >Java实现拼图小游戏

Java实现拼图小游戏

时间:2024-07-28 22:56:38浏览次数:14  
标签:imageArray JFrame Java 拼图 int 小游戏 import new JLabel

        Java中的图形化界面使用得是比较少的,但是可以用来结合前期学习的面向对象编程的思想,通过图形化的呈现,创造一个拼图小游戏。

        主要用的到的包:

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.util.Random;

        类的继承和实现:

public class GameJFrame extends JFrame implements KeyListener, ActionListener

        主要思想:JFrame 、JMenu、JMenuBar、JMenuItem、JLabel、ImageIcon;数组、随机数、面向对象、键盘、鼠标监视、动作监视……

        游戏主体代码:

package GameUI;
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.util.Random;
public class GameJFrame extends JFrame implements KeyListener, ActionListener {
    int x = 0; // 用x来记录空白块的数组行标
    int y = 0; // 用y来记录空白快数组的列标
    int[][] imageArray = new int[4][4];
    // 创建胜利数组,当imageArray和胜利数组完全一样的时候,代表游戏胜利
    int[][] winArray = new int[][] {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    // 用字符串来记录图片的路径,方便修改
    String path = "Game\\image\\animal\\animal3\\";
    // 用以记录移动步数
    int step = 0;
    // 创建功能中条目
    JMenuItem replayItem = new JMenuItem("重新开始");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem closeItem = new JMenuItem("关闭游戏");
    // 创建关于制作人员中条目
    JMenuItem accountItem = new JMenuItem("Rose");
    public GameJFrame() {
        // 设置界面
        setJFrame();
        // 设置菜单
        setMenu();
        // 初始化数组
        initArray();
        // 设置图片
        setImage();
        // 设置界面可见
        this.setVisible(true);
    }

    private void setJFrame() {
        // 设置界面大小
        this.setSize(603, 680);
        // 设置界面标题
        this.setTitle("Puzzle version 1.0");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        // 取消默认放置(JFrame只是一个框架,真正存放组件的是其中的ContentPanel
        // ,必须要取消默认放置的设定才可以自定义坐标放置)
        this.setLayout(null);
        // 添加键盘监听
        this.addKeyListener(this);
    }

    private void setMenu() {
        // 创建整个菜单对象
        JMenuBar jMenuBar = new JMenuBar();
        // 创建选项功能
        JMenu functionJMenu = new JMenu("功能  ");
        JMenu aboutJMenu = new JMenu("制作人员");
        // 给条目绑定事件
        replayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        closeItem.addActionListener(this);
        accountItem.addActionListener(this);

        // 在功能中加入条目
        functionJMenu.add(replayItem);
        functionJMenu.add(reLoginItem);
        functionJMenu.add(closeItem);
        // 在关于我们中加入条目
        aboutJMenu.add(accountItem);
        // 在菜单中加入选项
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);
        //  在JFrame中创建菜单
        this.setJMenuBar(jMenuBar);
    }

    public void setImage() {
        // 清空本来已经出现的图片
        this.getContentPane().removeAll();
        if (victory()) {
            JLabel victoryImage = new JLabel(new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\win.png"));
            victoryImage.setBounds(203, 283, 197, 73);
            this.getContentPane().add(victoryImage);
        }
        JLabel stepImage = new JLabel("步数:" + step);
        stepImage.setBounds(50, 30, 100, 20);
        this.getContentPane().add(stepImage);
        for(int i = 0; i < 4; i++) {
            for(int j = 0; j < 4; j++) {
                int number = imageArray[i][j];
                // 创建新的图片对象(构造方法可以传入图片文件的路径)
                ImageIcon image = new ImageIcon(path + number + ".jpg");
                // JLabel是一个图片容器,可以将ImageIcon创造出来的图片对象加入这个容器
                JLabel jLabel = new JLabel(image);
                 /*设置图片在界面中的显示位置,每个小图片的像素是105*105;通过双重循环
                 可以达到将不同的图片,按行列放置到对应位置的效果*/
                jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
                // 给每张图片设置一个边框,增强美观性
                jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
                /*JFrame实际上只是一个框架,真正的组件实际上是“放置”于JFrame中的
                 ContentPanel中的,可以通过JFrame的getContentPanel方法得到,并且
                 在其中添加JLabel对象*/
                this.getContentPane().add(jLabel);
            }
        }

        // 添加背景图片
        ImageIcon background = new ImageIcon("Game\\image\\background.png");
        JLabel bg = new JLabel(background);
        bg.setBounds(40, 40, 508, 560);
        this.getContentPane().add(bg);
        // 刷新界面
        this.getContentPane().repaint();
    }

    public void initArray() {
        int[] arr = new int[16];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }

        Random r = new Random();
        int randomNumber;
        for (int i = 15; i >= 0; i--) {
            randomNumber = r.nextInt(i + 1);
            int temp = arr[randomNumber];
            arr[randomNumber] = arr[i];
            arr[i] = temp;
        }

        // 初始化时必须将二维数组全部设置为0
        // 如果不全部设置为0,上一次的数据会遗留
        for (int i = 0; i < imageArray.length; i++) {
            for (int j = 0; j < imageArray.length; j++) {
                imageArray[i][j] = 0;
            }
        }
        for(int i = 0; i < arr.length; i++) {
            if (arr[i] == 0) {
                this.x = i / 4;
                this.y = i % 4;
            } else{
                imageArray[i / 4][i % 4] = arr[i];
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == 65) {
            this.getContentPane().removeAll();
            JLabel allImage = new JLabel(new ImageIcon(path + "all.jpg"));
            allImage.setBounds(83,134,420,420);
            this.getContentPane().add(allImage);
            // 添加背景图片
            ImageIcon background = new ImageIcon("Game\\image\\background.png");
            JLabel bg = new JLabel(background);
            bg.setBounds(40, 40, 508, 560);
            this.getContentPane().add(bg);
            // 刷新界面
            this.getContentPane().repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (victory()) {
            return;
        }
        int code = e.getKeyCode();
        // 左移
        if (code == 37) {
            if (y == 3) {
                return;
            } else {
                imageArray[x][y] = imageArray[x][y + 1];
                imageArray[x][y + 1] = 0;
                y++;
                step++;
                setImage();
            }
        }
        // 上移
        else if (code == 38) {
            if (x == 3) {
                return;
            } else {
                imageArray[x][y] = imageArray[x + 1][y];
                imageArray[x + 1][y] = 0;
                x++;
                step++;
                setImage();
            }
        }
        // 右移
        else if (code == 39) {
            if (y == 0) {
                return;
            } else {
                imageArray[x][y] = imageArray[x][y - 1];
                imageArray[x][y - 1] = 0;
                y--;
                step++;
                setImage();
            }
        }
        // 下移
        else if (code == 40) {
            if (x == 0) {
                return;
            } else {
                imageArray[x][y] = imageArray[x - 1][y];
                imageArray[x - 1][y] = 0;
                x--;
                step++;
                setImage();
            }
        } else if (code == 65) {
            setImage();
        } else if (code == 87) {
            for (int i = 0; i < imageArray.length* imageArray.length; i++) {
                if (i == 15) {
                   imageArray[3][3] = 0;
                   break;
                }
                imageArray[i / 4][i % 4] = i + 1;
            }
            setImage();
        }
    }

    public boolean victory() {
        for (int i = 0; i < imageArray.length; i++) {
            for (int j = 0; j < imageArray.length; j++) {
                if (imageArray[i][j] != winArray[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if(obj == replayItem) {
            // 重开游戏
            // 步数清零
            step = 0;
            // 初始化图片数组
            initArray();
            // 展示打乱的图片
            setImage();
        } else if (obj == reLoginItem) {
            System.out.println("重新登录(待开发)");
        } else if (obj == accountItem) {
            // 制作者
            System.out.println("rose");
            // 创建一个新的JFrame对象
            JFrame rose = creatRose();
            // 创建玫瑰图像的对象
            ImageIcon roseImage = new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\rose.jpg");
            // 创建JLabel容器存放玫瑰图像
            JLabel roseJB = new JLabel(roseImage);
            // 设置图像的位置和大小
            roseJB.setBounds(40, 40, 1080, 1080);
            // 将图像容器加入JFrame中
            rose.getContentPane().add(roseJB);

        } else if (obj == closeItem) {
            // 退出游戏
            // 直接关闭JVM虚拟机
            System.exit(0);
        }
    }

    public JFrame creatRose() {
        JFrame rose = new JFrame();
        // 设置宽高为1080*1080
        rose.setSize(1080, 1080);
        // 设置窗口可见
        rose.setVisible(true);
        // 设置窗口标题
        rose.setTitle("制作人员");
        // 设置窗口默认在屏幕中央
        rose.setLocationRelativeTo(null);
        // 设置窗口总是在最上层
        rose.setAlwaysOnTop(true);
        // 设置窗口关闭模式(只关闭当前JFrame窗口(默认关闭的方式))
        rose.setDefaultCloseOperation(HIDE_ON_CLOSE);
        // 返回JFrame对象
        return rose;
    }
}

        游戏的测试

import GameUI.GameJFrame;
import GameUI.LoginJFrame;
import GameUI.RegisterJFrame;
public class Application {
    public static void main(String[] args) {
        // 注册
        RegisterJFrame rj = new RegisterJFrame();
        // 登录
        LoginJFrame lj = new LoginJFrame();
        // 游戏
        GameJFrame gj = new GameJFrame();
    }
}

        还剩下的坑:登录、注册,等到日后有时间再把这个坑填上

package GameUI;
import javax.swing.*;
public class LoginJFrame extends JFrame {
    public LoginJFrame() {
        // 设置界面大小
        this.setSize(488, 430);
        // 设置界面标题
        this.setTitle("Login");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(3);
        // 设置界面可见
        this.setVisible(true);
    }
}
package GameUI;
import javax.swing.*;
public class RegisterJFrame extends JFrame{
    public RegisterJFrame() {
        // 设置界面大小
        this.setSize(488, 500);
        // 设置界面标题
        this.setTitle("Register");
        // 设置界面居中
        this.setLocationRelativeTo(null);
        // 设置界面永远在上
        this.setAlwaysOnTop(true);
        // 设置界面关闭模式
        this.setDefaultCloseOperation(3);
        // 设置界面可见
        this.setVisible(true);
    }
}

 

 

 

        

标签:imageArray,JFrame,Java,拼图,int,小游戏,import,new,JLabel
From: https://blog.csdn.net/Aishangyuwen/article/details/140621537

相关文章

  • 【科大讯飞笔试题汇总】2024-07-27-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • 【JavaEE】阻塞队列
    目录一.阻塞队列(BlockingQueue)1.什么是阻塞队列2.特性二.生产者消费者模型1.什么是生产者消费者模型?2.生产者消费模型的好处2.1解耦合  2.2削峰填谷三.如何在java中使用阻塞队列 四.模拟实现阻塞队列1.加锁2.阻塞等待实现3.解决interrupt唤醒waitting问题4......
  • java开发,安装JDK8
    java开发,入职第一天都干什么,带你提前揭晓  2024.7.24,帝都今晚大雨,在雨声磅礴的夜晚适合干什么,没错适合敲代码,写博客,今晚来聊下入职一个新公司,第一天都干什么。无论是刚毕业的新手小白,还是工作十余年的职场老人,入职一家新公司,只要还是做研发,那么毫无疑问,在领到电脑后,第一件......
  • javascript(一)
    一、基本语法1.位置(1)JavaScript脚本必须位于<script>与</script>之间(2)<script>标签可以位于<body>或者<head>部分中2.输出语句(1)window.alter()弹出警告框(2)document.write()可以将内容在网页中打印出来,同时也会将原有的内容覆盖(3)console.log()可以将内容在......
  • java 集合框架-map(键值对集合)
    一、Map接口 (键值对集合)1.实现类(1).线程不安全HashMap1.特点:        ①无序          ②查找效率高:根据key,查找value2.数据结构:数组(哈希表)+链表(链地址法解决哈希表冲突)+红黑树(自平衡二叉树,提高查找效率)      ①数组(哈希表):Ha......
  • 三种语言实现高精度加法(C++/Python/Java)
    题目给定两个正整数(不含前导00),计算它们的和。1≤整数长度≤100000C++#include<bits/stdc++.h>usingnamespacestd;vector<int>add(vector<int>&A,vector<int>&B){if(A.size()<B.size())returnadd(B,A);vector<int>C;......
  • JavaSE基础知识分享(一)
    写在前面今天要讲的是JAVA数据类型、运算符、选择语句、循环语句部分的基础知识,来看看你会不会!基础知识1Java语言规定标识符由字母、下划线、美元符号和数字组成,并且第一个字符不能是数字。Java中整型变量有byte、short、int和long四种,不同类型的整数变量在内存中分配的......
  • Java如何通过日志排查问题
    问题:大家有没有遇到过这样一种场景,在一个接口或者方法当中,业务逻辑很复杂,方法嵌套调用层级很深,此时要定位业务流程的走向,是不是要在每个方法中打日志,而这些日志是不串联的,比如,一个接口调用下来,程序没有报错,但没有按预期执行,怎么排查,就得翻这个方法调用时的每一条记录日志,而代......
  • JavaScript图片轮播
    代码在文章最后面(含图片URL)实现功能按向左按钮图片显示上一张按向右按钮图片显示下一张每隔2000毫秒显示下一张图底部三个圆点显示当前的图片的编号实现流程初始化图片数组创建一个包含图片URL的数组,轮播时会通过这个数组来切换图片。创建当前索引变量 这个变量用来追踪......
  • 计算机毕业设计-基于Java+SSM架构的校园美食交流系统项目开发实战(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......