Java项目 拼图游戏

2024-03-21 02:30
文章标签 java 项目 拼图游戏

本文主要是介绍Java项目 拼图游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        目录

1 项目基本信息

1.1 项目名称

1.2 实训环境

2 实训内容简介

2.1 拼图游戏

3 项目开发过程

3.1 拼图游戏

3.1.1 核心类

3.1.2开发步骤

4 实训总结及心得

1 项目基本信息

1.1 项目名称

拼图游戏

1.2 实训环境

JDK1.8 、eclipse 、 mysql 、navicat、Windows

2 实训内容简介

2.1 拼图游戏

        拼图游戏内容由若干小图像块组成的,其中有一个空白的小图像块,该图像块是来与别的图像块交换的,以此来实现大图像的拼凑。在Java标准环境下运行,通过鼠标点击图像块上下左右移动,完成大图像的拼凑。通过所创建的窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面,实现游戏登录、开始游戏、退出游戏、选择图片、图片缩放、图片分割、调整难易度、计数计时、打乱图片、判断拼图成功等功能。游戏可以通过对图片文件的读取和加载,从多张图片中选择来进行拼图游戏,通过设置图像块的个数来实现对游戏难易度的调整,最后将游戏完成后所用时间和步数记录到游戏记录中,方便用户查看游戏记录。

3 项目开发过程

3.1 拼图游戏

3.1.1 核心类

        1.MainJFrame类:继承JFrame类,实现Runnable接口,窗体用于存放发左右面板,添加组件等等。知识点有:

a.实现游戏关卡等级
itemeasy.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {rp.hs=2; //第一,传递2*2到右面板rp.ls=2;rp.init(url); //调用右面板组件初始化的方法}});
b. 游戏记录
itemchange.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {
//显示一个打开对话框,选择一个图片文件,将文件转换为url对象,调用左右面板的相应方法JFileChooser jfc=new JFileChooser();
//设置文件的扩展名jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|jif)", "jpg","png","gif"));
//弹出打开对话框int sd=jfc.showOpenDialog(MainJFrame.this);//null表示父容器是谁if(sd==jfc.APPROVE_OPTION)//如果用户选择打开了按钮{
//获取用户选择的文件完整名称String file=jfc.getSelectedFile().getAbsolutePath();try {url=new URL("file:\\"+file);lp.init(url);rp.init(url);} catch (MalformedURLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});
c. //记录清空itemclear.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {File f=new File("c://a");if(f.exists()){f.delete();}}});
d. 实现计时并显示步数@Overridepublic void run() {//死循环,使得代码一直在执行while (true) {endTime = System.currentTimeMillis();total_time.setText("用时:"+(endTime - startTime) / 1000 );total_count.setText("步数:"+rp.times);try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

        2.LeftJPanel类:左面板,将完整图片展示在左面板。知识点:

实现图片的缩放:
public void init(URL url){ImageIcon icon=new ImageIcon(url);//使用链式编程方式实现图片缩放jl.setIcon(new ImageIcon(icon.getImage().getScaledInstance(width, height, 1)));//将标签添加到面板中this.add(jl);}

        3.RightJPanel类:右面板实现ActionListener接口,右面板成为了监听器,实现拼图。重要知识点:

a.确定按钮的位置和大小
bs=new JButton[hs*ls]; //创建按钮数组
widthbut=width/ls;// 计算按钮的宽度高度heightbut=height/hs;
for(int i=0;i<jbs.length;i++){//为每一个按钮实现初始化操作jbs[i]=new JButton();jbs[i].setSize(widthbut, heightbut);jbs[i].setLocation(i%ls*widthbut,i/ls*heightbut);// 添加按钮前要确定坐标位置
b. //图片的获取
BufferedImage subimage=buf.getSubimage(i%ls*widthxt,i/ls*heightxt, widthxt, heightxt); //小图的获取
c. //图片的缩放
Image image=subimage.getScaledInstance(widthbut, heightbut, 1);
d. //将小图图片放到按钮上
jbs[i].setIcon(new ImageIcon(image));
e. //设置按钮变色,不可用
jbs[i].setEnabled(false);
f. //设置按钮的监听,当按钮被单击,找ActionListener方法执行
jbs[i].addActionListener(this);
g. //设置最后一个按钮图片为空jbs[hs*ls-1].setIcon(null);kb=jbs[hs*ls-1];
h. //打乱按钮在面板中的顺序Random rand=new Random();//创建随机数对象for(int i=0;i<hs*ls;i++){ //打乱多次 for//生成两个随机数表示数组下标,互换两个数组元素的位置int index1 = rand.nextInt(hs * ls);int index2 = rand.nextInt(hs * ls);// getX 和getY 可以获取按钮的坐标位置int x1 = jbs[index1].getX();int y1 = jbs[index1].getY();int x2 = jbs[index2].getX();int y2 = jbs[index2].getY();jbs[index1].setLocation(x2, y2);jbs[index2].setLocation(x1, y1);jbs[i].setEnabled(true);}
i. //获取用户单击的按钮,通过ActionEvent e的方法getSource获取事件源,需要将得到的object类型中转换为按钮类型
JButton jb=(JButton)e.getSource();
j. //获取单击按钮和空白按钮的坐标int x1=jb.getX();int y1=jb.getY();int x2=kb.getX();int y2=kb.getY();
k. //判断单击按钮和空白按钮是否相邻,相邻则位置互换
if(Math.abs((x1-x2)/widthbut)+Math.abs((y1-y2)/heightbut)==1){jb.setLocation(x2, y2);// 用Math.abs取绝对值kb.setLocation(x1, y1);times++;}
l. //判断是否拼图成功if(isWin()){JOptionPane.showMessageDialog(null, "恭喜,拼图成功,总共步数:"+times);//使得按钮不可用for(int i=0;i<jbs.length;i++){jbs[i].setEnabled(false);}
m. //创建文件字符输出流对象,指向c盘,追加数据到文件
String info=hs+"*"+ls+"拼图的记录:"+name+"步数是:"+times+"\r\n";
FileWriter fw=new FileWriter("c://a//1.dat",true);fw.write(info);fw.close();
n. //获取每个按钮的坐标for(int i=0 ; i<jbs.length;i++){int x=jbs[i].getX()/widthbut;int y=jbs[i].getY()/heightbut;//方法二:通过下标值,也可获取按钮坐标  横坐标:i%ls  纵坐标 i/lsif(i%ls!=x || i/ls!=y){return false;}}

        4.TpJFrame类:实现图片分割功能。知识点有:

a. //显示一个打开对话框,选择一个图片文件,将文件转换为url对象, JFileChooser jfc=new JFileChooser();
b. //设置文件的扩展名jfc.setFileFilter(new FileNameExtensionFilter("图片文件", "jpg","bmp","jpeg"));
c. //获取用户选择的文件完整名称
jfc.getSelectedFile().getAbsolutePath()d.//获取图片后,将图片转换成Image类型的对象,进行缩放,然后再将Image类型对象转换成ImageIcon类型的对象,将图片放到jlb中
jlb.setIcon(new ImageIcon(new ImageIcon (jtf.getText()).getImage().getScaledInstance(100,100, 1)));
e. //从本地文本读取图片BufferedImage buf=ImageIO.read(new File(jtf.getText()));
f. //设置该面板标题
jp3.setBorder(BorderFactory.createTitledBorder("选择保存位置"));

3.1.2开发步骤

        1.配置开发环境,进行环境变量的配置:JAVA_HOME,path。

        2.创建窗体类MainJFrame,设置窗体大小、标题、窗体大小是否可变、窗体位置等等。在窗体内设置菜单、菜单项、单选菜单项等信息,并添加到窗体内。明确左面板、右面板、中间面板和窗体的关系:在窗体中设置一个中间面板,中间面板包括左面板和右面板。

        3.中间面板布局方式为网格布局。添加左面板和右面板:左面板(LeftJPanel)为自定义面板,继承JPanel;右面板(RightJPanel)为自定义面板,继承JPanel。

        4.左面板的设计:首先在主窗体中定义,将左面板添加到中间面板,再将中间面板添加到窗体,并进行初始化。然后在左面板类中添加一个标签,并在标签上显示图片,并实现图片缩放。

        在标签上显示图片的方法为:

ImageIcon(URL location)根据指定的 URL 创建一个 ImageIcon。相对路径:url=this.getClass().getResource("s4.jpg");绝对路径:url=new URL(“file:\\”+”d:\\abc\\1.jpg”);

        实现图片缩放的方法:图片放置在标签中,使用的类是ImageIcon,这个类没有缩放功能,Image类有缩放功能。所以要实现ImageIcon类和Image类相互转换。转换方法:

a.将ImageIcon的对象转换成Image类型的对象:public Image getImage()icon.getImage().getScaledInstance(700,700,1)b.将Image类型对象转换成ImageIcon类型的对象:ImageIcon的构造方法 ImageIcon(Image image)

        5.右面板的设计:首先在主窗体中定义,将右面板添加到中间面板,再将中间面板添加到窗体,并进行初始化。然后在右面板定义按钮数组、按钮大小及位置。然后进行图片分割,使图片显示在按钮上,在未点击开始按钮时使所有按钮变灰,不可用。设置最后一个按钮为空白按钮,方便单击按钮和空白按钮的相互转换。具体分析为:

a.首先分析按钮的大小和位置的关系,定义按钮的宽度和高度、按钮数组、行数和列数,在游戏未开始时,设置按钮不可见。bs=new JButton[hs*ls]; //创建按钮数组
widthbut=width/ls;// 计算按钮的宽度高度heightbut=height/hs;
for(int i=0;i<jbs.length;i++){//为每一个按钮实现初始化操作jbs[i]=new JButton();jbs[i].setSize(widthbut, heightbut);jbs[i].setLocation(i%ls*widthbut,i/ls*heightbut);// 添加按钮前要确定坐标位置add(jbs[i]); //添加按钮到右面板jbs[i].setEnabled(false);// 使得按钮变灰色不可用
b.实现图片分割:使用ImageIO类对图片进行读写,然后使用BufferedImage类获取BufferedImage类的对象对图片进行分割,使用到的方法为:
读图片文件:public static BufferedImage read(URL input) throws IOException
写图片文件:public static boolean write(RenderedImage im, String formatName, File output) throws IOException
分割方法:public BufferedImage getSubimage(int x, int y, int w, int h)
代码:BufferedImage subimage=buf.getSubimage(i%ls*widthxt, i/ls*heightxt, widthxt, heightxt); //小图的获取
c.分割图片后,要对图片进行缩放。使用Image类中的getScaledInstance()方法对图片进行缩放。方法为:
public Image getScaledInstance(int width, int height,int hints)
代码: Image image=subimage.getScaledInstance(widthbut, heightbut, 1); //小图的缩放
d.最后添加一个空白按钮在右下角,为实现按钮的移动提供条件。
JButton kb; //空白按钮
jbs[hs*ls-1].setIcon(null); //设置最后一个按钮图片为空
kb=jbs[hs*ls-1];

        6.拼图完成后与左面板的原图比较进行判赢。设置不同游戏等级,可分为简单、一般、困难。若想更换图片,可进行图片的更换。

        a. 开始菜单单击时,执行具体操作只与右面板的组件相关,代码放到右面板类中

        通过改变按钮的坐标位置打乱按钮的顺序。方法是:生成两个随机数表示数组下标,互换两个数组元素的位置,按钮的方法getX和getY可以获取按钮的坐标。

相关代码:

 Random rand=new Random();//创建随机数对象int index1 = rand.nextInt(hs * ls); /生成两个随机数表示数组下标,互换两个数组元素的位置int index2 = rand.nextInt(hs * ls);

        b. 当对右面板中的按钮单击的时候,移动按钮。通过按钮的单击事件的处理,设置按钮的监听事件ActionListener,将代码写在监听事件中。代码为:

jbs[i].addActionListener(this); //设置按钮的监听,当按钮被单击,找ActionListener方法执行

        c.当用户拼图完成后,与原图进行比较判断是否拼图成功。判断拼图是否成功,主要取决于每一个按钮通过索引下标获取的位置值,与当前按钮的位置值是否相同。相关代码:

for(int i=0 ; i<jbs.length;i++){//获取每个按钮的坐标int x=jbs[i].getX()/widthbut;int y=jbs[i].getY()/heightbut;if(i%ls!=x || i/ls!=y){return false;}}return true;

        d.设置游戏等级,即游戏的难易度。而游戏的难易度主要与右面板的行数和列数有关。可将行数hs和列数ls的值传给右面板,并对菜单进行监听和使用removeAll方法来清除所有组件来实现难易度。相关代码为:

rp.hs=2; //等级为简单时,传递2*2到右面板rp.ls=2;rp.init(url); //调用右面板组件初始化的方法

        e.在菜单项中有更换图片选项,用户可单击该菜单项,选择当前电脑中的图片文件,替换游戏中已有的图片。通过使用url数据的传递替换选择的图片,在两个面板中都起作用,即左面板的标签的背景图要换,右面板中的分割原图也要变。可通过监听事件实现,涉及的类有涉及到的类JFileChooser、FileNameExtendsionFilter,具体实现如下:

//显示一个打开对话框,选择一个图片文件,将文件转换为url对象,调用左右面板的相应方法
JFileChooser jfc=new JFileChooser();
//设置文件的扩展名
jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|jif)", "jpg","png","gif")); 
//null表示父容器是谁
int sd=jfc.showOpenDialog(MainJFrame.this); 
if(sd==jfc.APPROVE_OPTION)//如果用户选择打开了按钮
{  String file=jfc.getSelectedFile().getAbsolutePath();
//获取用户选择的文件完整名称
url=new URL("file:\\"+file);lp.init(url);rp.init(url);	}

        f.整个框架实现完成后,可设置计时和计数功能。

        计时:从单击开始菜单时计时开始,拼图成功计时结束。通过System类的currentTimeMillis ()方法,获取当前系统时间的毫秒值;通过线程的run()方法中,定时获取当前系统的时间点,线程的定义方法有两种:继承Thread类;实现Runnable接口,创建带实现接口的子类对象的Thread对象,重写run方法。通过公式(endTime-startTime)/1000计算出以秒为单位的时间段。

        计数:设置一个标签 total_count,使计数显示在菜单栏中,在设置一个计数功能 int times,判断按钮是否可以移动使times加1来实现计数功能。

        g.如果拼图成功,将信息记录到文件中,即菜单项中的游戏记录:显示用户之前的记录结果,读取文件并显示。通过FileWriter记录当前信息到文件中,FileReader读取文件。

        h.如果不想保留之前的记录,可将文件删除,即实现菜单项中的清空记录。相关代码为:

File f=new File("c://a");if(f.exists()){f.delete();

        7.可增加一个功能在菜单项中添加图片分割,新建一个TPJFrame类实现图片分割。

        a.新建窗口,在新窗口中设置组件四个面板,三个按钮,四个文本框和标题等等。

        b.首先通过单击选择图片按钮获取图片文件,将文件转换为url对象,获取用户选择的文件完整名称,获取图片后,将图片转换成Image类型的对象,进行缩放,然后再将Image类型对象转换成ImageIcon类型的对象,将图片放到jlb中。

4 实训总结及心得

见文档。

这篇关于Java项目 拼图游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/831505

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p