Android 2048 game logic analysis, android2048

Source: Internet
Author: User
Tags gety

Android 2048 game logic analysis, android2048

 

I continue to learn the practical path course of geek College and talked about the compilation process of 2048 games. I will give a summary here to share with you (the results will be accompanied by the source code and the code I modified ):

This article mainly includes two aspects: drawing the 1.2048 interface and implementing the 2.2048 algorithm logic 3. Adding a random number 4. Determining the end of the game

First view (simulated image on a real machine ):

 

1. Drawing the interface

The interface is relatively simple to draw. First create a new card class, which is mainly described in the 16 small blocks

/** This class is mainly used to initialize the square in game 2048 */public class Card extends FrameLayout {private TextView lable; public Card (Context context) {super (context ); lable = new TextView (getContext (); lable. setTextSize (32); lable. setGravity (Gravity. CENTER); lable. setBackgroundColor (0X30FFFFFF); // 30 indicates transparency. The transparency range is 00-ff. The last six digits are color values. // The Layout_wight and Layout_height are set as match_parent (-1 indicates match_parent, respectively, -2 stands for wrap_content) LayoutParams lp = new LayoutParams (-1,-1); lp. setMargins (10, 10, 10, 10); // set the card spacing addView (lable, lp); setNum (0);} int num = 0; public int getNum () {return num;} public void setNum (int num) {this. num = num; // when cardMap [] [] <= 0, it is set to "if (num <= 0) {lable. setText ("");} else {lable. setText (num + "") ;}} public boolean equals (Card o) {return getNum () = o. getNum ();}}

 

Create a main class of GameView to inherit GirdLayout and rewrite the method. Before that, you need to change the main_activity layout file, including a textView for scoring and the layout implemented outside.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.game1024.MainActivity" >    <LinearLayout         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">                <TextView             android:layout_width="wrap_content"            android:layout_height="match_parent"            android:layout_gravity="center_vertical"            android:textSize="20sp"            android:text="score:"/>        <TextView             android:id="@+id/cvScore"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textSize="20sp"             />    </LinearLayout>        <com.example.game1024.GameView        android:background="#00ff00"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1">        </com.example.game1024.GameView></LinearLayout>

 

Public class GameView extends GridLayout {public GameView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); initGame ();} public GameView (Context context Context, attributeSet attrs) {super (context, attrs); initGame ();} public GameView (Context context) {super (context); initGame ();} public void initGame () {setColumnCount (4); // set the specified number of rows to four rows: setBackgroundColor (0XffF4A460); setOnTouchListener (new View. onTouchListener () {private float startX, startY, offsetX, offsetY; @ Override public boolean onTouch (View v, MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: // obtain the initial Coordinate System for clicking. out. println ("00000"); startX = event. getX (); startY = event. getY (); break; case MotionEvent. ACTION_UP: // get the offset of System in each direction. out. println ("0--0"); offsetX = event. getX ()-startX; offsetY = event. getY ()-startY;/** compares the offset between the X axis and the Y axis to determine whether it is a sliding up or down or a sliding left or right * and then determines whether the offset is positive or negative, to determine the specific direction of Moving * Below I write the moving order as follows: Left, right, top, bottom */if (Math. abs (offsetX)> Math. abs (offsetY) {// if (offsetX <-5) {swipeLeft ();} else if (offsetX> 5) is regarded as moving when the moving distance is greater than 5 DP) {swipeRight () ;}} else if (Math. abs (offsetX) <Math. abs (offsetY) {if (offsetY <-5) {swipeUp ();} else if (offsetY> 5) {swipeDown () ;}} break; default: break ;} return true ;}}) ;}/ ** (non-Javadoc) * @ see android. view. view # onSizeChanged (int, int) * When the width and height of the screen change, the width and height of the card change accordingly */@ Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); int cardWidth = (Math. min (w, h)-10)/4; addCard (cardWidth, cardWidth); startGame ();} // create an array to store the num private Card cardMap [] [] = new Card [4] [4] of each Card; /** Method for adding a card */private void addCard (int cardwidth, int cardheight) {Card c; for (int y = 0; y <4; y ++) {for (int x = 0; x <4; x ++) {c = new Card (getContext (); c. setNum (0); addView (c, cardwidth, cardheight); cardMap [x] [y] = c ;}}}

2. Game logic Algorithms

This comment is clear. Let's take a look at it. if (judge) is used later to determine when the game is over.

/** Mobile algorithm */private void swipeLeft () {boolean judge = false; for (int y = 0; y <4; y ++) {for (int x = 0; x <4; x ++) {for (int x1 = x + 1; x1 <4; x1 ++) {// first judge whether there is a vertex with num greater than zero on the right of the current vertex. If yes, proceed to the next step. Otherwise, continue to the loop.
// Determines whether the current vertex is null (less than or equal to zero is equivalent to null, which has been set to not display in the card class). If it is null, assign the right vertex to the current vertex, at the same time, it is set to zero. If it is not null, determine whether the current vertex is equal to or not.
// The vertices on the right are equal. Equal, The num of the current vertex is multiplied by 2, and the vertices on the right are set to zero.
If (cardMap [x1] [y]. getNum ()> 0) {if (cardMap [x] [y]. getNum () <= 0) {cardMap [x] [y]. setNum (cardMap [x1] [y]. getNum (); cardMap [x1] [y]. setNum (0);/** if there is a number at the 1st position, it will move to the 0th position and continue the loop. If there are also a number at the 2nd position, * Because a number already exists in the 0th positions, the number of the 2nd positions will not be moved to the first blank position, but will remain unchanged * therefore, you need to subtract x by 1, compare it again */x --; judge = true;} else if (cardMap [x] [y]. getNum () = cardMap [x1] [y]. getNum () {cardMap [x] [y]. setNum (cardMap [x] [y]. getNum () * 2); cardMap [x1] [y]. setNum (0); MainActivity. getMainActivity (). addScore (cardMap [x] [y]. getNum (); judge = true;} break ;}}}if (judge) {checkGame (); addRandom () ;}} private void swipeRight () {boolean judge = false; for (int y = 0; y <4; y ++) {for (int x = 3; x> = 0; x --) {for (int x1 = X-1; x1> = 0; x1 --) {if (cardMap [x1] [y]. getNum ()> 0) {if (cardMap [x] [y]. getNum () <= 0) {cardMap [x] [y]. setNum (cardMap [x1] [y]. getNum (); cardMap [x1] [y]. setNum (0); x ++; judge = true;} else if (cardMap [x] [y]. getNum () = cardMap [x1] [y]. getNum () {cardMap [x] [y]. setNum (cardMap [x] [y]. getNum () * 2); cardMap [x1] [y]. setNum (0); MainActivity. getMainActivity (). addScore (cardMap [x] [y]. getNum (); judge = true;} break ;}}}if (judge) {checkGame (); addRandom () ;}} private void swipeUp () {boolean judge = false; for (int x = 0; x <4; x ++) {for (int y = 0; y <4; y ++) {for (int y1 = y + 1; y1 <4; y1 ++) {if (cardMap [x] [y1]. getNum ()> 0) {if (cardMap [x] [y]. getNum () <= 0) {cardMap [x] [y]. setNum (cardMap [x] [y1]. getNum (); cardMap [x] [y1]. setNum (0); y --; judge = true;} else if (cardMap [x] [y]. getNum () = cardMap [x] [y1]. getNum () {cardMap [x] [y]. setNum (cardMap [x] [y]. getNum () * 2); cardMap [x] [y1]. setNum (0); MainActivity. getMainActivity (). addScore (cardMap [x] [y]. getNum (); judge = true;} break ;}}}if (judge) {checkGame (); addRandom () ;}} private void swipeDown () {boolean judge = false; for (int x = 0; x <4; x ++) {for (int y = 3; y> = 0; y --) {for (int y1 = Y-1; y1> = 0; y1 --) {if (cardMap [x] [y1]. getNum ()> 0) {if (cardMap [x] [y]. getNum () <= 0) {cardMap [x] [y]. setNum (cardMap [x] [y1]. getNum (); cardMap [x] [y1]. setNum (0); y ++; judge = true;} else if (cardMap [x] [y]. getNum () = cardMap [x] [y1]. getNum () {cardMap [x] [y]. setNum (cardMap [x] [y]. getNum () * 2); cardMap [x] [y1]. setNum (0); MainActivity. getMainActivity (). addScore (cardMap [x] [y]. getNum (); judge = true;} break ;}}}if (judge) {checkGame (); addRandom ();}}

3. Add random points:

Add a method to GameView. startGame () is called in onSizeChanged ().

/** Game Initialization Method */private void startGame () {MainActivity. getMainActivity (). clearScore (); for (int y = 0; y <4; y ++) {for (int x = 0; x <4; x ++) {cardMap [x] [y]. setNum (0) ;}} addRandom (); addRandom () ;}private List <Point> emptyPoint = new ArrayList <Point> (); // Method for adding a random number private void addRandom () {emptyPoint. clear (); for (int y = 0; y <4; y ++) {for (int x = 0; x <4; x ++) {// place a point smaller than 0 in cardMap on emp In tyPoint, if (cardMap [x] [y]. getNum () <= 0) {emptyPoint. add (new Point (x, y) ;}}// randomly remove a unit in emptyPoint. Point p = emptyPoint. remove (int) (Math. random () * emptyPoint. size (); cardMap [p. x] [p. y]. setNum (Math. random ()> 0.1? 2: 4 );}

4. Determine the end of the game

/** End game Method * when there are equal points and numbers next to the game, the game will not prompt that it has ended */private void checkGame () {boolean check = true; ALL: for (int y = 0; y <4; y ++) {for (int x = 0; x <4; x ++) {if (cardMap [x] [y]. getNum () = 0 | x> 0 & cardMap [x] [y]. equals (cardMap [x-1] [y]) | x <3 & cardMap [x] [y]. equals (cardMap [x + 1] [y]) | y> 0 & cardMap [x] [y]. equals (cardMap [x] [Y-1]) | y <3 & cardMap [x] [y]. equals (cardMap [x] [y + 1]) {check = false; break ALL ;}}// the error code returned when the game fails. if (check) {new AlertDialog. builder (getContext ()). setTitle ("prompt "). setMessage ("game failed "). setPositiveButton ("" ", new DialogInterface. onClickListener () {@ Override public void onClick (DialogInterface dialog, int which) {startGame ();}}). show ();}}

 

My 2048 improvement:

1. added the highest score for display.

2. added the game restart button.

3. added color changes

Game1024 Original: http://pan.baidu.com/s/1sjpCdIl

Game2048 ultimate address: http://pan.baidu.com/s/1o6qyfJc

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.