作者简介
作者名:编程界明世隐
简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞!
系列目录
1. Java俄罗斯方块
2. Java五子棋小游戏
3. 老Java程序员花一天时间写了个飞机大战
4. Java植物大战僵尸
5. 老Java程序员花2天写了个连连看
6. Java消消乐(天天爱消除)
7. Java贪吃蛇小游戏
8. Java扫雷小游戏
9. Java坦克大战
10. Java迷宫小游戏
引言:
前几天群里的小伙伴问我Java小游戏啥时候做完,怎么还没更新,说能不能提个建议,然后就说明哥能不能做个拼图游戏。
哈哈,像我这么帅气的博主向来都不太会拒绝人的,于是,它来了它来了。
效果图
实现思路
- 绘制窗口。
- 加载好所有的图片。
- 绘制按钮、边框等。
- 创建右边预览小图。
- 将大图切片,并展示。
- 点击开始按钮,打乱图片位置。
- 加入鼠标移入和点击事件,处理移入和点击效果。
- 点击交换后判断顺序,如果顺序正确则提示成功。
代码实现
创建窗口
首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(window的对象),每个游戏都有一个窗口,设置好窗口标题、尺寸、布局等就可以。
package main;
import java.awt.Color;
import javax.swing.JFrame;
/**
*窗体类
*/
public class GameFrame extends JFrame {
//构造方法
public GameFrame(){
setTitle("拼图游戏");//设置标题
setSize(874, 412);//设置窗体大小
getContentPane().setBackground(new Color(0,0,0));//加上黑色背景
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭后进程退出
setLocationRelativeTo(null);//居中
setResizable(false);//不允许变大
//setVisible(true);//设置显示窗体
}
}
复制代码
创建面板容器GamePanel继承至JPanel
package main;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
/*
* 画布类
*/
public class GamePanel extends JPanel {
private JMenuBar jmb = null;
private GameFrame mainFrame = null;
private GamePanel panel = null;
//构造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
}
}
复制代码
再创建一个Main类,来启动这个窗口,用来启动。
package main;
//Main类
public class Main {
public static void main(String[] args) {
GameFrame frame = new GameFrame();
GamePanel panel = new GamePanel(frame);
frame.add(panel);
frame.setVisible(true);
}
}
复制代码
右键执行这个Main类,窗口建出来了(加的黑色背景不好看)
加载好所有的图片
package common;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
//图片加载
public class ImageValue {
//图片路径
private static String path = "/images/";
//图片集合
public static Map<Integer,BufferedImage> images = new HashMap<Integer,BufferedImage>();
//初始化图片方法
public static void init() {
try {
//加载16张图片,并放入Map中
for (int i = 1; i <= 16; i++) {
images.put(i,ImageIO.read(ImageValue.class.getResource(path+i+".jpeg")));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
在构造函数中调用,待会就可以直接使用了。
创建边框
//绘制边框
private void drawBorder(Graphics g) {
BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(128,128,128));
g_2d.setStroke(bs_2);
g_2d.drawRect(6, 6, 652, 372);
}
//绘制右边预览边框
private void drawViewBorder(Graphics g) {
BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(128,128,128));
g_2d.setStroke(bs_2);
g_2d.drawRect(658, 6, 204, 372);
}
复制代码
在GamePanel重写 paint 方法,并调用这两个方法,如下:
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制边框
drawBorder(g);
//绘制右边预览边框
drawViewBorder(g);
}
复制代码
运行效果如下:
难度系数、预览图等文字
难度系数默认是3
创建难度系数、预览图等
//绘制预览图文字
private void drawViewText(Graphics g) {
//得分
Color oColor = g.getColor();
oColor = g.getColor();
g.setColor(Color.white);
g.setFont(new Font("思源宋体", Font.BOLD, 18));
g.drawString("预览图",668, 40);
g.setColor(oColor);
}
//绘制难度系数显示
private void drawGradeText(Graphics g) {
//得分
Color oColor = g.getColor();
oColor = g.getColor();
g.setColor(Color.white);
g.setFont(new Font("思源宋体", Font.BOLD, 18));
g.drawString("难度系数:"+grade+"",668, 210);
g.setColor(oColor);
}
复制代码
在paint方法中调用:
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制边框
drawBorder(g);
//绘制右边预览边框
drawViewBorder(g);
//绘制预览图文字
drawViewText(g);
//绘制难度系数显示
drawGradeText(g);
}
复制代码
创建按钮
创建4个按钮的代码如下:
//初始化
private void init() {
// 开始按钮
JButton btnStart = new JButton();
btnStart.setFont(new Font("思源宋体", Font.BOLD, 18));
btnStart.setFocusPainted(false);
btnStart.setText("开始");
btnStart.setBounds(668, 300, 80, 33);
btnStart.setBorder(BorderFactory.createRaisedBevelBorder());
this.add(btnStart);
btnStart.addActionListener(this);
btnStart.setActionCommand("start");
//切换按钮
JButton nextStart = new JButton();
nextStart.setFont(new Font("思源宋体", Font.BOLD, 18));
nextStart.setFocusPainted(false);
nextStart.setText("换换");
nextStart.setBounds(768, 300, 80, 33);
nextStart.setBorder(BorderFactory.createRaisedBevelBorder());
this.add(nextStart);
nextStart.addActionListener(this);
nextStart.setActionCommand("next");
//难度减按钮
JButton gradeDecrease = new JButton();
gradeDecrease.setFont(new Font("思源宋体", Font.BOLD, 18));
gradeDecrease.setFocusPainted(false);
gradeDecrease.setText("难度减");
gradeDecrease.setBounds(668, 250, 80, 33);
gradeDecrease.setBorder(BorderFactory.createRaisedBevelBorder());
this.add(gradeDecrease);
gradeDecrease.addActionListener(this);
gradeDecrease.setActionCommand("gradeDecrease");
//难度加按钮
JButton gradeIncrease = new JButton();
gradeIncrease.setFont(new Font("思源宋体", Font.BOLD, 18));
gradeIncrease.setFocusPainted(false);
gradeIncrease.setText("难度加");
gradeIncrease.setBounds(768, 250, 80, 33);
gradeIncrease.setBorder(BorderFactory.createRaisedBevelBorder());
this.add(gradeIncrease);
gradeIncrease.addActionListener(this);
gradeIncrease.setActionCommand("gradeIncrease");
}
复制代码
此时可以看到开发工具中,报红,因为没有实现ActionListener
实现 ActionListener 并重新方法 actionPerformed
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
if("start".equals(command)){//开始
}else if("next".equals(command)){//切换
}else if("gradeDecrease".equals(command)){//难度减
}else if("gradeIncrease".equals(command)){//难度加
}
}
复制代码
在构造函数中调用 init方法,运行效果如下:
实现右侧预览小图
创建 ViewImage 类,这个类很简单就是通过调用draw方法在指定的位置、指定的宽高、绘制指定的图片。
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
/*
* 预览图
*/
public class ViewImage {
private int x = 0;// x坐标
private int y = 0;// y坐标
private int w = 0;// 宽
private int h = 0;// 高
private BufferedImage img = null;// 图片对象
public ViewImage(BufferedImage img,int x,int y,int w,int h){
this.img=img;
this.x=x;
this.y=y;
this.w=w;
this.h=h;
}
// 图片绘制方法
public void draw(Graphics g) {
g.drawImage(img, x, y, w, h, null);
}
}
复制代码
创建预览图实例
private void createViewImage() {
BufferedImage img = ImageValue.images.get(imageKey);
int x=664;
int y=62;
int w=192;
int h=108;
viewImage = new ViewImage(img, x, y, w, h);
}
复制代码
注意需加入成员变量
private ViewImage viewImage = null;
private int imageKey = 1;//图片下标,默认1
复制代码
在GamePanel的构造方法中调用
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//图片的加载
ImageValue.init();
//初始化
init();
//创建预览图
createViewImage();
}
复制代码
绘制预览图的方法
//绘制预览图
private void drawViewImage(Graphics g) {
if(viewImage!=null){
viewImage.draw(g);
}
}
复制代码
在paint方法中调用
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制边框
drawBorder(g);
//绘制右边预览边框
drawViewBorder(g);
//绘制预览图文字
drawViewText(g);
//绘制难度系数显示
drawGradeText(g);
//绘制预览图
drawViewImage(g);
}
复制代码
运行效果如下:
将大图切片
图片绘制方法介绍:
g.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
参数说明:
img – 绘制指定图像。如果 img 为 null,不执行任何操作。
dx1 – 目标矩形第一个角的 x 坐标。
dy1 – 目标矩形第一个角的 y 坐标。
dx2 – 目标矩形第二个角的 x 坐标。
dy2 – 目标矩形第二个角的 y 坐标。
sx1 – 源矩形第一个角的 x 坐标。
sy1 – 源矩形第一个角的 y 坐标。
sx2 – 源矩形第二个角的 x 坐标。
sy2 – 源矩形第二个角的 y 坐标。
创建 SmallImage 类
属性名 | 说明 |
---|---|
dx1 | 目标显示左上角x坐标 |
dy1 | 目标显示左上角y坐标 |
dWidth | 目标宽度,与dx1相加计算第2个点dx2 |
dHeight | 目标高度,与dy1相加计算第2个点dy2 |
sx1 | 源图左上角x坐标 |
sy1 | 源图左上角y坐标 |
sWidth | 源宽度,与sx1相加计算第2个点sx2 |
sHeight | 源高度,与sy1相加计算第2个点sy2 |
i | 下标i(切片交换时候用的) |
j | 下标j(切片交换时候用的) |
oi | 原始下标i(用来比较顺序) |
oj | 原始下标j(用来比较顺序) |
img | 图片对象 |
selected | 选择状态,根据选择的状态来显示小图片的边框 |
disX | x方向长 |
disY | y方向高 |
注意点:
- 根据的 oi,oj 来计算源的两个点坐标,因为一旦实例话oi,oj 就是固定的,也就是来源变。
- 根据 i,j 来计算目标的两个点坐标,当我们执行拼图交换位置的时候,就是交换 i,j ,所以达到交换的目的。
//初始化
public void init() {
int start = 12;//初始偏移量,根据边框来偏移
//根据传入的i j 来计算目标的两个点坐标
int x = start+i*disX;
int y = start+j*disY;
this.dx1 = x;
this.dy1 = y;
this.dWidth = disX;
this.dHeight = disY;
//根据的oi oj 来计算源的两个点坐标
int sx = start+oi*disX;
int sy = start+oj*disY;
this.sx1 = sx;
this.sy1 = sy;
this.sWidth = disX;
this.sHeight = disY;
}
复制代码
- 绘制完图片后要根据图显示类型来显示小边框。
//图片绘制方法
public void draw(Graphics g) {
//每次绘制之前要重新计算
init();
/*
* img - 要绘制的指定图像。如果 img 为 null,则此方法不执行任何操作。
dx1 - 目标矩形第一个角的 x 坐标。
dy1 - 目标矩形第一个角的 y 坐标。
dx2 - 目标矩形第二个角的 x 坐标。
dy2 - 目标矩形第二个角的 y 坐标。
sx1 - 源矩形第一个角的 x 坐标。
sy1 - 源矩形第一个角的 y 坐标。
sx2 - 源矩形第二个角的 x 坐标。
sy2 - 源矩形第二个角的 y 坐标。
*/
g.drawImage(img, dx1, dy1, dx1+dWidth, dy1+dHeight, sx1, sy1, sx1+sWidth, sy1+sHeight,
null);
if(selected==0){//默认黑色
g.setColor(new Color(0,0,0));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}else if(selected==1){//鼠标移入白色
g.setColor(new Color(255,255,255));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}else if(selected==2){//选中,黄色
g.setColor(new Color(209,146,17));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}
}
复制代码
- 加入判断鼠标是否在小图片范围内的方法
//判断是否在小图片范围内
public boolean isPoint(int x,int y){
//左上角
int x1 = this.dx1;
int y1 = this.dy1;
//右下角
int x2 = this.dx1 + dWidth;
int y2 = this.dy1 + dHeight;
return x>x1&&y>y1&&x<x2&&y<y2;
}
复制代码
SmallImage类完整代码
package main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class SmallImage {
private int dx1 = 0;// x坐标
private int dy1 = 0;// y坐标
private int dWidth = 0;// 宽
private int dHeight = 0;// 高
private int sx1 = 0;// x坐标
private int sy1 = 0;// y坐标
private int sWidth = 0;// 宽
private int sHeight = 0;// 高
private int i = 0;// 下标i
private int j = 0;// 下标j
private int oi = 0;// 原始下标i
private int oj = 0;// 原始下标j
private BufferedImage img = null;// 图片对象
private int selected = 0;//选择状态
private int disX;//x方向长
private int disY;//y方向高
// 构造方法
public SmallImage(BufferedImage img, int i, int j, int disX, int disY) {
this.img = img;
this.i = this.oi = i;
this.j = this.oj = j;
this.disX=disX;
this.disY=disY;
}
//初始化
public void init() {
int start = 12;
int x = start+i*disX;
int y = start+j*disY;
this.dx1 = x;
this.dy1 = y;
this.dWidth = disX;
this.dHeight = disY;
int sx = start+oi*disX;
int sy = start+oj*disY;
this.sx1 = sx;
this.sy1 = sy;
this.sWidth = disX;
this.sHeight = disY;
}
// 图片绘制方法
public void draw(Graphics g) {
//每次绘制之前要重新计算
init();
/*
* img - 要绘制的指定图像。如果 img 为 null,则此方法不执行任何操作。
dx1 - 目标矩形第一个角的 x 坐标。
dy1 - 目标矩形第一个角的 y 坐标。
dx2 - 目标矩形第二个角的 x 坐标。
dy2 - 目标矩形第二个角的 y 坐标。
sx1 - 源矩形第一个角的 x 坐标。
sy1 - 源矩形第一个角的 y 坐标。
sx2 - 源矩形第二个角的 x 坐标。
sy2 - 源矩形第二个角的 y 坐标。
*/
g.drawImage(img, dx1, dy1, dx1+dWidth, dy1+dHeight, sx1, sy1, sx1+sWidth, sy1+sHeight,
null);
if(selected==0){//默认黑色
g.setColor(new Color(0,0,0));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}else if(selected==1){//鼠标移入白色
g.setColor(new Color(255,255,255));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}else if(selected==2){//选中,黄色
g.setColor(new Color(209,146,17));
g.drawRect(dx1, dy1, dWidth-1, dHeight-1);
}
}
//判断是否在小图片范围内
public boolean isPoint(int x,int y){
//左上角
int x1 = this.dx1;
int y1 = this.dy1;
//右下角
int x2 = this.dx1 + dWidth;
int y2 = this.dy1 + dHeight;
return x>x1&&y>y1&&x<x2&&y<y2;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
public int getOi() {
return oi;
}
public void setOi(int oi) {
this.oi = oi;
}
public int getOj() {
return oj;
}
public void setOj(int oj) {
this.oj = oj;
}
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected = selected;
}
}
复制代码
GamePanel类中加入成员变量
private String gameFlag="end";//游戏状态
private int grade=3;//难道系数,最小为3,最大为10
private int w=640;//图片的宽
private int h=360;//图片的高
private SmallImage[][] sImages;//图片二维数组
List<SmallImage> imageList = new ArrayList<SmallImage>();//图片集合
private SmallImage curSmallImage;//当前选择的小图片
复制代码
创建切片方法
//对图片进行切片
private void sliceImage(){
int disX = this.w/grade;//小图片的宽
int disY = this.h/grade;//小图片的高
//初始化小图片对象
SmallImage smallImage;
BufferedImage img = ImageValue.images.get(imageKey);
sImages = new SmallImage[grade][grade];
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = new SmallImage(img,i,j,disX, disY);
sImages[i][j]=smallImage;
imageList.add(smallImage);
}
}
}
复制代码
构造函数调用此方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//图片的加载
ImageValue.init();
//初始化
init();
//创建预览图
createViewImage();
//切片
sliceImage();
}
复制代码
绘制这些切片图形
//绘制小图片
private void drawSmallImages(Graphics g) {
SmallImage smallImage;
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = sImages[i][j];
if(smallImage!=null){
smallImage.draw(g);
}
}
}
}
复制代码
paint方法中调用,注意drawSmallImages放到前面,因为涉及到边框绘制,如果放到后面拼图的边框会变的很粗,也可以做别的处理,我这里就取巧了。
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制小图片
drawSmallImages(g);
//绘制边框
drawBorder(g);
//绘制右边预览边框
drawViewBorder(g);
//绘制预览图文字
drawViewText(g);
//绘制难度系数显示
drawGradeText(g);
//绘制预览图
drawViewImage(g);
}
复制代码
运行一下:
加入鼠标事件
移动事件,就是在图片的范围内,设置selected属性为1,然后重绘就行。
//鼠标点击、移动事件处理
private void createMouseListener() {
MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if(!"start".equals(gameFlag)) return ;
//获取鼠标坐标
int x = e.getX();
int y = e.getY();
SmallImage smallImage;
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = sImages[i][j];
if(smallImage!=null){
if(curSmallImage==smallImage){
//针对当前选择的小图片不做处理
continue;
}
if(smallImage.isPoint(x, y)){
//鼠标移入,设置边框白色
smallImage.setSelected(1);
}else{
//设置边框默认黑色
smallImage.setSelected(0);
}
}
}
}
//重绘
repaint();
}
};
addMouseMotionListener(mouseAdapter);
addMouseListener(mouseAdapter);
}
复制代码
注意在构造中调用哦
给几个按钮先添加好方法
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
if("start".equals(command)){//开始
restart();
}else if("next".equals(command)){//切换
next();
}else if("gradeDecrease".equals(command)){//难度减
gradeDecrease();
}else if("gradeIncrease".equals(command)){//难度加
gradeIncrease();
}
}
复制代码
实现这些方法,都比较简单,就不解释了,上代码:
//难度减
private void gradeDecrease() {
if(grade<=3){//最小为3
return ;
}
//数组清空
imageList.clear();
//清空二维数组
clearImages(sImages);
//先清空,再-- 不然数据没完全清空
grade--;
//切片
sliceImage();
//重新绘制
repaint();
}
//难度加
private void gradeIncrease() {
if(grade>=10){//最大为10
return ;
}
//数组清空
imageList.clear();
//清空二维数组
clearImages(sImages);
//先清空,再++ 不然会报错
grade++;
//切片
sliceImage();
//重新绘制
repaint();
}
//切换图片
void next(){
gameFlag = "end";
//图片切换到下一张
imageKey++;
//到了最后则切回第一张
if(imageKey>16){
imageKey=1;
}
//数组清空
imageList.clear();
//清空二维数组
clearImages(sImages);
//创建预览图
createViewImage();
//切片
sliceImage();
//重新绘制
repaint();
}
//重新开始
void restart() {
gameFlag = "start";
//当前选择图片设置为null
curSmallImage = null;
//清空二维数组
clearImages(sImages);
//随机排序,打乱拼图
Collections.shuffle(imageList);
//将排序后的图片添加到二维数组中
addImages();
//重新绘制
repaint();
}
//将排序后的图片添加到二维数组中
private void addImages() {
SmallImage smallImage;
int n=0;
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = imageList.get(n);
smallImage.setI(i);
smallImage.setJ(j);
sImages[i][j]=smallImage;
n++;
}
}
}
//清空指定二维数组
void clearImages(SmallImage[][] imgs){
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
imgs[i][j]=null;
}
}
}
//游戏胜利
public void gameWin() {
gameFlag = "end";
//弹出结束提示
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
JOptionPane.showMessageDialog(mainFrame, "你成功了,太棒了!");
}
复制代码
测试一下鼠标移入事件
处理鼠标点击事件
- 点击后判断是否已经有选择,如果没有则当前图片设置为已选择,并设置selected为2。
- 如果已经有选择的拼图块,则互相交换,交换就是交换 i 和 j即可。
- 交换完成后selected都设置为0,并且存储选择的对象设置为null。
- 每次交换完成后要进行差异比较,看拼图是否完成。
- 右键取消已经选择的处理。
@Override
public void mouseClicked(MouseEvent e) {
if(!"start".equals(gameFlag)) return ;
int buttonType = e.getButton();
if(buttonType==2){//滚轮
return ;
}else if(buttonType==1){//左键
boolean diffFlag =false;//是否要判断拼图完成
//获取鼠标坐标
int x = e.getX();
int y = e.getY();
SmallImage smallImage;
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = sImages[i][j];
if(smallImage!=null){
if(smallImage.isPoint(x, y)&& smallImage.getSelected()!=2){
if(curSmallImage!=null){//交换
//将curSmallImage 的i j临时存储
int ti = curSmallImage.getI();
int tj = curSmallImage.getJ();
//把smallImage的i j 设置给curSmallImage
curSmallImage.setI(smallImage.getI());
curSmallImage.setJ(smallImage.getJ());
//把curSmallImage的i j 设置给smallImage
smallImage.setI(ti);
smallImage.setJ(tj);
//将两个边框都设置为默认
curSmallImage.setSelected(0);
smallImage.setSelected(0);
//交换完 curSmallImage 置空
curSmallImage = null;
diffFlag =true;
}else {//标记为当前
curSmallImage = smallImage;
//设置边框红色
smallImage.setSelected(2);
}
}
}
}
}
//重绘
repaint();
//每次交换完要判断拼图是否完成
if(diffFlag && diff()){
gameWin();
return;
}
}else if(buttonType==3){//右键
//取消选择
if(curSmallImage!=null){
curSmallImage.setSelected(0);
curSmallImage=null;
//重绘
repaint();
}
}
}
复制代码
差异判断,比较每一个小图片的 i与oi,j与oj,如果都相同表示拼图完成 。
//差异比较 true表示没有差异
private boolean diff() {
//比较每一个小图片的 i与oi,j与oj,如果都相同表示拼图完成
SmallImage smallImage;
for(int i=0;i<grade;i++){
for(int j=0;j<grade;j++){
smallImage = sImages[i][j];
if(smallImage!=null){
//一旦有一个不成立,就表示没完成
if(!(smallImage.getI()==smallImage.getOi() &&
smallImage.getJ()==smallImage.getOj())){
return false;
}
}
}
}
return true;
}
复制代码
到这里基本就完成了,图片切换和难度系数的修改就不说明了。
看到这里的大佬,动动发财的小手 点赞 + 回复 + 收藏,能【 关注 】一波就更好了。
代码获取方式:
帮忙文章【点赞】 +【 收藏】+【关注】+【评论】 后,加V:qq283582761,我发给你!
更多精彩
1. Java俄罗斯方块
2. Java五子棋小游戏
3. 老Java程序员花一天时间写了个飞机大战
4. Java植物大战僵尸
5. 老Java程序员花2天写了个连连看
6. Java消消乐(天天爱消除)
7. Java贪吃蛇小游戏
8. Java扫雷小游戏
9. Java坦克大战
10. Java迷宫小游戏