java—连连看-实现消除

时间:2022-11-25 16:07:24

实现消除

1、Chess.java

package Linkup;

/**
 * 棋子封装类
 * 
 * @author laixl
 * 
 */

public class Chess {

    // 图片的 状态 //1.....20
    // 0表示消掉

    private int status;

    public Chess(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

}

2、Param.java

package tools;

import java.awt.Image;

import javax.swing.ImageIcon;

public class Param {
    
    //游戏总行数与总列数
    public static int rows=8;
    public static int cols=10;
    
    //棋子图标 宽与高
    public static int chessWidth =55;
    public static int chessHeight=55;
    
    //棋盘到边界的距离
    public static int marginWidth = 200-chessWidth;
    public static int marginHeight = 100-chessHeight;

    //游戏的背景图片
    public static Image imageBackground = new ImageIcon("Images/build/back.jpg").getImage();
    
    public static Image[] chessImage = new Image[20];
    static {
        for (int i = 0; i < chessImage.length; i++) {
            chessImage[i] = new ImageIcon("Images/build/" + (i + 1) + ".png").getImage();
        }
    }

}

3、MapPanel.java

package Linkup;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.Random;

import javax.swing.JPanel;

import tools.Core;
import tools.Param;

/**
 * 棋盘面板
 * 
 * @author laixl
 * 
 */

public class MapPanel extends JPanel implements MouseListener {
    Chess[][] arr = new Chess[Param.rows + 2][Param.cols + 2];
    // 粗线条
    Stroke stroke = new BasicStroke(3.0f);

    // 定义两个点 存放点击的两个点的坐标
    Point firstPoint;
    Point secondPoint;

    public MapPanel() {
        initArr();

        this.addMouseListener(this);
    }

    public void initArr() {

        Random random = new Random();
        for (int i = 1; i <= 20; i++) {
            int count = 0;
            while (count < 4) {
                int x = random.nextInt(8) + 1;
                int y = random.nextInt(10) + 1;
                if (arr[x][y] == null) {
                    arr[x][y] = new Chess(i);
                    count++;
                }
            }
        }

        // 外围一圈 手动初始化
        // 最上面一行与最下面一行
        for (int i = 0; i < arr[0].length; i++) {
            arr[0][i] = new Chess(0);
            arr[arr.length - 1][i] = new Chess(0);
        }

        // 最左边一行与最右边一行
        for (int i = 0; i < arr.length; i++) {
            arr[i][0] = new Chess(0);

            arr[i][arr[0].length - 1] = new Chess(0);
        }

    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(Param.imageBackground, 0, 0, this);// 设置背景图片

        

        for (int i = 1; i < arr.length; i++) {
            for (int j = 1; j < arr[i].length; j++) {
                if (arr[i][j].getStatus() != 0) {
                    int x = j * Param.chessWidth + Param.marginWidth;
                    int y = i * Param.chessHeight + Param.marginHeight;
                    g.drawImage(Param.chessImage[arr[i][j].getStatus() - 1], x,
                            y, this);
                    g.setColor(Color.green);
                    g.drawRect(x, y, Param.chessWidth, Param.chessHeight);
                }
            }
        }
        // 判断第一个点firstPoint不为null
        if (firstPoint != null) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setStroke(stroke);
            g2d.setColor(Color.blue);
            int rowX = firstPoint.y * Param.chessWidth + Param.marginWidth;

            int rowY = firstPoint.x * Param.chessHeight + Param.marginHeight;

            g2d.drawRect(rowX + 2, rowY + 2, Param.chessWidth - 4,
                    Param.chessHeight - 4);
        }

    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getModifiers() != InputEvent.BUTTON1_MASK) {
            return;
        }

        int x = e.getX();
        int y = e.getY();

        int X = (x - Param.marginWidth) / Param.chessWidth;
        int rowX = X * Param.chessWidth + Param.marginWidth;
        int Y = (y - Param.marginHeight) / Param.chessHeight;
        int rowY = Y * Param.chessHeight + Param.marginHeight;

        Graphics g = getGraphics();
        Graphics2D g2d = (Graphics2D) g;
        g2d.setStroke(stroke);
        g2d.setColor(Color.blue);
        if ((x >= Param.marginWidth + Param.chessWidth && x <= Param.marginWidth
                + Param.cols * Param.chessWidth + Param.chessWidth)
                && (y >= Param.marginHeight + Param.chessHeight && y <= Param.marginHeight
                        + Param.rows * Param.chessHeight + Param.chessHeight)) {

            // 第一次点击了firstPoint==null||重复点击了第一个点
            if (firstPoint == null || (firstPoint.x == Y && firstPoint.y == X)) {
                firstPoint = new Point(Y, X);
                g2d.setColor(Color.blue);
                g2d.drawRect(rowX + 2, rowY + 2, Param.chessWidth - 4,
                        Param.chessHeight - 4);
                return;
            }
            // 第二点
            secondPoint = new Point(Y, X);
            g2d.setColor(Color.red);
            g2d.drawRect(rowX + 2, rowY + 2, Param.chessWidth - 4,
                    Param.chessHeight - 4);
            // 判断两个点的图标是否一致
            if (arr[firstPoint.x][firstPoint.y].getStatus() != arr[secondPoint.x][secondPoint.y]
                    .getStatus()) {
                firstPoint = secondPoint;

                repaint();
                return;
            }

            // 图标的状态值相同 连通算法
            List<Point> list = Core.checkLinked(arr, firstPoint, secondPoint);
            if (list == null) {
                firstPoint = secondPoint;

                repaint();
                return;
            }

            // 可以连通:设置图标的状态值为0,把两点放null,绘制连接线,重新绘制界面
            arr[firstPoint.x][firstPoint.y].setStatus(0);
            arr[secondPoint.x][secondPoint.y].setStatus(0);
            firstPoint = null;
            secondPoint = null;

            // 绘制连接线

            drawLinkedLine(list, g2d);

            repaint();
        }

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    private void drawLinkedLine(List<Point> list, Graphics2D g2d) {
        // TODO Auto-generated method stub
        if (list.size() == 2) {
            Point a = list.get(0);
            Point b = list.get(1);
            int ax = a.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int ay = a.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            int bx = b.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int by = b.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            g2d.drawLine(ax, ay, bx, by);

        }

        if (list.size() == 3) {
            Point a = list.get(0);
            Point c = list.get(1);
            Point b = list.get(2);

            int ax = a.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int ay = a.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;

            int cx = c.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int cy = c.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            int bx = b.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int by = b.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            g2d.drawLine(ax, ay, cx, cy);
            g2d.drawLine(cx, cy, bx, by);
        }

        if (list.size() == 4) {
            Point a = list.get(0);
            Point c = list.get(1);
            Point d = list.get(2);
            Point b = list.get(3);
            int ax = a.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int ay = a.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;

            int cx = c.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int cy = c.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            int dx = d.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int dy = d.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            int bx = b.y * Param.chessWidth + Param.marginWidth
                    + Param.chessWidth / 2;
            int by = b.x * Param.chessHeight + Param.marginHeight
                    + Param.chessHeight / 2;
            g2d.drawLine(ax, ay, cx, cy);
            g2d.drawLine(cx, cy, dx, dy);
            g2d.drawLine(dx, dy, bx, by);
        }

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

4、Core.java

package tools;

import java.util.List;
import java.awt.Point;
import java.util.ArrayList;

import Linkup.Chess;
/**
 * 连连看核心算法类  实现连通
 * @author laixl
 *
 */
public class Core {
    //定义 静态集合
    private static List<Point> list = new ArrayList<Point>();

    /**
     * 连通的总判断方法
     * @param arr
     * @param a
     * @param b
     * @return 连通点的集合;null表示无法连通
     */
    public static List<Point> checkLinked(Chess[][] arr, Point a, Point b) {
        list.clear();
        if (noCorner(arr, a, b) != null) {
            return list;
        }
        if (oneCorner(arr, a, b) != null) {
            return list;
        }

        if (twoCorner(arr, a, b) != null) {
            return list;
        }
        return null;
    }

    /**
     * 直线连通算法
     * @param arr
     * @param a
     * @param b
     * @return 连通点的集合,null代表不能连通
     */
    public static List<Point> noCorner(Chess[][] arr, Point a, Point b) {
        if (canArrived(arr, a, b)) {
            list.add(a);
            list.add(b);
            return list;
        }
        return null;
    }

    /**
     * 一拐角连通算法
     * 
     * @param arr
     * @param a
     * @param b
     * @return 连通点的集合,null代表不能连通
     */
    public static List<Point> oneCorner(Chess[][] arr, Point a, Point b) {
        Point c = new Point(a.x, b.y);

        if (arr[c.x][c.y].getStatus() == 0 && canArrived(arr, a, c)
                && canArrived(arr, c, b)) {
            list.add(a);
            list.add(c);
            list.add(b);
            return list;
        }

        Point d = new Point(b.x, a.y);
        if (arr[d.x][d.y].getStatus() == 0 && canArrived(arr, a, d)
                && canArrived(arr, d, b)) {
            list.add(a);
            list.add(d);
            list.add(b);
            return list;
        }
        return null;
    }

    /**
     * 二拐角连通算法
     * 
     * @param arr
     * @param a
     * @param b
     * @return 连通点的集合,null代表不能连通
     */
    public static List<Point> twoCorner(Chess[][] arr, Point a, Point b) {
        for (int i = 0; i < arr[0].length; i++) {
            Point c = new Point(a.x, i);

            if (arr[c.x][c.y].getStatus() == 0 && canArrived(arr, a, c)
                    && oneCorner(arr, c, b) != null) {
                list.add(0, a);
                return list;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            Point c = new Point(i, a.y);
            if (arr[c.x][c.y].getStatus() == 0 && canArrived(arr, a, c)
                    && oneCorner(arr, c, b) != null) {

                list.add(0, a);
                return list;
            }
        }
        return null;
    }

    /**
     * 判断直线是否可以连通
     * 
     * @param arr
     * @param a
     * @param b
     * @return true表示可以连通,false表示不可以连通
     */
    public static boolean canArrived(Chess[][] arr, Point a, Point b) {
        // 横向 a.x == b.x
        if (a.x == b.x) {
            
            
            for (int i = Math.min(a.y, b.y) + 1; i < Math.max(a.y, b.y); i++) {
                if (arr[a.x][i].getStatus() != 0) {
                    return false;
                }
            }
            // 可以连通
            return true;
        }

        // 纵向: a.y == b.y
        if (a.y == b.y) {
            for (int i = Math.min(a.x, b.x) + 1; i < Math.max(a.x, b.x); i++) {
                if (arr[i][a.y].getStatus() != 0) {
                    return false;
                }
            }
            // 可以连通
            return true;
        }

        return false;
    }

    public static void main(String[] args) {
    }

}

5、LinkUpMainFrame.java

package Linkup;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class LinkUpMainFrame extends JFrame {
    MapPanel mapPanel = new MapPanel();

    public LinkUpMainFrame() {
        this.add(mapPanel);
        this.setTitle("连连看");// 设置 标题

        this.setSize(1000, 650);// 设置宽高

        this.setLocationRelativeTo(null);// 自动适配到屏幕中间

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置关闭模式
        this.setResizable(false);

        this.setVisible(true);// 设置可见

        ImageIcon imageIcon = new ImageIcon("Images/Photos/serverstop.gif");
        Image image = imageIcon.getImage();
        this.setIconImage(image);// 设置连连看窗体图标
    }

    public static void main(String[] args) {

        new LinkUpMainFrame();

    }
}

运行效果:

java—连连看-实现消除

接下来就要开始做进度条,时间限制,如何实现洗牌啦!期待~~