Android实现九格智能拼图算法
最近想业余做一款android游戏,发现我国一款古老好玩的智力游戏-九格智能拼图挺好玩的,相信大多80后小时玩过,因此有了开发的想法。
一、九格智能拼图
游戏规则:将一副图片分割为9个子图片,其中一个为空白图片,随机打乱。通过两两图片的交换,合并为一张图片,最后游戏完成。
二、开发步骤
1、将一个图片分割为9个子图片,放入ArrayList中。
利用Bitmap.createBitmap()进行图片切割, 根据参数坐标的不同,可以切图一张图片的任意部分。
2、采用自定义view,随机打乱的画出9个子图片
选生成0-9的随机排列。然后根据排列值画出对应的图片
3、在自定义view中响应点击图片是否可以移动。
遍历左右方块数字,如果为0,则可以移动。同时交换相连数字和数组中的位置。
4、判断游戏完成的结束算法。
依次遍历各个方块,如何数字呈依次递增排列,则游戏结束
代码:
package org.diudiululu.magicSquare; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Point; import android.os.Bundle; import android.util.Log; /** * @author a1623z * */ public class MagicSquareActivity extends Activity { private static final String TAG = "MagicSquare"; public static final int SQUARE_WIDTH = 3; private int square[] = new int[SQUARE_WIDTH * SQUARE_WIDTH]; private int steps = 0; private MagicSquareView magicSquareView; public int getTitleNumber(int x, int y) { return square[y * SQUARE_WIDTH + x]; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(this.TAG, "OnCreate"); initGame(); magicSquareView = new MagicSquareView(this); this.setContentView(magicSquareView); magicSquareView.requestFocus(); } private void initGame() { generateMagicSquare(); steps = 0; } private void generateMagicSquare() { java.util.ArrayList<Integer> numArray = new java.util.ArrayList<Integer>(); for (int i = 0; i < square.length; i++) { numArray.add(new Integer(i)); } int i = 0; while (numArray.size() > 0) { int index = (int) (Math.random() * numArray.size()); Integer integer = numArray.get(index); square[i] = integer.intValue(); i++; numArray.remove(index); } } public boolean moveable(int x, int y) { if (x < 0 || x >= SQUARE_WIDTH) return false; if (y < 0 || y >= SQUARE_WIDTH) return false; for (int i = x - 1; i <= x + 1; i++) { for (int j = y - 1; j <= y + 1; j++) { if (i == x && j == y) // it's myself, skip continue; if (i != x && j != y) continue; if (i < 0 || i >= SQUARE_WIDTH) continue; if (j < 0 || j >= SQUARE_WIDTH) continue; if (square[j * SQUARE_WIDTH + i] == 0) return true; } } return false; } public Point move(int x, int y) { Log.d(TAG, "move" + ",x=" + x + ",y=" + y); if (!moveable(x, y)) return new Point(-1, -1); steps++; for (int i = x - 1; i <= x + 1; i++) { for (int j = y - 1; j <= y + 1; j++) { if (i == x && j == y) // it's myself, skip continue; if (i != x && j != y) continue; if (i < 0 || i >= SQUARE_WIDTH) continue; if (j < 0 || j >= SQUARE_WIDTH) continue; if (square[j * SQUARE_WIDTH + i] == 0) { int temp = square[j * SQUARE_WIDTH + i]; square[j * SQUARE_WIDTH + i] = square[y * SQUARE_WIDTH + x]; square[y * SQUARE_WIDTH + x] = temp; return new Point(i, j); } } } return new Point(-1, -1); } public boolean win() { for (int i = 0; i < square.length - 1; i++) { if (square[i] != i + 1) return false; } return true; } public class Pic{ private int id; private Bitmap subbitmap; } }
MagicSquarView.java
/** * */ package org.diudiululu.magicSquare; import java.util.ArrayList; import org.diudiululu.magicSquare.R; import android.app.Dialog; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.*; import android.graphics.*; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.Style; import android.util.*; /** * @author a1623z * */ public class MagicSquareView extends View { private static final String TAG = "MagicSquare"; private final MagicSquareActivity magicSquareActivity; private float width; private float height; private int selX; private int selY; private final Rect selRect = new Rect(); private final int pingtuheight = 200; private ArrayList<Pic> pieces; /** * @param context */ public MagicSquareView(Context context) { super(context); this.magicSquareActivity = (MagicSquareActivity) context; this.setFocusable(true); this.setFocusableInTouchMode(true); // TODO Auto-generated constructor stub } // 切割图片,放入ArrayList中 { pieces = new ArrayList<MagicSquareView.Pic>(); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pingtu); int bitmapwidth = bitmap.getWidth(); int bitmapheight = bitmap.getHeight(); int pieceWidth = bitmapwidth / 3; int pieceHeight = bitmapheight / 3; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Pic piece = new Pic(); piece.index = j + i * 3; int xValue = j * pieceWidth; int yValue = i * pieceHeight; piece.piece = Bitmap.createBitmap(bitmap, xValue, yValue, pieceWidth, pieceHeight); pieces.add(piece); } } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w / 3f; height = (h - pingtuheight) / 3f; getRect(selX, selY, selRect); Log.d(TAG, "onSizeChanged: width=" + width + ", height=" + height + ",selX=" + selX + ",selY=" + selY); super.onSizeChanged(w, h, oldw, oldh); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: select(selX, selY - 1); break; case KeyEvent.KEYCODE_DPAD_DOWN: select(selX, selY + 1); break; case KeyEvent.KEYCODE_DPAD_LEFT: select(selX - 1, selY); break; case KeyEvent.KEYCODE_DPAD_RIGHT: select(selX + 1, selY); break; case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_DPAD_CENTER: Point point = magicSquareActivity.move(selX, selY); if (point.x >= 0 && point.y >= 0) { this.invalidate(selRect); Rect targetRect = new Rect(); this.getRect(point.x, point.y, targetRect); this.invalidate(targetRect); } break; default: return super.onKeyDown(keyCode, event); } return true; } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) return super.onTouchEvent(event); if (event.getY() <= pingtuheight) return false; Log.i(TAG, "event.getX()=" + event.getX() + ",event.getY=" + event.getY()); select((int) (event.getX() / width), (int) ((event.getY() - pingtuheight) / height)); Point point = magicSquareActivity.move(selX, selY); if (point.x >= 0 && point.y >= 0) { this.invalidate(selRect); Rect targetRect = new Rect(); this.getRect(point.x, point.y, targetRect); this.invalidate(targetRect); } return true; } @Override protected void onDraw(Canvas canvas) { Paint backround = new Paint(); backround.setColor(getResources().getColor(R.color.ms_backgroud)); canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), backround); // 画出原图及图片的介绍 Rect dst = new Rect();// 屏幕 >>目标矩形 Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.pingtu); dst.left = 0; dst.top = 0; dst.right = (int) (width * 3) / 2; dst.bottom = pingtuheight; canvas.drawBitmap(pic, null, dst, null); // 绘制出图片的介绍 Paint textpaint = new Paint(); textpaint.setTextSize(25); canvas.drawText("一副美丽的图片,", dst.right, 30, textpaint); canvas.drawText("但已支离破碎......", dst.right, 70, textpaint); // draw the board Paint dark = new Paint(); dark.setColor(getResources().getColor(R.color.ms_dark)); Paint hilite = new Paint(); hilite.setColor(getResources().getColor(R.color.ms_hilite)); Paint light = new Paint(); light.setColor(getResources().getColor(R.color.ms_light)); // draw the minor grid lines for (int i = 0; i < 3; i++) { canvas.drawLine(0, i * height + pingtuheight, getWidth(), i * height + pingtuheight, light); canvas.drawLine(0, i * height + 1 + pingtuheight, getWidth(), i * height + pingtuheight + 1, hilite); canvas.drawLine(i * width, pingtuheight, i * width, getHeight() + pingtuheight, light); canvas.drawLine(i * width + 1, pingtuheight, i * width + 1, getHeight() + pingtuheight, hilite); } Rect picrect = new Rect(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int n = this.magicSquareActivity.getTitleNumber(i, j);//根据坐标依次取出0,1,2,3,4,5,6,7,8下标数组对应的值 if (n == 0) continue; picrect.left = (int) (i * width); picrect.top = pingtuheight + (int) (j * height); picrect.right = (int) (i * width + width); picrect.bottom = (int) (pingtuheight + j * height + height); canvas.drawBitmap(pieces.get(n).getPiece(), null, picrect, null); } } Paint selected = new Paint(); selected.setColor(getResources().getColor(R.color.ms_selected)); canvas.drawRect(selRect, selected); if (magicSquareActivity.win()) { Dialog winDlg = new Win(magicSquareActivity); winDlg.show(); magicSquareActivity.finish(); } } private void getRect(int x, int y, Rect rect) { Log.i(TAG, "getRect" + x + "y" + y); rect.set((int) (x * width), (int) (y * height + pingtuheight), (int) (x * width + width), (int) (y * height + height + pingtuheight)); } private void select(int x, int y) { invalidate(selRect); selX = Math.min(Math.max(x, 0), 2); selY = Math.min(Math.max(y, 0), 2); getRect(selX, selY, selRect); invalidate(selRect); } public class Pic { public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public Bitmap getPiece() { return piece; } public void setPiece(Bitmap piece) { this.piece = piece; } int index; Bitmap piece; } }
三、运行结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Flutter加载图片流程MultiFrameImageStreamCompleter解析
这篇文章主要为大家介绍了Flutter加载图片流程MultiFrameImageStreamCompleter示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-04-04Android编程之绘制文本(FontMetrics)实现方法
这篇文章主要介绍了Android编程之绘制文本(FontMetrics)实现方法,结合实例形式较为详细的分析了Android使用FontMetrics对象绘制文本的相关技巧,需要的朋友可以参考下2015-12-12Android EditText输入框实现下拉且保存最近5个历史记录思路详解
今天给大家介绍Android EditText输入框实现下拉且保存最近5个历史记录功能,android实现文本框下拉利用sharedpreferences来保存每次app启动和关闭时已经填写的数值,具体代码跟随小编一起看看吧2021-07-07
最新评论