Let's see the effect picture first
The first game start interface
The second is the game interface

The third is the end of the game interface

<> On the difficulties of implementation :

1. Because you have to click two pictures to delete each time , So randomly generated images are to appear in pairs on the interface
The implementation code is as follows
public void suiji() { int x1; int x2; int y1; int y2; for (int i = 0; i < shuzu
.length; i++) { for (int j = 0; j < shuzu[i].length; j++) { shuzu[i][j] = 0; } }
Random rand= new Random(); for (int i = 0; i < shuzu.length * shuzu[0].length /
2; i++) { int type = rand.nextInt(10) + 1;// The value is 1,2,...10 array 1-10 Corresponding picture 0-9 do { x1
= (int) ((12 * Math.random()));// x1 The scope is 0,1,2,...12 y1 = (int) ((10 * Math.random
()));// y1 The scope is 0,10 } while (shuzu[x1][y1] != 0); shuzu[x1][y1] = type; do { x2 =
(int) ((12 * Math.random())); y2 = (int) ((10 * Math.random())); } while (shuzu[
x2][y2] != 0); shuzu[x2][y2] = type; } }

2. After random generation of two-dimensional array , Each number in a two-dimensional array represents a picture . Then you can insert the image , Every time you open the interface, it will be a new one . The code that generates the image should be written into the redraw , Otherwise, the image will refresh without reason . Random array code cannot be written into redraw , Because you can't pull the interface , It will refresh the interface .
the reason being that 12x10 Picture placement for , So I first drew one 13x11 Chessboard assistant of lines , After the function is realized , Redraws the chessboard code comment , Beginners can borrow the auxiliary line of chessboard .
The redraw code is as follows :
public void paint(Graphics g) { super.paint(g); ImageIcon image = new ImageIcon
(getClass().getResource("A dream .png")); int width = getWidth();// Get picture component width int height
= getHeight(); g.drawImage(image.getImage(), 0, 0, width , height, this); Font
font= new Font(" Blackbody ", Font.BOLD, 135);// Create font g.setFont(font);// Use fonts g.setColor(
Color.WHITE);// Use white /* * // Redraw chessboard for (int i = 0; i < Cow; i++) {
g.drawLine(leftX + SIZE * i, leftY, * leftX + SIZE * i, leftY + SIZE * (Lum -
1));// Vertical line g.drawLine(leftX, leftY + * SIZE * i, leftX + SIZE * (Cow - 1), leftY
+ SIZE * i);// Horizontal line } */ // int[][] shuzu = new int[12][10];// Two dimensional arrays are used to represent 12*10 Map
Image[] imagArr = new Image[10]; for (int i = 0; i < imagArr.length; i++) {
imagArr[i] = new ImageIcon("C:\\Users\\TANGNAN\\Desktop\\ Keep looking \\ameng\\" + i +
".png").getImage(); } System.out.println(shuzu[1][1] + "png"); for (int i = 0; i
< shuzu.length; i++) { for (int j = 0; j < shuzu[i].length; j++) { if (0 < shuzu
[i][j]) { g.drawImage(imagArr[shuzu[i][j] - 1], leftX + i * 80, leftY + j * 80,
80, 80, this); } } } }

3. After the implementation of the whole Lianliankan interface , It's the rule of continuous reading . If you look inside, you can only set up lines with two corners at most to eliminate the square . So now I'm going to write four methods , Realize the horizontal connection of Lianliankan respectively , Vertical connection , Single inflection point connection , Double turning point connection , And there is also an edge connection between the two identical blocks of the most edge . The single inflection point connection and double inflection point connection are difficult , Comparison foundation of horizontal and vertical edge connection .
The code is as follows :

<> Horizontal connection
Horizontal connection code , Sorry for using Pinyin public boolean shuipingLink(int clickX1, int clickY1, int
clickX2, int clickY2) { // Horizontal connection if(clickX1>clickX2){// ensure x2>x1 int temp1 = clickX1
; int temp2 = clickY1; clickX1 = clickX2; clickY1 = clickY2; clickX2 = temp1;
clickY2= temp2; } if(clickY1==clickY2){// If the number of columns of the two selected pictures is the same , It can be connected horizontally for(int i=
clickX1+1;i<clickX2;i++){ if(shuzu[i][clickY1]!=0){// If there are other pictures between the two pictures , It means that it cannot be connected horizontally
return false; } } linkMethod=shuipingLink; return true; } return false; }
<> Vertical connection
public boolean chuizhiLink(int clickX1,int clickY1,int clickX2,int clickY2) {
// Vertical connection if(clickY1>clickY2) {// ensure Y2>Y1 int temp1 = clickX1; int temp2 = clickY1;
clickX1=clickX2; clickY1=clickY2; clickX2=temp1; clickY2=temp2; } if(clickX1==
clickX2) {// The two pictures have the same number of columns , It can be connected vertically for(int i=clickY1+1;i<clickY2;i++) { if(shuzu[
clickX1][i]!=0) { return false; } } linkMethod=chuizhiLink; return true; }
return false; }
<> Implementation of edge connection
public boolean edgeLink(int clickX1,int clickY1,int clickX2,int clickY2) { if(
clickY1==0&&clickY2==0&&shuzu[clickX1][clickY1]==shuzu[clickX2][clickY2]) {
// Find at top edge return true; }else if(clickX1==0&&clickX2==0&&shuzu[clickX1][clickY1]
==shuzu[clickX2][clickY2]) {// Left edge search return true; } else if(clickY1==9&&clickY2
==9&&shuzu[clickX1][clickY1]==shuzu[clickX2][clickY2]) {// Bottom edge search return true; }
else if(clickX1==11&&clickX2==11&&shuzu[clickX1][clickY1]==shuzu[clickX2][
clickY2]) {// Find it on the right return true; } return false; }
<> Realization of single inflection point connection
public boolean oneLink(int clickX1,int clickY1,int clickX2,int clickY2) {
// A connection with an inflection point if(clickY1>clickY2) {// ensure Y2>Y1 int temp1 = clickX1; int temp2 =
clickY1; clickX1=clickX2; clickY1=clickY2; clickX2=temp1; clickY2=temp2; } if(
clickX1<clickX2){ // Determine whether the lower left corner is empty and can be directly linked with the (x1,y1) and (x2,y2) Phase connection ,(clickX1,
clickY2) It's the subscript of the inflection point in the upper right corner if(shuzu[clickX1][clickY2]==0&&shuipingLink(clickX2, clickY2,
clickX1, clickY2)&&chuizhiLink(clickX1,clickY1,clickX1,clickY2)){ linkMethod=
oneLink; z1=new Node(clickX1,clickY2); return true; } if(shuzu[clickX2][clickY1]
==0&&shuipingLink(clickX2, clickY1, clickX1, clickY1)&&chuizhiLink(clickX2,
clickY2,clickX2, clickY1)){ linkMethod=oneLink; z1=new Node(clickX2,clickY1);
return true; } }else{ if(shuzu[clickX2][clickY1]==0&&shuipingLink(clickX1,
clickY1, clickX2, clickY1)&&chuizhiLink(clickX2,clickY2,clickX2, clickY1)){
linkMethod=oneLink; z1=new Node(clickX2,clickY1); return true; } if(shuzu[
clickX1][clickY2]==0&&shuipingLink(clickX1, clickY2, clickX2, clickY2)&&
chuizhiLink(clickX1,clickY2,clickX1, clickY1)){ linkMethod=oneLink; z1=new Node(
clickX1,clickY2); return true; } } return false; }
<> Realization of double turning point connection
public boolean twoLink(int clickX1,int clickY1,int clickX2,int clickY2) {
// Look up for(int i=clickY1-1;i>=0;i--) { // Two inflection points are on the upper side of the selected pattern if(i>=0&&shuzu[clickX1][i]
==0) { if(oneLink(clickX1,i,clickX2,clickY2)) { z1=new Node(clickX1,i); z2=new
Node(clickX2,i); linkMethod=twoLink; return true; } } else { break; } } // Look down
for(int i=clickY1+1;i<=10;i++) { // Two inflection points are below the selected pattern if(i!=10&&shuzu[clickX1][i]==0)
{ if(oneLink(clickX1,i,clickX2,clickY2)) { z1=new Node(clickX1,i); z2=new Node(
clickX2,i); linkMethod=twoLink; return true; } } else { break; } } // Find left for(
int i=clickX1-1;i>=0;i--) { // Two inflection points are on the left side of the selected picture if(i!=-1&&shuzu[i][clickY1]==0) { if(
oneLink(i,clickY1,clickX2,clickY2)) { z1=new Node(i,clickY1); z2=new Node(i,
clickY2); linkMethod=twoLink; return true; } } else { break; } } // Find right for(int
i=clickX1+1;i<=12;i++) { // The two inflection points are on the right if(i!=12&&shuzu[i][clickY1]==0) { if(oneLink(
i,clickY1,clickX1,clickY2)) { z1=new Node(i,clickY1); z2=new Node(i,clickY2);
linkMethod=twoLink; return true; } } else { break; } } return false; }
<> Draw lines to connect the selected blocks

Look inside every time , After each box is selected , You should draw a check box in the box , And between the second selected box , Draw a line to connect . Line drawing is also divided into horizontal line drawing , Draw lines vertically , Draw a line with a single stick , Draw a line with two crutches . It's as easy to draw a line on the edge as it is to draw a line horizontally , There is no redundancy in the code .
private void drawLink(int x1, int y1, int x2, int y2) { //Graphics g =
this.getGraphics(); Point p1 = new Point(x1*80+leftX+40,y1*80+leftY+40); Point
p2= new Point(x2*80+leftX+40,y2*80+leftY+40); if(linkMethod == shuipingLink ||
linkMethod== chuizhiLink){ g.drawLine(p1.x, p1.y,p2.x, p2.y); try { Thread.sleep
(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.
printStackTrace(); } System.out.println(" Draw line without inflection point "); //System.out.println("g="+g);
}else if(linkMethod ==oneLink){ Point point_z1 = new Point(z1.x*80+leftX+40,z1.y
*80+leftY+40);// Convert inflection point to pixel coordinate g.drawLine(p1.x, p1.y,point_z1.x, point_z1.y); g.
drawLine(p2.x, p2.y,point_z1.x, point_z1.y); try { Thread.sleep(300); } catch (
InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace()
; } System.out.println(" Draw a line at a single inflection point "); //System.out.println("g="+g); }else{ Point
point_z1= new Point(z1.x*80+leftX+40,z1.y*80+leftY+40); Point point_z2 = new
Point(z2.x*80+leftX+40,z2.y*80+leftY+40); try { Thread.sleep(300); } catch (
InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace()
; } if(p1.x!=point_z1.x&&p1.y!=point_z1.y){// ensure (x1,y1) And inflection point z1 In the same column or row Point temp;
temp= point_z1; point_z1 = point_z2; point_z2 = temp; } g.drawLine(p1.x, p1.y,
point_z1.x, point_z1.y); g.drawLine(p2.x, p2.y, point_z2.x, point_z2.y); g.
drawLine(point_z1.x,point_z1.y, point_z2.x, point_z2.y); try { Thread.sleep(300)
; } catch (InterruptedException e) { // TODO Auto-generated catch block e.
printStackTrace(); } System.out.println(" Draw a line with two turning points "); } shuzu[x1][y1] = 0; shuzu[x2]
[y2] = 0; }
<> Prompt box function

Then there is the prompt box function , If you have realized the connection and line drawing I mentioned earlier , So the prompt function is very simple , Just call the previous method . Bloggers in the game set each game can only prompt once . Click restart to refresh the number of times . Clicking refresh does not refresh the number of prompts . Traverse the entire array , Find the connection blocks that haven't been found yet .
public void find2Block() { for(int i=0;i<12;i++){ for(int j=0;j<10;j++){ if(
shuzu[i][j]==0){ continue; } for(int p=i;p<12;p++){ for(int q=0;q<10;q++){ if(
shuzu[p][q]!=shuzu[i][j]||(p==i&&q==j)){// If the patterns are not equal continue; } if((chuizhiLink(p,
q,i,j)||shuipingLink(p,q,i,j)||oneLink(p,q,i,j)||twoLink(p,q,i,j))&&tishi==1){ g
.setColor(Color.green); g.drawRect(i*80+leftX, j*80+leftY,80,80); g.drawRect(p*
80+leftX, q*80+leftY,80,80); drawLink(p, q, i, j); return; // repaint(); } } } }
} }
<> Mobile block function

Because there is only a single function of continuous reading , The play is monotonous , Bloggers give the realization of all the blocks to achieve a mobile grid ( The premise is that the place to be moved is a blank space ) How to do it , And all the blocks move to the most edge ( Unlimited lattice number ). After the implementation of these two kinds of mobile methods , You can change Lianliankan to xiaoxiaole and other games with higher playing methods, or you can increase the difficulty of Lianliankan ( For example, every time you eliminate a square , The rest of the blocks move to the left and so on ), In this way, the playing method will be greatly increased . Because I'm in the mobile method , Twice for Loop through the array to find the block to move , If you want to achieve automatic movement , Remove traversal and add it to the listener . Shift left and shift left for the following example . The rest of them are written almost like this , Bloggers will not post ,
Particular attention , For example, if you want to move right , Follow my code , You need to start at the end of the array , That is to say, the cycle starts on the right side , Otherwise, the expected effect will not be achieved .
public void leftMove(int[][] shuzu){ for (int i = 0; i < shuzu.length; i++) {
for (int j = 0; j < shuzu[i].length; j++) { if(shuzu[i][j]!=0){ // Look to the left for(int
n=i-1;n>=0;n--) { if(shuzu[n][j]==0) { int temp; temp=shuzu[n][j]; shuzu[n][j]=
shuzu[i][j]; shuzu[i][j]=temp; } } } } } } // All left public void AllLeft(int[][]
shuzu) { int jishu=0; for(int i =0;i<shuzu.length;i++) { for(int j=0;j<shuzu[i].
length;j++) { if(shuzu[i][j]!=0){ // Look to the left for(int n=i-1;n>=0;n--) { if(shuzu[n][
j]==0) { jishu++; } } int temp; temp = shuzu[i][j]; shuzu[i][j]=shuzu[i-jishu][j
]; shuzu[i-jishu][j]=temp; jishu=0; } } } }
<> refresh function

Refresh function is the process of shuffling the remaining blocks .
The code is as follows :
public void refresh(int[][] shuzu){ for (int i = 0; i < shuzu.length; i++) {
for (int j = 0; j < shuzu[i].length; j++) { if(shuzu[i][j]!=0){ // Look to the left for(int
n=i-1;n>=0;n--) { do { int temp; temp=shuzu[n][j]; shuzu[n][j]=shuzu[i][j];
shuzu[i][j]=temp; }while(shuzu[i][j]==0); } } } } }
<> music

If you need music , You need to set the music to WAV format , It's for bloggers qq music ( new edition ) realization mp3 turn WAV. You can do it yourself , Many music softwares have their own format conversion function . Turn it into a good one WAV Format file directly copy and paste to Lianliankan project file can be called .
But sometimes the music stops automatically while playing , I can't find the reason . But when I just went in , Music is played , And if you don't do it , The music will sing all the time , We haven't found the reason yet .
The code is as follows
import java.applet.AudioClip; import java.net.MalformedURLException; import
java.net.URL; import javax.swing.JApplet; public class Playmusic { public static
AudioCliploadSound(String filename) { URL url = null; try { url = new URL(
"file:" + filename); } catch (MalformedURLException e) {;} return JApplet.
newAudioClip(url); } public void play() { AudioClip christmas = loadSound(
"llk.wav"); christmas.loop(); } }

okay , Here we are , The basic and enhanced functions of Lianliankan have been basically realized . I didn't post the code of the monitor . The blogger himself is the bottom one JFrame, And then the border layout , The middle one JPanel Look at the interface , The one on the right JPanel Using flow layout to place buttons . The interface is a little ugly , Daga can be creative .

©2019-2020 Toolsou All rights reserved,
tkinter Implementation of user login interface Vue Invalid render dynamic component in subcomponent ( First invalid , Valid for the second time )9 ride 9 Sudoku C/C++ Memory model TypeScript actual combat -12-TS The mechanism of type checking - Type inference Java Thread safety and insecurity JLink,STLink,DAPLink,CMSIS DAP Differences in use Chapter 10 use SpringMVC Frame transformation of supermarket order management system -1C Language calculation of deposit interest About the Blue Bridge Cup , Things you should know !