java实现拼图游戏
作者:angry_youth 发布时间:2022-09-21 11:14:19
标签:java,拼图游戏
本文实例为大家分享了java实现拼图游戏的具体代码,供大家参考,具体内容如下
游戏说明:
设计一款拼图游戏,要求点击图片按钮,实现图片按钮的移动,直到每一个按钮都到达指定位置游戏终止退出。
游戏设计思路:
1.准备一张图像文件;
2.创建N个按钮图标,每个按钮图标里面存入一张分割后的图片信息;
3.创建一个空白按钮用于和图标按钮交换位置,达到移动的效果;
4.乱序,将按钮图标乱序,完成游戏效果;
5.创建一个面板添加游戏开始和游戏结束按钮;
6.设计游戏窗口;
游戏界面设计基本结构:
代码实现:
Cell类----设计每个按钮对象应该具备的属性功能---针对按钮
package puzzle_game;
import java.awt.Rectangle;
import javax.swing.Icon;
import javax.swing.JButton;
@SuppressWarnings("serial")
public class Cell extends JButton{
private static int IMAGEWIDTH;//设置按钮的宽度大小
private static int IMAGEHEIGHT;
private int ID = 0;//设置当前按钮的指向坐标
public Cell(Icon icon, int id, int imagewidth, int height)//构造函数初始化,传入两个参数,一个是图像的图标,一个是该按钮的数组ID
{
this.setIcon(icon);
this.ID = id;
this.IMAGEWIDTH = imagewidth;
this.IMAGEHEIGHT = height;
this.setSize(IMAGEWIDTH, IMAGEHEIGHT);
}
public void move(Direction dir)//移动
{
Rectangle rec = this.getBounds();//获取当前对象的这个边框
switch(dir)
{
case UP://向上移动,改变坐标
this.setLocation(rec.x, rec.y + IMAGEHEIGHT);
break;
case DOWN://向下移动
this.setLocation(rec.x, rec.y - IMAGEHEIGHT);
break;
case LEFT://向左移动
this.setLocation(rec.x - IMAGEWIDTH, rec.y);
break;
case RIGHT://向右移动
this.setLocation(rec.x + IMAGEWIDTH, rec.y);
break;
}
}
public int getID() {
return ID;
}
public int getX()
{
return this.getBounds().x;
}
public int getY()
{
return this.getBounds().y;
}
}
Direction类------方向枚举类,存放移动的方向
package puzzle_game;
public enum Direction {
UP,
DOWN,
LEFT,
RIGHT
}
GamePanel类-----游戏面板设计类,真正的游戏思想从此开始
主要实现的功能有:
1.初始化面板按钮数组,将图像转化成图标然后存入按钮中;
2.打乱数组面板中的按钮排序,实现游戏娱乐功能;
3.每个按钮添加监听机制,实现点击按钮后的移动功能;
package puzzle_game;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class GamePanel extends JPanel implements MouseListener{
private Cell BlankCell = null;
private int row = 4;
private int col = 4;//设置这个拼图的行列
private Cell cells[] = new Cell[row*col];//创建一个按钮对象数组
int ImageWidth;
int ImageHeight;
public GamePanel()//构造函数
{
this.setLayout(null);
init();
}
public void init()//初始化完成以下功能--完成图像的切割,完成图像到图标的转换,完成按钮图标的添加,将按钮添加到面板上,并且给每一个按钮添加监听机制
{
int num = 0;
BufferedImage buf = null;
BufferedImage bufnew = null;
ImageIcon icon = null;
int width = 0;
int height = 0;
try
{
buf = ImageIO.read(new File("F:/Image/Puzzle_game/puze.jpg"));//读取文件图像
ImageWidth = buf.getWidth();
ImageHeight = buf.getHeight();
System.out.println("ImageWidth->"+ImageWidth+"ImageHeight->"+ImageHeight);
width = ImageWidth/col;
height = ImageHeight/row;
}catch(Exception e)
{
System.out.println(e);
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
num = i*col+j;//表示当前这个图像的坐标id,在数组中的下标
if(num < row*col-1)
{
bufnew = buf.getSubimage(width*j, height*i, width, height);
icon = new ImageIcon(bufnew);//将图像转化成图标
}
else//使最后一张图像为空白图像
{
icon = new ImageIcon("F:/Image/Puzzle_game/background2.jpg");//一张空白图像
}
cells[num] = new Cell(icon, num, width, height);//添加图标到每一个BUTTON按钮上面
cells[num].setLocation(width*j, height*i);
}
}
BlankCell = cells[cells.length-1];//初始化空白格
for(int i = 0; i < cells.length; i++)
{
this.add(cells[i]);//将每一个按钮添加到当前这个面板上面
if(i < cells.length-1)
cells[i].addMouseListener(this);//空白格不添加监听机制
}
}
public void OutOfOrder()//乱序----打乱图片的排布顺序
{
Random random = new Random();
for(int i = 0 ; i < cells.length ; i++)
{
int index1 = random.nextInt(cells.length);//cells的长度是9,但是他的上限是9,取不到9,所取值范围是0-8
int index2 = random.nextInt(cells.length);
int x = cells[index1].getX();
int y = cells[index1].getY();//获取下标是index1的数组元素按钮的坐标
cells[index1].setLocation(cells[index2].getX(), cells[index2].getY());
cells[index2].setLocation(x, y);
}
}
public boolean IsWin()//判断游戏玩家是否赢
{
for(int i = 0; i < cells.length; i++)
{
int x = cells[i].getX();
int y = cells[i].getY();
if(x/(ImageWidth/col) + y/(ImageHeight/row) != i)
{
return false;
}
}
return true;
}
public void mouseClicked(MouseEvent e)
{
Cell t = (Cell) e.getSource();
int x = BlankCell.getX();
int y = BlankCell.getY();
if(t.getY() == y && t.getX() + ImageWidth/col == x)//图像向右走
{
t.move(Direction.RIGHT);
BlankCell.move(Direction.LEFT);
}
else if(t.getY() == y && t.getX() - ImageWidth/col == x)//图像向左走
{
t.move(Direction.LEFT);
BlankCell.move(Direction.RIGHT);
}
else if(t.getX() == x && t.getY() + ImageHeight/row == y)//图像向上走
{
t.move(Direction.UP);
BlankCell.move(Direction.DOWN);
}
else if(t.getX() == x && t.getY() - ImageHeight/row == y)//图像向下走
{
t.move(Direction.DOWN);
BlankCell.move(Direction.UP);
}
if(IsWin())
{
int choice = JOptionPane.showConfirmDialog(null, "恭喜您过关了是否还来一局?", "提示", JOptionPane.YES_NO_OPTION);
if(choice == 0)//表示再来一局
{
this.OutOfOrder();
}
else//表示退出游戏
System.exit(1);
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
GameFrame类------设置游戏的打开窗口类,创建了一个菜单面板存放游戏开始和游戏结束两个按钮,并且对游戏的窗口进行了基本设置,这是整个游戏的入口。
package puzzle_game;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GameFrame extends JFrame {
public JPanel pane1 = new JPanel();
public JButton button1 = new JButton("游戏开始");
public JButton button2 = new JButton("游戏结束");
public GameFrame()
{
super("拼图游戏");
pane1.setLayout(new FlowLayout());
pane1.add(button1);
pane1.add(button2);
Container con = this.getContentPane();
con.add(pane1,BorderLayout.NORTH);
GamePanel gamepane = new GamePanel();
con.add(gamepane,BorderLayout.CENTER);
this.setBounds(300, 300, 600, 600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button1.addActionListener(new ActionListener()
{
public void actionPerformed(final ActionEvent e)
{
gamepane.OutOfOrder();
}
});
button2.addActionListener(new ActionListener()
{
public void actionPerformed(final ActionEvent e)
{
System.exit(1);
}
});
}
public static void main(String[] args) {
new GameFrame(); }
}
这是刚运行程序以后的界面,也是拼图成功的界面,我设置的是4*4模式,你也可以根据自己的喜好设计模式诸如–2*3,3*4,都可以;
这是我点击开始以后运行的界面,当然每次都不同,因为乱序是随机生成的顺序,那么现在就可以玩你自己的游戏了:
来源:https://blog.csdn.net/angry_youth/article/details/71404651


猜你喜欢
- 定义注解也叫原数据,它是JDK1.5及之后版本引入的一个特性,它可以声明在类、方法、变量等前面,用来对这些元素进行说明。作用生成文档:通过代
- 开场白我本来是一名android开发者,突然就对java后端产生了浓烈的兴趣。所以,立马就转到了后端。第一个项目使用的使用Spring Da
- 在混淆编译之前,我的程序可以正常运行,混淆编译时,报告如下错误: Error:Execution failed for task ‘:gvi
- LongAdder实现原理图高并发下N多线程同时去操作一个变量会造成大量线程CAS失败,然后处于自旋状态,导致严重浪费CPU资源,降低了并发
- 最近工作遇到一个需求,需要下载excel模板,编辑后上传解析存储到数据库。因此为了更好的理解公司框架,我就自己先用spring mvc实现了
- Java Json的各种处理一、net.sf.json1、Json转MapJSONObject jsonObject = JSONObjec
- 上一小节我们学习了FastThreadLocal的创建和get方法的实现逻辑, 这一小节学习FastThreadLocal的set方法的实现
- 我们来简单实现一个cookie。一、简单介绍Cookie 是一些数据, 存储于你电脑上的文本文件中。当 web 服务器向浏览器发送 web
- springboot 启动排除某些bean的注入问题:最近做项目的时候,需要引入其他的jar。然后还需要扫描这些jar里的某些bean。于是
- 前言在最近的一个项目中做了一个涂鸦的效果,手指快速移动,会出现折线,这篇文章记录笔触优化。下面话不多说了,来一起看看详细的介绍吧。优化前优化
- 前言内存泄漏简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系
- 前言提问:springboot项目,开发环境、测试环境和生产环境配置文件如何分开表示?答:多profile文件方式1、多环境配置(profi
- ElGamal数字签名,供大家参考,具体内容如下一、实验目的学习ElGamal算法在数字签名方面的使用,掌握教科书版本的ElGamal数字签
- Input源码解读——从"Show tabs"开始本文基于Android T版本
- 最近有小伙伴问我mybatis有没有自动创建表结构的功能,因为他们之前一直使用hibernate用习惯了,理所当然的认为,在实体类上配置 *
- Spring Security OAuth 默认提供OAuth2.0 的四大基本授权方式(authorization_code\implic
- Java中List.of()和Arrays.asList()的区别及原因动手写一下,让自己更有印象1.Arrays.asList()可以插入
- 1. 前言在目前众多编程语言中,Java 语言的表现还是抢眼,不论是企业级服务端开发,还是 Andorid 客户端开发,都是作为开发语言的首
- 本文实例讲述了C#实现文件压缩与解压的方法。分享给大家供大家参考,具体如下:在企业开发过程中经常会遇到文件的压缩与解压,虽然网上很多流行的压
- filter类不能注入@Autowired变量问题描述项目中的登录是用了shiro以及filter * 。输入正确的账号密码之后却不能正常登