This article shares the specific code for Android realizing Lianlian game for your reference. The specific content is as follows
I implemented it with android studio
Source code
Main Event Category:
package packageName; import .; import ; import ; import ; import ; import ; import MaView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); params = new (.WRAP_CONTENT, .WRAP_CONTENT); final MaView mainView = new MaView(this); addContentView(mainView, params); // Add three buttons to execute the corresponding method Button btn = new Button(this); ("New Game"); (20); (40); (40); (new () { @Override public void onClick(View v) { (); } }); addContentView(btn, params); Button tipBtn = new Button(this); ("hint"); (20); (380); (40); (new () { @Override public void onClick(View v) { (); } }); addContentView(tipBtn, params); Button resetBtn = new Button(this); ("Reset"); (20); (720); (40); (new () { @Override public void onClick(View v) { (); } }); addContentView(resetBtn, params); } }
MaView class
package packageName; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class MaView extends View { //Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-Long-L // The connection is only horizontal and vertical. // 1, its horizontal or vertical direction is the same, and there is no other linear relationship between the two grids. // 2, there is a one-point relationship between a one-point relationship // 3, There are two fold-point relationships with two fold-points // Left margin public static final int MARGINLEFT = 40; // Top margin public static final int MARGINTOP = 400; // Number of rows of grids public static final int ROW = 10; // The width and height of the grid public static final int W = 100; // The width and height of the picture public static final int IMGW = 90; // The grid is empty public static final int NULL = -1; // Connection status is straight public static final int STRAIGHT = 1; // The connection status is 10% off public static final int ONELINK = 2; // Connection status is 20% off public static final int TWOLINK = 3; // Number of types of grids public static final int L = 25; // Map for storing grid information private int[] map = new int[ROW * ROW]; // Pictures of plaids private Bitmap[] imgs = new Bitmap[L]; // Determine whether the touch screen event is a click private boolean isMove; // Whether to select the grid for the first time private boolean isFirstSelect; // Can you draw selected borders for connecting lines and grids private boolean canDrawLine, canDrawRect; // Is there any prompt? If not, you need to reset the current grid position private boolean canTip; // Is it possible to select a grid private boolean canPlay; // Is the prompt clicked? private boolean firstTip; // Store the positions of the first and second selected blocks private int x1 = NULL, y1 = NULL, x2 = NULL, y2 = NULL; // The position of the first vertex and the second vertex private int px1, py1, px2, py2; // Category of connection lines private int linkState; // Counter, used to solve asynchronous problems private int count = 0; public MaView(Context context) { super(context); // Initialize the picture initImg(); // Initialize the game newGame(); // Set touch screen events setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // The current status cannot be clicked. If you draw a connection line, there will be a waiting time of 0.5 seconds. if (!canPlay) { return false; } switch (()) { case MotionEvent.ACTION_DOWN: isMove = false; break; case MotionEvent.ACTION_MOVE: isMove = true; case MotionEvent.ACTION_UP: // If it is a mobile event, it will not be executed if (!isMove) { // Get the position of the current click in the grid int x = (int) () - MARGINLEFT; int y = (int) () - MARGINTOP; // Whether it exceeds the boundary if (x < 0 || x > W * ROW || y < 0 || y > W * ROW) { return false; } // Convert to lattice coordinates // x is the column, y is the row x = x / W % ROW; y = y / W; // Is it the first choice if (isFirstSelect) { // Is the clicked position a space sub if (map[y * ROW + x] == NULL) { return false; } // Store the location of the first grid x1 = x; y1 = y; // You can draw borders canDrawRect = true; isFirstSelect = false; // The method that comes with View will execute the onDraw() method asynchronously, which will play the role of updating the view invalidate(); } else { if (map[y * ROW + x] == NULL) { return false; } // If the clicked grid is the same, reset the selection if (x1 == x && y1 == y) { noDraw(); // Update the view invalidate(); return false; } // Store the location of the second grid x2 = x; y2 = y; // Determine whether the two grids are the same if (map[y1 * ROW + x1] == map[y2 * ROW + x2]) { // Is it possible to connect if (isCanLink(x1, y1, x2, y2)) { canDrawLine = true; // Update the view invalidate(); // Counter to prevent view effects from being synchronized count++; waitLose(); } else { noDraw(); invalidate(); } } else { noDraw(); invalidate(); } } } } return true; } }); } // Determine whether you win private boolean isWin() { for (int i = 0; i < ROW * ROW; i++) { if (map[i] != NULL) { return false; } } return true; } // Determine whether the eliminated grid can be private void waitLose() { if (count == 2) { map[y2 * ROW + x2] = NULL; map[y1 * ROW + x1] = NULL; count = 0; } } // Start a new game public void newGame() { randomMap(); noDraw(); firstTip = true; canPlay = true; invalidate(); } private boolean isCanLink(int x1, int y1, int x2, int y2) { // Three judgments should be made by straight line, one-point connection, and two-point connection // Vertical straight lines are connected, and the column coordinates are the same if (x1 == x2 && isVLink(x1, y1, y2)) { linkState = STRAIGHT; return true; } // Horizontal straight lines are connected, and the row coordinates are the same if (y1 == y2 && isHLink(y1, x1, x2)) { linkState = STRAIGHT; return true; } // Determine the connection of a vertex if (isOneLink(x1, y1, x2, y2)) { linkState = ONELINK; return true; } // Determine the connection between two vertices if (isTwoLink(x1, y1, x2, y2)) { linkState = TWOLINK; return true; } return false; } // Vertical straight line judgment private boolean isVLink(int x1, int y1, int y2) { // Guaranteed that y1 is never greater than y2 if (y1 > y2) { int t = y1; y1 = y2; y2 = t; } // traverse the grids from x, y1 to y2 for (int i = y1 + 1; i < y2; i++) { // If there is one that is not empty, it cannot be connected if (map[i * ROW + x1] != NULL) { return false; } } return true; } // Horizontal linear judgment private boolean isHLink(int y1, int x1, int x2) { // Ensure that x1 is never greater than x2 if (x1 > x2) { int t = x1; x1 = x2; x2 = t; } // traverse x1 to x2, y grid for (int i = x1 + 1; i < x2; i++) { // If there is one that is not empty, it cannot be connected if (map[y1 * ROW + i] != NULL) { return false; } } return true; } // Two verdicts private boolean isTwoLink(int x1, int y1, int x2, int y2) { // Ensure that the first coordinate is on the left, making it easier to traverse if (x1 > x2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } // There are four directions to judge // top // First move the first vertex up, and then use the rectangle connection method to judge the first vertex and the second coordinates for (int i = y1 - 1; i >= -1; i--) { // If the boundary is reached, determine whether the second coordinate can reach the boundary in this direction. If so, it can be connected. if (i == -1) { // Whether the second coordinate can reach the upper boundary if (isCanTop(x2, y2)) { //Storing the first and second vertices px1 = x2; py1 = i; px2 = x1; py2 = i; return true; } break; } if (map[x1 + i * ROW] != NULL) { break; } if (isOneLink(x1, i, x2, y2)) { // Store the second vertex, the first vertex is stored in the one-peripheral connection px2 = x1; py2 = i; return true; } } // down for (int i = y1 + 1; i <= ROW; i++) { if (i == ROW) { if (isCanDown(x2, y2)) { px1 = x2; py1 = i; px2 = x1; py2 = i; return true; } break; } if (map[x1 + i * ROW] != NULL) { break; } if (isOneLink(x1, i, x2, y2)) { px2 = x1; py2 = i; return true; } } // left for (int i = x1 - 1; i >= -1; i--) { if (i == -1) { if (isCanLeft(x2, y2)) { px2 = i; py2 = y1; px1 = i; py1 = y2; return true; } break; } if (map[i + y1 * ROW] != NULL) { break; } if (isOneLink(i, y1, x2, y2)) { px2 = i; py2 = y1; return true; } } // right for (int i = x1 + 1; i <= ROW; i++) { if (i == ROW) { if (isCanRight(x2, y2)) { px2 = i; py2 = y1; px1 = i; py1 = y2; return true; } break; } if (map[i + y1 * ROW] != NULL) { break; } if (isOneLink(i, y1, x2, y2)) { px2 = i; py2 = y1; return true; } } return false; } private boolean isCanTop(int x2, int y2) { // traverse the grid between the coordinates and the upper boundary. If it is not empty, it cannot for (int i = y2 - 1; i >= -1; i--) { if (i == -1) { break; } if (map[i * ROW + x2] != NULL) { return false; } } return true; } private boolean isCanLeft(int x2, int y2) { for (int i = x2 - 1; i >= -1; i--) { if (i == -1) { break; } if (map[y2 * ROW + i] != NULL) { return false; } } return true; } private boolean isCanRight(int x2, int y2) { for (int i = x2 + 1; i <= ROW; i++) { if (i == ROW) { break; } if (map[y2 * ROW + i] != NULL) { return false; } } return true; } private boolean isCanDown(int x2, int y2) { for (int i = y2 + 1; i <= ROW; i++) { if (i == ROW) { break; } if (map[i * ROW + x2] != NULL) { return false; } } return true; } // A verdict private boolean isOneLink(int x1, int y1, int x2, int y2) { // Ensure that the first coordinate is on the left, making it easier to traverse if (x1 > x2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } // Use a rectangle to judge a vertex, two coordinates are at the diagonal, and the vertex is at the other diagonal // First determine whether this vertex is empty. If it is not empty, it cannot be connected. // If it is empty, connect two coordinate points to this vertex by a straight line. If possible, you can connect them. if (map[y1 * ROW + x2] == NULL) { if (isHLink(y1, x1, x2) && isVLink(x2, y1, y2)) { //Storing the position of the first vertex for easy drawing of lines px1 = x2; py1 = y1; return true; } } // Another break if (map[x1 + y2 * ROW] == NULL) { // Note the transformation position of x, y if (isHLink(y2, x1, x2) && isVLink(x1, y1, y2)) { //Storing the position of the first vertex for easy drawing of lines px1 = x1; py1 = y2; return true; } } return false; } private void initImg() { int id; for (int i = 0; i < ; i++) { id = getResources().getIdentifier("a" + (i + 1), "drawable", getContext().getPackageName()); // Show original size of the picture// options = new (); // = false; imgs[i] = (getResources(), id); int w = imgs[i].getWidth(); int h = imgs[i].getHeight(); Matrix matrix = new Matrix(); (IMGW * 1.0f / w, IMGW * 1.0f / h); imgs[i] = (imgs[i], 0, 0, w, h, matrix, true); } } private Bitmap getMyImg(Bitmap rootImg, int goalW, int goalH) { int rootW = (); int rootH = (); // graphics packaged Matrix matrix = new Matrix(); (goalW * 1.0f / rootW, goalH * 1.0f / rootH); return (rootImg, 0, 0, rootW, rootH, matrix, true); } private void randomMap() { // Initialize the map and disrupt the location int c = 0; // There are four lattices in each type for (int i = 0; i < L; i++) { for (int j = 0; j < 4; j++) { map[c] = i; c++; } } // 500 cycles to disrupt the position int a, b, t; Random random = new Random(); for (int i = 0; i < 500; i++) { a = (ROW * ROW); b = (ROW * ROW); if (map[a] == NULL || map[b] == NULL) { continue; } t = map[a]; map[a] = map[b]; map[b] = t; } } // private void showMap() { // String s = ""; // int c = 0; // for (int i = 0; i < ROW; i++) { // for (int j = 0; j < ROW; j++) { // s += map[c] + " "; // c++; // } // s = ""; // } // } @Override protected void onDraw(Canvas canvas) { int x, y; int c = 0; // Draw a grid for (int i = 0; i < ROW; i++) { for (int j = 0; j < ROW; j++) { x = MARGINLEFT + j * W; y = MARGINTOP + i * W; if (map[c] != NULL) { (imgs[map[c]], x, y, new Paint()); } c++; } } // Draw the lattice border for prompts if (canTip) { // Set the style of the lines Paint paint = new Paint(); (8); (("#08ffc8")); (); x = x1 * W + MARGINLEFT; y = y1 * W + MARGINTOP; (x, y, x + W - 3, y + W - 3, paint); x = x2 * W + MARGINLEFT; y = y2 * W + MARGINTOP; (x, y, x + W - 3, y + W - 3, paint); canTip = false; noDraw(); } // Draw the border of the selected grid if (canDrawRect) { Paint paint = new Paint(); (8); (); (); // The first grid if (x1 != NULL) { x = x1 * W + MARGINLEFT; y = y1 * W + MARGINTOP; (x, y, x + W - 3, y + W - 3, paint); firstTip = true; } // The second grid if (x2 != NULL) { x = x2 * W + MARGINLEFT; y = y2 * W + MARGINTOP; (x, y, x + W - 3, y + W - 3, paint); count++; waitLose(); } } // Draw the connection line if (canDrawLine) { Paint paint = new Paint(); (8); (); (); int sx1, sy1, sx2, sy2, zx1, zy1, zx2, zy2; // The first coordinate sx1 = x1 * W + W + MARGINLEFT - W / 2; sy1 = y1 * W + W + MARGINTOP - W / 2; // The second coordinate sx2 = x2 * W + W + MARGINLEFT - W / 2; sy2 = y2 * W + W + MARGINTOP - W / 2; switch (linkState) { case STRAIGHT: // Draw a straight line (sx1, sy1, sx2, sy2, paint); break; case ONELINK: // Draw a line of point zx1 = px1 * W + MARGINLEFT + W / 2; zy1 = py1 * W + MARGINTOP + W / 2; (sx1, sy1, zx1, zy1, paint); (zx1, zy1, sx2, sy2, paint); break; case TWOLINK: // Draw two-fold point lines // The second fold zx1 = px1 * W + MARGINLEFT + W / 2; zy1 = py1 * W + MARGINTOP + W / 2; // The first fold zx2 = px2 * W + MARGINLEFT + W / 2; zy2 = py2 * W + MARGINTOP + W / 2; // Change the position of the line when you reach the boundary if (px1 == -1) { zx1 += 30; zx2 += 30; } else if (px1 == ROW) { zx1 -= 30; zx2 -= 30; } // There are two situations: left and right, upper and lower, but the first vertex must be the same as x or y of the first coordinate if (px1 == x1 || py1 == y1) { int t = zx1; zx1 = zx2; zx2 = t; t = zy1; zy1 = zy2; zy2 = t; } (sx1, sy1, zx2, zy2, paint); (zx2, zy2, zx1, zy1, paint); (zx1, zy1, sx2, sy2, paint); } noDraw(); // The line drawing process cannot be clicked canPlay = false; // Open a thread to make connection effect new Timer().schedule(new TimerTask() { @Override public void run() { // This method is used to go to the main thread to execute. The update view operation must be put into the main thread to execute. Its invalidate() and new view post(new Runnable() { @Override public void run() { invalidate(); // Do you know if you win? if (isWin()) { (getContext(), "You Win! Please New Game", Toast.LENGTH_SHORT).show(); } // You can click canPlay = true; } }); } }, 500); } } // Reset the current image location public void reset() { if (!canPlay) { return; } int a, b, t; Random random = new Random(); for (int i = 0; i < 500; i++) { a = (ROW * ROW); b = (ROW * ROW); if (map[a] == NULL || map[b] == NULL) { continue; } t = map[a]; map[a] = map[b]; map[b] = t; } invalidate(); } // Get prompt public void getTip() { if (!canPlay) { return; } // Cannot click continuously if (!firstTip) { (getContext(), "Alright Tip!", Toast.LENGTH_SHORT).show(); return; } firstTip = false; int count = 0; int x1, y1, x2, y2; Tag: for (int i = 0; i < ROW * ROW; i++) { if (map[i] == NULL) { continue; } for (int j = i + 1; j < ROW * ROW; j++) { if (map[j] == NULL) { continue; } if (map[i] == map[j]) { x1 = i % ROW; y1 = i / ROW; x2 = j % ROW; y2 = j / ROW; if (isCanLink(x1, y1, x2, y2)) { count++; this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; break Tag; } } } } // If it is not empty, there is a grid that can be connected if (count != 0) { canTip = true; invalidate(); } else { (getContext(), "No One! Please Click New Game", Toast.LENGTH_SHORT).show(); } } // Reset the selection grid private void noDraw() { canDrawRect = false; canDrawLine = false; isFirstSelect = true; x1 = NULL; x2 = NULL; y1 = NULL; y2 = NULL; } }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.