java编程之拼图_java版拼图
基于java的拼图小游戏
学习java也有一段时间了,但是一直处于控制台的编程阶段,乏味的控制台看久了有没有给人一种很枯燥乏味的感觉呢?于是乎博主开始自己学习java的swing组件,让我们的程序可以脱离控制台。好了废话不多说了,下面开始整理我的第一个小游戏——拼图。
拼图的原理其实很简单,首先我们得准备一张完整的图片,其关键过程在于如何分割图片,打乱图片次序,以及图片之间的移动交换,最后判断是否拼图成功。
按照上述关键过程我们开始逐一进行描述吧!
首先准备一张图片规格可以自定义在这里我选择300*300的图片:
因为本程序需要切割图片并把每一块作为一个具体的东西放在面板上,因此我们可以使用JButton按钮组件,把截取的小图一图标的形式显示在按钮组件上。所以在此我们先创建一个Cell类并继承JButton类:
/**
* 此类作为拼图的按钮类,每一张分割的图片
* 都是以一个按钮的形式存在的
*/
import javax.swing.Icon;
import javax.swing.JButton;
import com.direction.Direction;
public class Cell extends JButton {
/*
* 记录按钮的位置
*/
private int place;
/*
* 定义每个按钮的宽度即图片的固定宽度为100px
*/
public static final int WIDTH=100;
/*
* 构造每个图片按钮
* 传入图标和位置参数
*/
public Cell(Icon icon,int place){
this.setIcon(icon);
this.place=place;
this.setSize(WIDTH, WIDTH);//设置每个按钮的大小为100*100
}
/*
* 获得单元按钮的x坐标
*/
public int getButtonX(){
return this.getBounds().x;
}
/*
* 获得单元按钮的Y坐标
*/
public int getButtonY(){
return this.getBounds().y;
}
/*
* 获取图片的位置
*/
public int getPlace(){
return this.place;
}
/*
* 移动按钮的方法
*/
public void move(Direction d){
int x=this.getButtonX();
int y=this.getButtonY();
switch(d){
//向上移动
case UP:this.setLocation(x, y-WIDTH);
break;
//向下移动
case DOWN:this.setLocation(x, y+WIDTH);
break;
//向左移动
case LEFT:this.setLocation(x-WIDTH, y);
break;
//向右移动
case RIGHT:this.setLocation(x+WIDTH, y);
break;
}
}
}
下面开始要进行图片的分割在这里用到了ImageIO类,BufferedImage类,首先我们得以流的形式把图片载入内存中,之后按照3*3的格式把整张图片分割成9张尺寸为100*100的矩形,在这里用到BufferedImage类中的getSubimage方法,该方法截取开始点的X,Y轴的坐标以及截取的width和height可以得到一个指定大小的图片,返回的也是一个BufferedImage对象。我们可以将每块小图片存放到按钮上,需要把BufferedImage对象转换成Icon对象
//定义接收整张图片
BufferedImage bi=null;
//定义接收分割后的一张图片
BufferedImage newImage=null;
//定义图片的序号
int place;
//定义每张小图截取的左上点位置
int x=0;
int y=0;
//定义图标对象
Icon icon=null;
try {
//读取图片以流的形式载入内存
bi=ImageIO.read(new File("./image/pic.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
/*
* 开始分割图片把图片分割成9*9的每个张小图并装入数组里
*/
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
place=i*3+j;//计算图片编号
//计算截取的左上角xy坐标
x=j*100;
y=i*100;
newImage=bi.getSubimage(x,y , 100, 100);
//将图片装入cells数组
if(place+1!=9){
icon=new ImageIcon(newImage);
}else{
icon=new ImageIcon("./image/blank.jpg");//获取空白图片
}
//将图片装入按钮中
Cell cell=new Cell(icon, place);
cell.setLocation(x, y);
cells[place]=cell;//将按钮存入数组
}
}
之后我们只需要将数组打乱即可,使用Random类
Random random=new Random();
for(int i=0;i
/*
*获取两个随机数m,n
*/
int m=random.nextInt(cells.length);
int n=random.nextInt(cells.length);
while(m==n){
m=random.nextInt(cells.length);
n=random.nextInt(cells.length);
}
int x=cells[m].getButtonX();
int y=cells[m].getButtonY();
//交换两个按钮
cells[m].setLocation(cells[n].getButtonX(), cells[n].getButtonY());
cells[n].setLocation(x, y);
}
之后为每个按钮注册监听
//获取空白图片
if(cellBlank==null){
cellBlank=cells[cells.length-1];
for(int i=0;i
//为每个按钮注册监听
cells[i].addMouseListener(this);
}
}
下面关键的来了,我们需要实现按钮与空白图片的按钮之间的上下左右的移动,通过鼠标单击的方法获取每个触发事件的对象,因此我们需要实现MouseListener接口的mouseClicked方法:在此方法中实现我们的移动过程:
@Override
public void mouseClicked(MouseEvent e) {
//获得点击图片的按钮对象
Cell cell=(Cell)e.getSource();
int x=cell.getButtonX();//获得当前按钮对象的x坐标
int y=cell.getButtonY();//获得当前按钮对象的y坐标
Cell blank=cells[8];//获得空白按钮图片对象
/*
* 如果事件对象在空白图片的左边
* 那么对象事件右移并把空白区域左移
*/
if(x-blank.getButtonX()==-Cell.WIDTH&&y==blank.getButtonY()){
//调用按钮对象中的move方法实现两个按钮之间的交换
cell.move(Direction.RIGHT);
blank.move(Direction.LEFT);
}
/*
*如果事件对象在空白图片的右边
*那么对象事件左移并把空白区域右移
*/
else if(x-blank.getButtonX()==Cell.WIDTH&&y==blank.getButtonY()){
cell.move(Direction.LEFT);
blank.move(Direction.RIGHT);
}
/*
* 如果事件对象在空白图片的上边
*那么对象事件下移并把空白区域上移
*/
else if(y-blank.getButtonY()==-Cell.WIDTH&&x==blank.getButtonX()){
cell.move(Direction.DOWN);
blank.move(Direction.UP);
}
/*
* 如果事件对象在空白图片的下边
*那么对象事件上移并把空白区域下移
*/
else if(y-blank.getButtonY()==Cell.WIDTH&&x==blank.getButtonX()){
cell.move(Direction.UP);
blank.move(Direction.DOWN);
}
}
至此我们的拼图就可以实现移动的功能了,此外对于方向的参数我这里使用了java中的枚举类只有4个参数:
public enum Direction {
UP,DOWN,LEFT,RIGHT;
}最后我们将我们的panel面板加入我们的主面板即可:
public class PicFrame extends JFrame {
public PicFrame(){
super("拼图游戏");
this.getContentPane().setLayout(new BorderLayout());
setBounds(300, 300, 358, 414);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel=new JPanel(new BorderLayout());
this.getContentPane().add(panel, BorderLayout.NORTH);
final GamePanel gp=new GamePanel();
JButton btn=new JButton("开始");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gp.randomButton();
}
});
panel.add(btn,BorderLayout.CENTER);
this.getContentPane().add(gp,BorderLayout.CENTER);
}
public static void main(String[] args) {
new PicFrame().setVisible(true);
}
}
最终效果如下:
java编程之拼图_java版拼图相关推荐
- Java编程思想第四版——第十五天
2012-04-23 121-131/913 Java编程思想第四版--第十五天 5.5.3 终结条件 通常不能指望finalize(),必须创建其他的"清理"方法,并明确的调用它 ...
- Java编程思想第四版学习总结
Java编程思想第四版学习总结 文章目录 Java编程思想第四版学习总结 第 1 章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重 ...
- java编程50实例_java编程实例大全及详解谜底(50例).doc
java编程实例大全及详解谜底(50例).doc 还剩 33页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: 谓 ...
- java编程规范换行_Java编程规范整理
近期即将开始编码阶段,特地整理一下各方面的编程规范与命名约定,以便内部团队风格统一. 文章大多从网络上收集汇总而来,参考列表附在文章末尾. Java编程规范整理 基本命名规范 包命名 包名按照域名的范 ...
- 第二章java编程基础测试题_Java编程基础测试题分享
单选题:(每道题目2分) 1. 下列哪个声明是错误的?(B) A. int i=10; B. float f=1.1; //float f=1.1f C. double d=34.4; D. byte ...
- java编程英语词汇_Java编程基础常见英语词汇
Java编程基础常见英语词汇 学编程英语基础要好,下面小编整理了Java编程基础常见英语词汇,希望对大家有帮助! OO:object-oriented ,面向对象 OOP: object-orient ...
- java编程兔子问题_JAVA编程题-用java解决兔子问题
题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 解答: 分析:从第一对兔子开始,第1个月1对兔 ...
- java编程的英文_Java编程基础常见英语词汇总编
Java编程基础常见英语词汇总编 以下是百分网小编收集的Java编程基础常见英语词汇,希望对您的学习有所帮助! Java编程基础常见英语词汇 OO:object-oriented ,面向对象 OOP: ...
- Java编程思想 第四版 读书笔记巩固基础,完善知识框架。
Java编程思想读书笔记 此笔记仅仅是作者的阅读此书时,发现自己错误认识和不牢固的知识,用来完善作者的知识框架,其列出重点不具有参考性,代码也是为了省工作量,简写代码,能看懂即可,语法并不规范 第一章 ...
最新文章
- 英伟达发布RTX 2000系列显卡,“实时光线追踪”究竟能为游戏带来什么?
- android studio 如何让包名展开
- android sina oauth2.0 code认证,Android通过第三方登录理解oauth2.0机制
- 【赠书】图神经网络基础与前沿最新书籍,赠5本学习
- python中bs4库_python系统学习2——beautiful soup库(bs4库)学习
- 关于“WARN: SQL Error: 1366, SQLState: HY000”错误的解决方案
- 局域网文件传输方式分析
- 第3次 实验 原码一位乘法实验
- c语言转换说明符总结(%d,%i,%u,%f,%o,%x,%X,%p,%s,%g,%e)
- 一封来自 1985 年程序员的辞职信
- c#录音和放音,超简单!不用DirectX
- 机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析...
- Android植入Wooboo广告教程
- 加解密算法及国密算法介绍
- 机器学习(Machine Learning,ML)
- EventBus的理解和使用
- 仿小米商城页面和简单效果
- 资产负债表和利润表的编制公式
- 全球区块链农业技术平台Dimitra与 Morpheus AMA回顾
- 重大改革:吴恩达,女儿识字后立马教她学Python!