目录

1、界面初始化

2、获取点击事件,处理消除逻辑

(1)完成最基本的消除功能

(2)直连消除

(3)增加单拐点可消除

(4)增加双拐点可消除

3、功能更全的连连看小游戏


本文开发的连连看小游戏,记录了从0到1的开发过程,简单易懂,代码可直接运行。

当前版本的效果展示:

完成一个小动物连连看的小游戏,主要的设计框架主要包括:

1、首先完成界面的初始化工作;

2、获取点击事件,判断两次点击是否满足消除条件;

3、方块消除完毕弹窗游戏结束,开启下一局;

没错,就是这么简单,不过在每个过程中有一些细节需要考虑,下面是开发的详细介绍,不想看的可以直接到文末复制代码去玩,别忘了点个赞哦!

实现过程中需要的图片可以去这个网站获取(免费的)

代码目录:

1、界面初始化

界面初始化并不是简单的将方块扔上去而已,还需要考虑图片是否成对出现,否则不能保证方块全部被消除。

在初始化时,先随机给出一半图片,然后在复制一份,这样就能保证图片成对出现了。代码如下所示:

package com.game.linkGame.demo2;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;public class demo2 {public static void main(String[] args) throws IOException {JFrame gameFrame = new JFrame("小动物连连看");//设置背景颜色gameFrame.setBackground(Color.WHITE);//设置游戏框体大小gameFrame.setSize(800,800);gameFrame.add(new GamePanel());gameFrame.setVisible(true);}
}class GamePanel extends JPanel{//初始化一个有图案的界面//allImages里面存放八张小动物图片Image[] allImages = new Image[8];//10*10的界面,用map记录每个位置上放置的图片的编号int[][] map = new int[10][10];Random r = new Random();public GamePanel() throws IOException {for (int i = 0; i < 8; i++) {//将图片保存到一个容器中,方便使用Image image1 = ImageIO.read(new File("a"+i+".png"));allImages[i] = image1;}//在初始化界面选定方块样式时,先随机给出一半,然后在复制这一半,这样就能保证生成的方块是成对出现的了List<Integer> list = new ArrayList<>();for(int i = 0;i < 50;i++){int num = r.nextInt(8);list.add(num);list.add(num);}Collections.shuffle(list);//shuffle可以用来打乱list数据Integer[] array = list.toArray(new Integer[0]);int[] count = new int[8];for(int i = 0;i < 10;i++){for (int j = 0; j < 10; j++) {map[i][j] = array[i * 10 + j];count[map[i][j]]++;//这里记录一下每个图片出现的次数,验证是否能全部消除System.out.print(map[i][j]+" ");}System.out.println();}System.out.println(Arrays.toString(count));}@Overridepublic void paint(Graphics g) {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {g.drawImage(allImages[map[i][j]],60+64*i,60+64*j,64,64,null);}}}
}

代码中记录了每个图片出现的次数,如下图所示,可以看出每个图片都出现了偶数次

效果展示:

2、获取点击事件,处理消除逻辑

这一步就稍微有些麻烦了,大概分为以下几步:

(1)完成最基本的消除功能

  • 获取点击坐标,计算出被点击的方块位置
  • 被点击方块四周显示红框,表示被选中
  • 第二次点击与第一次点击不满足消除,则将第二次点击作为第一次点击
  • 如果两次点击图片编号一致则开始消除;

这是最基本的消除功能,只要两个图片一致就消除,代码主要在GamePanel类中增加了addMouseListener方法,完整代码如下:

package com.game.linkGame.demo2;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;public class demo2 {public static void main(String[] args) throws IOException {JFrame gameFrame = new JFrame("小动物连连看");//设置背景颜色gameFrame.setBackground(Color.WHITE);//设置游戏框体大小gameFrame.setSize(800,800);gameFrame.add(new GamePanel());gameFrame.setVisible(true);}
}class GamePanel extends JPanel{//初始化一个有图案的界面//allImages里面存放八张小动物图片Image[] allImages = new Image[8];//10*10的界面,用map记录每个位置上放置的图片的编号int[][] map = new int[10][10];Random r = new Random();public GamePanel() throws IOException {for (int i = 0; i < 8; i++) {//将图片保存到一个容器中,方便使用Image image1 = ImageIO.read(new File("a"+i+".png"));allImages[i] = image1;}//在初始化界面选定方块样式时,先随机给出一半,然后在复制这一半,这样就能保证生成的方块是成对出现的了List<Integer> list = new ArrayList<>();for(int i = 0;i < 50;i++){int num = r.nextInt(8);list.add(num);list.add(num);}Collections.shuffle(list);//shuffle可以用来打乱list数据Integer[] array = list.toArray(new Integer[0]);for(int i = 0;i < 10;i++){for (int j = 0; j < 10; j++) {map[i][j] = array[i * 10 + j];}}//捕获点击addMouseListener(new MouseAdapter() {boolean isClick = false;int clickId = -1;int clickX = 0;int clickY = 0;@Overridepublic void mouseClicked(MouseEvent e) {System.out.println(clickId);Graphics g = getGraphics();g.setColor(Color.RED);int x = e.getX() - 60;int y = e.getY() - 60;int i = x/64;int j = y/64;if(x<0||y<0||i>9||j>9||map[i][j]==-1)return ;//如果是第二次点击if(isClick){if(i==clickX&&j==clickY){return ;}if(map[i][j]==clickId){//开始消除g.setColor(Color.RED);g.drawRect(i*64+60,j*64+60,64,64);try {Thread.sleep(100);} catch (InterruptedException ex) {throw new RuntimeException(ex);}g.setColor(Color.WHITE);g.drawRect(clickX*64+60,clickY*64+60,64,64);g.clearRect(clickX*64+60,clickY*64+60,64,64);g.drawRect(i*64+60,j*64+60,64,64);g.clearRect(i*64+60,j*64+60,64,64);map[i][j] = -1;map[clickX][clickY] = -1;isClick = false;}else{//两次点击不满足消除,则将第二次点击作为第一次点击clickId = map[i][j];g.setColor(Color.WHITE);g.drawRect(clickX*64+60,clickY*64+60,64,64);g.setColor(Color.RED);g.drawRect(i*64+60,j*64+60,64,64);clickX = i;clickY = j;}}else{//第一次点击clickId = map[i][j];isClick = true;clickX = i;clickY = j;g.drawRect(i*64+60,j*64+60,64,64);}}});}@Overridepublic void paint(Graphics g) {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {g.drawImage(allImages[map[i][j]],60+64*i,60+64*j,64,64,null);}}}
}

(2)直连消除

直连消除:在同一水平线且两相同方块间无障碍物;

为节省大家阅读时间,下面贴出完整代码,可以运行看看效果,代码主要改动:增加了是否直连的判断逻辑、增加直连的画线逻辑

package com.game.linkGame.demo2;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;public class demo2 {public static void main(String[] args) throws IOException {JFrame gameFrame = new JFrame("小动物连连看");//设置背景颜色gameFrame.setBackground(Color.WHITE);//设置游戏框体大小gameFrame.setSize(800,800);gameFrame.add(new GamePanel());gameFrame.setVisible(true);}
}class GamePanel extends JPanel{//初始化一个有图案的界面//allImages里面存放八张小动物图片Image[] allImages = new Image[8];//10*10的界面,用map记录每个位置上放置的图片的编号int[][] map = new int[10][10];Random r = new Random();public GamePanel() throws IOException {for (int i = 0; i < 8; i++) {//将图片保存到一个容器中,方便使用Image image1 = ImageIO.read(new File("a"+i+".png"));allImages[i] = image1;}//在初始化界面选定方块样式时,先随机给出一半,然后在复制这一半,这样就能保证生成的方块是成对出现的了List<Integer> list = new ArrayList<>();for(int i = 0;i < 50;i++){int num = r.nextInt(8);list.add(num);list.add(num);}Collections.shuffle(list);//shuffle可以用来打乱list数据Integer[] array = list.toArray(new Integer[0]);for(int i = 0;i < 10;i++){for (int j = 0; j < 10; j++) {map[i][j] = array[i * 10 + j];}}//捕获点击addMouseListener(new MouseAdapter() {boolean isClick = false;int clickId = -1;int clickX = 0;int clickY = 0;int pointNum = -1;@Overridepublic void mouseClicked(MouseEvent e) {System.out.println(clickId);Graphics g = getGraphics();g.setColor(Color.RED);int x = e.getX() - 60;int y = e.getY() - 60;int i = x/64;int j = y/64;if(x<0||y<0||i>9||j>9||map[i][j]==-1)return ;//如果是第二次点击if(isClick){if(i==clickX&&j==clickY){return ;}if(map[i][j]==clickId && directLink(clickX,clickY,i,j)){//开始消除g.setColor(Color.RED);g.drawRect(i*64+60,j*64+60,64,64);drawLink(clickX,clickY,i,j);g.setColor(Color.WHITE);g.drawRect(clickX*64+60,clickY*64+60,64,64);g.clearRect(clickX*64+60,clickY*64+60,64,64);g.drawRect(i*64+60,j*64+60,64,64);g.clearRect(i*64+60,j*64+60,64,64);map[i][j] = -1;map[clickX][clickY] = -1;isClick = false;}else{//两次点击不满足消除,则将第二次点击作为第一次点击clickId = map[i][j];g.setColor(Color.WHITE);g.drawRect(clickX*64+60,clickY*64+60,64,64);g.setColor(Color.RED);g.drawRect(i*64+60,j*64+60,64,64);clickX = i;clickY = j;}}else{//第一次点击clickId = map[i][j];isClick = true;clickX = i;clickY = j;g.drawRect(i*64+60,j*64+60,64,64);}}//判断是否可以直连private boolean directLink(int clickX1, int clickY1, int clickX2, int clickY2) {//判断两个方块是否在同一行if(clickX1 == clickX2){int start = Math.min(clickY1,clickY2);int end = Math.max(clickY1,clickY2);for(int i = start + 1;i < end;i++){if(map[clickX1][i] != -1){//如果两个方块中间还有未消除的方块,说明不能水平相连return false;}}pointNum = 0;return true;}//判断两个方块是否在同一列if(clickY1 == clickY2){int start = Math.min(clickX1,clickX2);int end = Math.max(clickX1,clickX2);for(int i = start + 1;i < end;i++){if(map[i][clickY1] != -1){//如果两个方块中间还有未消除的方块,说明不能垂直相连return false;}}pointNum = 0;return true;}return false;}//画线,此处的x1,y1,x2,y2二维数组下标private void drawLink(int x1, int y1, int x2, int y2) {Graphics g = getGraphics();Point p1 = new Point(x1*64+60+32,y1*64+60+32);Point p2 = new Point(x2*64+60+32,y2*64+60+32);g.setColor(Color.RED);if(pointNum == 0){g.drawLine(p1.x, p1.y,p2.x, p2.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x, p1.y,p2.x, p2.y);System.out.println("无拐点画线");}}private void wait_time(){try {Thread.sleep(500);//延时500ms} catch (InterruptedException e) {e.printStackTrace();}}});}@Overridepublic void paint(Graphics g) {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {g.drawImage(allImages[map[i][j]],60+64*i,60+64*j,64,64,null);}}}}

(3)增加单拐点可消除

由于之前判断过两方块是否直连,因此满足单拐点连接时两方块必然不在同一行或同一列,只需考虑下图红线所示两种情况

为节省大家阅读时间,下面贴出完整代码,可以运行看看效果,代码主要改动:增加了能否单拐点连接的判断逻辑、增加单拐点连接的画线逻辑

package com.game.linkGame.demo2;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;public class demo2 {public static void main(String[] args) throws IOException {JFrame gameFrame = new JFrame("小动物连连看");//设置背景颜色gameFrame.setBackground(Color.WHITE);//设置游戏框体大小gameFrame.setSize(800, 800);gameFrame.add(new GamePanel());gameFrame.setVisible(true);}
}class GamePanel extends JPanel {//初始化一个有图案的界面//allImages里面存放八张小动物图片Image[] allImages = new Image[8];//10*10的界面,用map记录每个位置上放置的图片的编号int[][] map = new int[10][10];Random r = new Random();public GamePanel() throws IOException {for (int i = 0; i < 8; i++) {//将图片保存到一个容器中,方便使用Image image1 = ImageIO.read(new File("a" + i + ".png"));allImages[i] = image1;}//在初始化界面选定方块样式时,先随机给出一半,然后在复制这一半,这样就能保证生成的方块是成对出现的了List<Integer> list = new ArrayList<>();for (int i = 0; i < 50; i++) {int num = r.nextInt(8);list.add(num);list.add(num);}Collections.shuffle(list);//shuffle可以用来打乱list数据Integer[] array = list.toArray(new Integer[0]);for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {map[i][j] = array[i * 10 + j];}}//捕获点击addMouseListener(new MouseAdapter() {boolean isClick = false;int clickId = -1;int clickX = 0;int clickY = 0;int pointNum = -1;Point temp1;@Overridepublic void mouseClicked(MouseEvent e) {Graphics g = getGraphics();g.setColor(Color.RED);int x = e.getX() - 60;int y = e.getY() - 60;int i = x / 64;int j = y / 64;if (x < 0 || y < 0 || i > 9 || j > 9 || map[i][j] == -1)return;//如果是第二次点击if (isClick) {if (i == clickX && j == clickY) {return;}if (map[i][j] == clickId && (directLink(clickX, clickY, i, j) || oneCornerLink(clickX, clickY, i, j))) {//开始消除g.setColor(Color.RED);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);drawLink(clickX, clickY, i, j);g.setColor(Color.WHITE);//去红框g.drawRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);//去方块图片g.clearRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.clearRect(i * 64 + 60, j * 64 + 60, 64, 64);map[i][j] = -1;map[clickX][clickY] = -1;isClick = false;} else {//两次点击不满足消除,则将第二次点击作为第一次点击clickId = map[i][j];g.setColor(Color.WHITE);g.drawRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.setColor(Color.RED);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);clickX = i;clickY = j;}} else {//第一次点击clickId = map[i][j];isClick = true;clickX = i;clickY = j;g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);}}//判断是否可以直连private boolean directLink(int clickX1, int clickY1, int clickX2, int clickY2) {//判断两个方块是否在同一行if (clickX1 == clickX2) {int start = Math.min(clickY1, clickY2);int end = Math.max(clickY1, clickY2);for (int i = start + 1; i < end; i++) {if (map[clickX1][i] != -1) {//如果两个方块中间还有未消除的方块,说明不能水平相连return false;}}pointNum = 0;return true;}//判断两个方块是否在同一列if (clickY1 == clickY2) {int start = Math.min(clickX1, clickX2);int end = Math.max(clickX1, clickX2);for (int i = start + 1; i < end; i++) {if (map[i][clickY1] != -1) {//如果两个方块中间还有未消除的方块,说明不能垂直相连return false;}}pointNum = 0;return true;}return false;}//判断是否单拐点可连接private boolean oneCornerLink(int clickX1, int clickY1, int clickX2, int clickY2) {if (clickY1 > clickY2) {//保证(x1,y1)是矩形的左上角或者左下角int temp1 = clickX1;int temp2 = clickY1;clickX1 = clickX2;clickY1 = clickY2;clickX2 = temp1;clickY2 = temp2;}if (clickX1 < clickX2) {//如果(x1,y1)位于矩形左上角//判断右上角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接,//(clickX1, clickY2)是右上角拐点下标if (map[clickX1][clickY2] == -1 && directLink(clickX1, clickY1, clickX1, clickY2) && directLink(clickX2, clickY2, clickX1, clickY2)) {pointNum = 1;temp1 = new Point(clickX1, clickY2);return true;}//判断左下角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX2, clickY1)是左下角拐点下标if (map[clickX2][clickY1] == -1 && directLink(clickX2, clickY2, clickX2, clickY1) && directLink(clickX1, clickY1, clickX2, clickY1)) {pointNum = 1;temp1 = new Point(clickX2, clickY1);return true;}} else {//如果(x1,y1)位于矩形左下角//判断左上角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX2, clickY1)是左上角拐点下标if (map[clickX2][clickY1] == -1 && directLink(clickX2, clickY2, clickX2, clickY1) && directLink(clickX1, clickY1, clickX2, clickY1)) {pointNum = 1;temp1 = new Point(clickX2, clickY1);return true;}//判断右下角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX1, clickY2)是右下角拐点下标if (map[clickX1][clickY2] == -1 && directLink(clickX1, clickY1, clickX1, clickY2) && directLink(clickX2, clickY2, clickX1, clickY2)) {pointNum = 1;temp1 = new Point(clickX1, clickY2);return true;}}return false;}//画线private void drawLink(int x1, int y1, int x2, int y2) {Graphics g = getGraphics();Point p1 = new Point(x1 * 64 + 60 + 32, y1 * 64 + 60 + 32);Point p2 = new Point(x2 * 64 + 60 + 32, y2 * 64 + 60 + 32);g.setColor(Color.RED);if (pointNum == 0) {g.drawLine(p1.x, p1.y, p2.x, p2.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x, p1.y, p2.x, p2.y);System.out.println("无拐点画线");} else if (pointNum == 1) {temp1.x = temp1.x * 64 + 60 + 32;temp1.y = temp1.y * 64 + 60 + 32;g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(p2.x,p2.y,temp1.x,temp1.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(p2.x,p2.y,temp1.x,temp1.y);System.out.println("单拐点画线");}}private void wait_time() {try {Thread.sleep(500);//延时500ms} catch (InterruptedException e) {e.printStackTrace();}}});}@Overridepublic void paint(Graphics g) {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {g.drawImage(allImages[map[i][j]], 60 + 64 * i, 60 + 64 * j, 64, 64, null);}}}}

(4)增加双拐点可消除

双拐点可消除分以下四种情况:

  • 点A左侧存在点C可与点B单拐点连接
  • 点A右侧存在点C可与点B单拐点连接
  • 点A上侧存在点C可与点B单拐点连接
  • 点A下侧存在点C可与点B单拐点连接

其中拐点超出地图边界的的情况要特殊考虑:

例如:向左搜索的情况下,由点A(x1,y1)可以确定拐点C(-1,y1)的位置,从而根据点B(x2,y2)确定拐点D(-1,y2)的位置,可参考下图:

完整代码:

package com.game.linkGame;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;public class demo1 {public static void main(String[] args) throws IOException {JFrame gameFrame = new JFrame("小动物连连看");//设置背景颜色gameFrame.setBackground(Color.WHITE);//设置游戏框体大小gameFrame.setSize(800, 800);gameFrame.add(new GamePanel());gameFrame.setVisible(true);}
}class GamePanel extends JPanel {//初始化一个有图案的界面//allImages里面存放八张小动物图片Image[] allImages = new Image[8];//10*10的界面,用map记录每个位置上放置的图片的编号int N = 10;int[][] map = new int[N][N];Random r = new Random();public GamePanel() throws IOException {for (int i = 0; i < 8; i++) {//将图片保存到一个容器中,方便使用Image image1 = ImageIO.read(new File("a" + i + ".png"));allImages[i] = image1;}//在初始化界面选定方块样式时,先随机给出一半,然后在复制这一半,这样就能保证生成的方块是成对出现的了List<Integer> list = new ArrayList<>();for (int i = 0; i < N*N/2; i++) {int num = r.nextInt(8);list.add(num);list.add(num);}Collections.shuffle(list);//shuffle可以用来打乱list数据Integer[] array = list.toArray(new Integer[0]);for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {map[i][j] = array[i * N + j];}}//捕获点击addMouseListener(new MouseAdapter() {boolean isClick = false;int clickId = -1;int clickX = 0;int clickY = 0;int pointNum = -1;Point temp1;Point temp2;@Overridepublic void mouseClicked(MouseEvent e) {Graphics g = getGraphics();g.setColor(Color.RED);int x = e.getX() - 60;int y = e.getY() - 60;int i = x / 64;int j = y / 64;if (x < 0 || y < 0 || i > N-1 || j > N-1 || map[i][j] == -1)return;//如果是第二次点击if (isClick) {if (i == clickX && j == clickY) {return;}if (map[i][j] == clickId && (directLink(clickX, clickY, i, j) || oneCornerLink(clickX, clickY, i, j) || twoCornerLink(clickX, clickY, i, j))) {//开始消除g.setColor(Color.RED);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);drawLink(clickX, clickY, i, j);g.setColor(Color.WHITE);//去红框g.drawRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);//去方块图片g.clearRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.clearRect(i * 64 + 60, j * 64 + 60, 64, 64);map[i][j] = -1;map[clickX][clickY] = -1;isClick = false;} else {//两次点击不满足消除,则将第二次点击作为第一次点击clickId = map[i][j];g.setColor(Color.WHITE);g.drawRect(clickX * 64 + 60, clickY * 64 + 60, 64, 64);g.setColor(Color.RED);g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);clickX = i;clickY = j;}} else {//第一次点击clickId = map[i][j];isClick = true;clickX = i;clickY = j;g.drawRect(i * 64 + 60, j * 64 + 60, 64, 64);}}//判断是否可以直连private boolean directLink(int clickX1, int clickY1, int clickX2, int clickY2) {//判断两个方块是否在同一行if (clickX1 == clickX2) {int start = Math.min(clickY1, clickY2);int end = Math.max(clickY1, clickY2);for (int i = start + 1; i < end; i++) {if (map[clickX1][i] != -1) {//如果两个方块中间还有未消除的方块,说明不能水平相连return false;}}pointNum = 0;return true;}//判断两个方块是否在同一列if (clickY1 == clickY2) {int start = Math.min(clickX1, clickX2);int end = Math.max(clickX1, clickX2);for (int i = start + 1; i < end; i++) {if (map[i][clickY1] != -1) {//如果两个方块中间还有未消除的方块,说明不能垂直相连return false;}}pointNum = 0;return true;}return false;}//判断是否单拐点可连接private boolean oneCornerLink(int clickX1, int clickY1, int clickX2, int clickY2) {if (clickY1 > clickY2) {//保证(x1,y1)是矩形的左上角或者左下角int temp1 = clickX1;int temp2 = clickY1;clickX1 = clickX2;clickY1 = clickY2;clickX2 = temp1;clickY2 = temp2;}if (clickX1 < clickX2) {//如果(x1,y1)位于矩形左上角//判断右上角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接,//(clickX1, clickY2)是右上角拐点下标if (map[clickX1][clickY2] == -1 && directLink(clickX1, clickY1, clickX1, clickY2) && directLink(clickX2, clickY2, clickX1, clickY2)) {pointNum = 1;temp1 = new Point(clickX1, clickY2);return true;}//判断左下角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX2, clickY1)是左下角拐点下标if (map[clickX2][clickY1] == -1 && directLink(clickX2, clickY2, clickX2, clickY1) && directLink(clickX1, clickY1, clickX2, clickY1)) {pointNum = 1;temp1 = new Point(clickX2, clickY1);return true;}} else {//如果(x1,y1)位于矩形左下角//判断左上角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX2, clickY1)是左上角拐点下标if (map[clickX2][clickY1] == -1 && directLink(clickX2, clickY2, clickX2, clickY1) && directLink(clickX1, clickY1, clickX2, clickY1)) {pointNum = 1;temp1 = new Point(clickX2, clickY1);return true;}//判断右下角是否为空并且可以直接与(x1,y1)和(x2,y2)相连接//(clickX1, clickY2)是右下角拐点下标if (map[clickX1][clickY2] == -1 && directLink(clickX1, clickY1, clickX1, clickY2) && directLink(clickX2, clickY2, clickX1, clickY2)) {pointNum = 1;temp1 = new Point(clickX1, clickY2);return true;}}return false;}//判断是否双拐点可连接//判断是否可以通过两个拐点相连private boolean twoCornerLink(int clickX1, int clickY1, int clickX2, int clickY2) {//向左查找for(int i = clickX1 - 1;i>=-1;i--){//判断是否到了地图外面if(i==-1){//看第二个点能否和地图外面直连if(directLink(-1,clickY2,clickX2,clickY2)){pointNum = 2;temp1 = new Point(-1,clickY1);temp2 = new Point(-1,clickY2);return true;}}else{if(map[i][clickY1] != -1)break;//判断是否存在一个点能与第二个点单拐点连接if(oneCornerLink(i,clickY1,clickX2,clickY2)){pointNum = 2;temp1 = new Point(i,clickY1);temp2 = new Point(i,clickY2);return true;}}}//向右查找for(int i = clickX1 + 1;i <= N;i++){//判断是否到了地图外面if(i==N){//看第二个点能否和地图外面直连if(directLink(N,clickY2,clickX2,clickY2)){pointNum = 2;temp1 = new Point(N,clickY1);temp2 = new Point(N,clickY2);return true;}}else{if(map[i][clickY1] != -1)break;//判断是否存在一个点能与第二个点单拐点连接if(oneCornerLink(i,clickY1,clickX2,clickY2)){pointNum = 2;temp1 = new Point(i,clickY1);temp2 = new Point(i,clickY2);return true;}}}//向下查找for(int i = clickY1 + 1;i <= N;i++){//判断是否到了地图外面if(i==N){//看第二个点能否和地图外面直连if(directLink(clickX2,N,clickX2,clickY2)){pointNum = 2;temp1 = new Point(clickX1,N);temp2 = new Point(clickX2,N);return true;}}else{if(map[clickX1][i] != -1)break;//判断是否存在一个点能与第二个点单拐点连接if(oneCornerLink(clickX1,i,clickX2,clickY2)){pointNum = 2;temp1 = new Point(clickX1,i);temp2 = new Point(clickX2,i);return true;}}}//向上查找for(int i = clickY1 - 1;i >= -1;i--){//判断是否到了地图外面if(i==-1){//看第二个点能否和地图外面直连if(directLink(clickX2,-1,clickX2,clickY2)){pointNum = 2;temp1 = new Point(clickX1,-1);temp2 = new Point(clickX2,-1);return true;}}else{if(map[clickX1][i] != -1)break;//判断是否存在一个点能与第二个点单拐点连接if(oneCornerLink(clickX1,i,clickX2,clickY2)){pointNum = 2;temp1 = new Point(clickX1,i);temp2 = new Point(clickX2,i);return true;}}}return false;}//画线private void drawLink(int x1, int y1, int x2, int y2) {Graphics g = getGraphics();Point p1 = new Point(x1 * 64 + 60 + 32, y1 * 64 + 60 + 32);Point p2 = new Point(x2 * 64 + 60 + 32, y2 * 64 + 60 + 32);g.setColor(Color.RED);if (pointNum == 0) {g.drawLine(p1.x, p1.y, p2.x, p2.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x, p1.y, p2.x, p2.y);System.out.println("无拐点画线");} else if (pointNum == 1) {temp1.x = temp1.x * 64 + 60 + 32;temp1.y = temp1.y * 64 + 60 + 32;g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(p2.x,p2.y,temp1.x,temp1.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(p2.x,p2.y,temp1.x,temp1.y);System.out.println("单拐点画线");} else if (pointNum == 2) {temp1.x = temp1.x * 64 + 60 + 32;temp1.y = temp1.y * 64 + 60 + 32;temp2.x = temp2.x * 64 + 60 + 32;temp2.y = temp2.y * 64 + 60 + 32;g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(temp1.x,temp1.y,temp2.x,temp2.y);g.drawLine(temp2.x,temp2.y,p2.x,p2.y);wait_time();g.setColor(Color.WHITE);g.drawLine(p1.x,p1.y,temp1.x,temp1.y);g.drawLine(temp1.x,temp1.y,temp2.x,temp2.y);g.drawLine(temp2.x,temp2.y,p2.x,p2.y);System.out.println("双拐点画线");}}private void wait_time() {try {Thread.sleep(500);//延时500ms} catch (InterruptedException e) {e.printStackTrace();}}});}@Overridepublic void paint(Graphics g) {for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {g.drawImage(allImages[map[i][j]], 60 + 64 * i, 60 + 64 * j, 64, 64, null);}}}}

效果展示:

3、功能更全的连连看小游戏

由于经验有限,于是参考java连连看_qq_38850132的博客-CSDN博客这篇博客,制作了功能更完善的小游戏,文笔不是特别好,就不介绍了。。源码可以到文末链接获取,以下是代码目录:

最终版效果展示:

背景切换、洗牌、提示功能展示:

源码下载地址:https://download.csdn.net/download/weixin_52641852/87629912(免费

【Java小游戏】小动物连连看由易到难相关推荐

  1. java小游戏英文文献,连连看Java小游戏毕业设计论文

    连连看Java小游戏毕业设计论文 连连看连连看 JavaJava 小游戏毕业论文小游戏毕业论文 设计设计 学生姓名学生姓名 学学 号号 系系 别别 专专 业业 指导教师指导教师 软件 071 班 目目 ...

  2. 性能测试实践|PerfDog助力微信小游戏/小程序性能调优

    概述 随着近年来微信生态圈的发展,小游戏,小程序也随之爆火,同样伴随着的便是对于小游戏/小程序的用户体验的严格要求:微信团队也在自家的微信平台推荐使用PerfDog测试小游戏/小程序的性能. 1.评测 ...

  3. cocos creator 接QQ小游戏小程序RewardedVideoAd 激励视频广告sdk

    cocos creator 接QQ小游戏小程序RewardedVideoAd 激励视频广告sdk 开发者工具 0.1.26 版本开始支持调试广告组件 话说你们看完为什么不留言点赞? 首先,你需要初始化 ...

  4. python小游戏小恐龙1

    python小游戏小恐龙1 #coding=utf-8 #coding=gbk import pygame from itertools import cycle from pygame.locals ...

  5. iOS如何测试微信小游戏小程序?

    "微信小游戏性能评测标准建立的初衷是希望能引导开发者优化相关性能数据,提升用户体验.评测标准根据小游戏整体的性能数据表现.玩家体验评价,结合操作系统.机型分档.网络条件等多种维度建立.&qu ...

  6. android调用微信程序,Android如何测试微信小游戏小程序?

    "微信小游戏性能评测标准建立的初衷是希望能引导开发者优化相关性能数据,提升用户体验.评测标准根据小游戏整体的性能数据表现.玩家体验评价,结合操作系统.机型分档.网络条件等多种维度建立.&qu ...

  7. android 微信检测工具,Android 如何测试微信小游戏小程序?

    "微信小游戏性能评测标准建立的初衷是希望能引导开发者优化相关性能数据,提升用户体验.评测标准根据小游戏整体的性能数据表现.玩家体验评价,结合操作系统.机型分档.网络条件等多种维度建立.&qu ...

  8. android 小游戏源码_Python入门太难?不如从玩塔防小游戏开始,玩通关就能学会编程...

    我一直认为,在python入门阶段学习基础理论,太枯燥.所以我们整理了很多有关python的项目案例,有详细教程还有源码,希望能帮助更多对python感兴趣的人. 这是其中一个适合入门的Python项 ...

  9. 2022最新酒桌小游戏小程序源码(附带流量主)

    正文: 2022最新酒桌小游戏喝酒小程序源码_带流量主 喝酒神器3.6,增加了广告位,根据文档直接替换即可,原版本没有广告位 直接上传源码到开发者端即可 通过后改广告代码,然后关闭广告展示提交,通过后 ...

最新文章

  1. centos下为firefox安装flash插件的几种方法
  2. P3390矩阵快速幂
  3. android的窗口机制分析------ViewRoot类
  4. Python中异常(Exception)的总结
  5. Class的getInterfaces与getGenericInterface区别
  6. ios uiview 如何刷新_2020最新迅雷苹果版如何下载?
  7. 数据3分钟丨​PingCAP DevCon 2021回顾;openGauss社区颁发首张OGCA认证证书
  8. sdcv: 在Ubuntu中使用命令行查询离线英文词典
  9. VXLAN配置实例(二)——VXLAN跨子网互通
  10. imgaug图像扩充实践
  11. 【深入理解计算机系统csapp】 attack lab实验四
  12. Linux查看当前时间
  13. [日常] 修改编辑word中的页眉页脚
  14. 室内定位技术研发简介
  15. linux安装mysql步骤用yum_linux 使用yum安装mysql详细步骤
  16. NeurIPS'22杰出论文奖:3项研究出自华人团队,AlexNet获时间检验奖
  17. 未转变者DLC皮肤在服务器,未转变者 steam上 最新的版本 肿么联机?肿么创建房间...
  18. 前端日历,vue日历,一周的日历
  19. TO BE A BETTER MAN(纪念时光)
  20. Sql Server数据库备份大全(Sql语句)

热门文章

  1. 微型计算机原理中LEA,微机原理lea指令什么意思_微机原理实训箱
  2. json java 转义_java解析json,带转义字符的json
  3. 开发中常见json转义
  4. 基于全卷积神经网络的图像分割方法详解(二)
  5. EF中的DBFirst实例(上)
  6. 输入网银密码时会重复
  7. linux下trap命令和SIGHUP信号量详解
  8. django 库存管理系统 计算机毕业源码19144
  9. 前端性能优化方法与实战14 高级进阶:瞒天过海的骨架屏及 SSR 优化手段
  10. censys 数据库地理信息自定义接口(python版)