Android jigsaw puzzle game development full record 3

Source: Internet
Author: User

Today, we will continue to develop Android game puzzles. Today we are also doing some preparation work. Yesterday we have prepared the UI. Today, let's think about how to complete a puzzle, what preparations do we need to make.

First, we need a tool class to obtain information about the screen, so that our program can automatically adapt to screens of different resolutions:

Package com. xys. xpuzzle. util; import android. content. context; import android. util. displayMetrics; import android. view. display; import android. view. windowManager;/*** screen tool class: implement screen-related parameters ** @ author xys **/public class ScreenUtil {/*** to obtain screen-related parameters ** @ param context * @ return DisplayMetrics screen width and height */public static DisplayMetrics getScreenSize (Context context) {DisplayMetrics metrics = new DisplayMetrics (); WindowManager wm = (WindowManager) context. getSystemService (Context. WINDOW_SERVICE); Display display = wm. getdefadisplay display (); display. getMetrics (metrics); return metrics ;}}

Next we will begin to design an Entity bean to encapsulate our puzzles. There are many methods here. I just want to give a brick.

As we know, an image is split into NXN blocks and moved to complete the puzzle, so I made an object for each split block, all our entity beans are based on each split square, so naturally we can abstract an Entity bean:

Package com. xys. xpuzzle. bean; import android. graphics. bitmap;/*** puzzle Item logical entity class: encapsulate logic-related attributes ** @ author xys **/public class ItemBean {// Item Id private int itemId; // bitmap Id private int bitmapId; // bitmap private Bitmap bitmap; public int getItemId () {return itemId;} public void setItemId (int itemId) {this. itemId = itemId;} public ItemBean () {} public int getBitmapId () {return bitmapId;} public void setBitmapId (int bitmapId) {this. bitmapId = bitmapId;} public Bitmap getBitmap () {return bitmap;} public void setBitmap (Bitmap bitmap) {this. bitmap = bitmap;} public ItemBean (int itemId, int bitmapId, Bitmap bitmap) {this. itemId = itemId; this. bitmapId = bitmapId; this. bitmap = bitmap ;}}

Bean encapsulates

1. The number of squares in the NXN format

2. the ID of the split image and the corresponding image

Next we will split the image:

Package com. xys. xpuzzle. util; import java. util. arrayList; import java. util. list; import com. xys. xpuzzle. r; import com. xys. xpuzzle. activity. puzzleMain; import com. xys. xpuzzle. bean. itemBean; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. graphics. matrix;/*** image tool class: Implements image segmentation and adaptability ** @ author xys **/public class ImagesUtil {public ItemBean itemBean; /*** cut graph, initial state (normal order) ** @ param type * @ param picSelected * @ param context */public void createInitBitmaps (int type, Bitmap picSelected, Context context) {Bitmap bitmap = null; List <Bitmap> bitmapItems = new ArrayList <Bitmap> (); // the width and height of each Item int itemWidth = picSelected. getWidth ()/type; int itemHeight = picSelected. getHeight ()/type; for (int I = 1; I <= type; I ++) {for (int j = 1; j <= type; j ++) {bitmap = Bitmap. createBitmap (picSelected, (j-1) * itemWidth, (I-1) * itemHeight, itemWidth, itemHeight); bitmapItems. add (bitmap); itemBean = new ItemBean (I-1) * type + j, (I-1) * type + j, bitmap); GameUtil. itemBeans. add (itemBean) ;}}// save the last image and fill it with PuzzleMain when the puzzle is complete. lastBitmap = bitmapItems. get (type * type-1); // you can specify ItembitmapItems. remove (type * type-1); GameUtil. itemBeans. remove (type * type-1); Bitmap blankBitmap = BitmapFactory. decodeResource (context. getResources (), R. drawable. blank); blkbitmap = Bitmap. createBitmap (blankBitmap, 0, 0, itemWidth, itemHeight); bitmapItems. add (blankBitmap); GameUtil. itemBeans. add (new ItemBean (type * type, 0, blankBitmap); GameUtil. blankItemBean = GameUtil. itemBeans. get (type * type-1 );} /*** process the image to zoom in and zoom out to the appropriate position ** @ param newWidth * @ param newHeight * @ param bitmap * @ return */public Bitmap resizeBitmap (float newWidth, float newHeight, bitmap bitmap) {Matrix matrix = new Matrix (); matrix. postScale (newWidth/bitmap. getWidth (), newHeight/bitmap. getHeight (); Bitmap newBitmap = Bitmap. createBitmap (bitmap, 0, 0, bitmap. getWidth (), bitmap. getHeight (), matrix, true); return newBitmap ;}}

This tool class mainly completes these two tasks:

1. Cut the graph and the initial status (in normal order)

2. process images to zoom in or out to a proper position

According to the algorithm mentioned in the previous article, we need to split the image and generate an Items set after the image is cut. Of course, we need to process the image size under the puzzle, because in addition to the default image, we can also customize the image.


After the image tool class is complete, we need to implement these algorithms in a tool class and make some game encapsulation:

Package com. xys. xpuzzle. util; import java. util. arrayList; import java. util. list; import com. xys. xpuzzle. activity. puzzleMain; import com. xys. xpuzzle. bean. itemBean;/*** puzzle tool class: implement the algorithm ** @ author xys **/public class GameUtil {// Game Information Cell Bean public static List <ItemBean> itemBeans = new ArrayList <ItemBean> (); // space cell public static ItemBean blankItemBean = new ItemBean ();/*** determines whether the clicked Item is movable ** @ p Whether aram position * @ return can be moved */public static boolean isMoveable (int position) {int type = PuzzleMain. type; // obtain the space Itemint blankId = GameUtil. blankItemBean. getItemId ()-1; // The difference between different rows is typeif (Math. abs (blankId-position) = type) {return true;} // the same row difference is 1if (blankId/type = position/type) & Math. abs (blankId-position) = 1) {return true;} return false;}/*** switch spaces and click the position of the Item ** @ param from * @ Param blank */public static void swapItems (ItemBean from, ItemBean blank) {ItemBean tempItemBean = new ItemBean (); // exchange BitmapIdtempItemBean. setBitmapId (from. getBitmapId (); from. setBitmapId (blank. getBitmapId (); blank. setBitmapId (tempItemBean. getBitmapId (); // exchange BitmaptempItemBean. setBitmap (from. getBitmap (); from. setBitmap (blank. getBitmap (); blank. setBitmap (tempItemBean. getBitmap (); // you can specify a new value for the machine. AmeUtil. blankItemBean = from;}/*** generate a random Item */public static void getPuzzleGenerator () {int index = 0; for (int I = 0; I <itemBeans. size (); I ++) {index = (int) (Math. random () * PuzzleMain. type * PuzzleMain. type); swapItems (itemBeans. get (index), GameUtil. blankItemBean);} List <Integer> data = new ArrayList <Integer> (); for (int I = 0; I <itemBeans. size (); I ++) {data. add (itemBeans. get (I ). getBitma PId ();} // determines whether the generated result has a solution. if (canSolve (data) {return;} else {getPuzzleGenerator ();}} /*** whether the puzzle is successful ** @ return whether the puzzle is successful */public static boolean isSuccess () {for (ItemBean tempBean: GameUtil. itemBeans) {if (tempBean. getBitmapId ()! = 0 & (tempBean. getItemId () = tempBean. getBitmapId () {continue;} else if (tempBean. getBitmapId () = 0 & tempBean. getItemId () = PuzzleMain. type * PuzzleMain. type) {continue;} else {return false ;}} return true ;} /*** whether the data has been resolved ** @ param data * @ return whether the data has been resolved */public static boolean canSolve (List <Integer> data) {// obtain the space Idint blankId = GameUtil. blankItemBean. getItemId (); // feasibility principle if (data. size () % 2 = 1) {return getInversions (data) % 2 = 0;} else {// number of leading spaces at the bottom, if (int) (blankId-1)/PuzzleMain. type) % 2 = 1) {return getInversions (data) % 2 = 0;} else {// number of rows from the bottom up. The empty rows are in the even row return getInversions (data) % 2 = 1 ;}}} /*** calculate the inversion and algorithm ** @ param data * @ return the inversion of the sequence and */public static int getInversions (List <Integer> data) {int inversions = 0; int inversionCount = 0; for (int I = 0; I <Data. size (); I ++) {for (int j = I + 1; j <data. size (); j ++) {int index = data. get (I); if (data. get (j )! = 0 & data. get (j) <index) {inversionCount ++ ;}} inversions + = inversionCount; inversionCount = 0 ;}return inversions ;}}

As you can see, in the game tool class, we mainly have the following features:

1. Determine whether the clicked Item can be moved: the main difficulty is to determine whether it needs to be divided into the same row and different rows. Otherwise, the last row and the first row of the previous row may be moved.

2. Switching spaces and clicking the position of an Item is actually switching the background of one or two items in the GridView.

3. Generate a random Item: based on the algorithm described in the previous article, randomly disrupt the split image.

4. Determine whether the puzzle is successful: based on the algorithm conclusion mentioned in the previous article

5. Determine whether the data is parsed: based on the algorithm conclusion in the previous article

6. Calculation inversion and algorithms: the Core of the algorithm should be kicked out of spaces.


So far, our preparations have basically ended. Many people may say that we have prepared so much at the beginning. In fact, this is the actual order of thinking. At the beginning of the project, you must plan the entire project first, instead of getting started. When you have a clear idea, coding is just a physical activity. Therefore, to do good things, you must first sharpen the tools and draw bamboo.


Ps: Leave a message if you need source code.



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.