g2048游戏2-android
来源:互联网 发布:坑爹哥的淘宝店 编辑:程序博客网 时间:2024/06/05 21:16
g2048游戏2-android
接着上一篇g2048游戏1-android
g2048主界面
主界面(MainView)其实就是需要绘制表格,首要考虑android自带的ShapeDrawable资源。
MainView需要绘制:
1:整个表格背景background_rectangle.xml
2:每一小格背景
- 小格无数字背景cell_rectangle.xml
- 小格有数字x背景cell_rectangle_x.xml
- 绘制背景上的数字canvas.drawText
主界面MainView
MainView需要自定义,在该类中只负责绘制,而数据逻辑交给辅助MainGame .java
背景使用ShapeDrawable
整个表格背景background_rectangle.xml
小格无数字背景cell_rectangle.xml
小格有数字x背景cell_rectangle_x.xml这个三个背景是一样的,都使用ShapeDrawable,只是颜色背景不一样
如background_rectangle.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" android:padding = "10dp"> <solid android:color="#bbada0"/> <corners android:bottomRightRadius="10dp" android:bottomLeftRadius="10dp" android:topLeftRadius="10dp" android:topRightRadius="10dp"/></shape>
其他背景颜色
color=”#d6cdc4”
color=”#eee4da”
color=”#ede0c8”
color=”#f2b179”
color=”#f59563”
color=”#f67c5f”
color=”#f65e3b”
color=”#edcf72”
color=”#edcc61”
color=”#edc850”
color=”#edc53f”
color=”#edc22e”
自定义MainView
其中MainGame 对象负责数据逻辑,GestureDetector手势对象负责监听上下左右滑动
public class MainView extends View { public MainGame game; private GestureDetector gesture; private int numCellTypes = 13; // Layout private Paint paint = new Paint(); private int cellSize; private int gridWidth; private float textSize; private float cellTextSize; private int startX; private int endX; private int startY; private int endY; // Text private int TEXT_WHITE; private int TEXT_BLACK; // asssets drawable private Drawable backgroundRectangle; private BitmapDrawable[] bitmapCell = new BitmapDrawable[numCellTypes]; private Bitmap background = null; public MainView(Context context) { super(context); game = new MainGame(this); //Loading resources Resources resources = context.getResources(); try { //Getting assets backgroundRectangle = resources.getDrawable(R.drawable.background_rectangle); TEXT_WHITE = resources.getColor(R.color.text_white); TEXT_BLACK = resources.getColor(R.color.text_black); this.setBackgroundColor(resources.getColor(R.color.background)); Typeface font = Typeface.createFromAsset(resources.getAssets(), "ClearSans-Bold.ttf"); paint.setTypeface(font); paint.setAntiAlias(true); } catch (Exception e) { System.out.println("Error getting assets?"); } gesture = new GestureDetector(context, new InputListener(this)); game.newGame(); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(background, 0, 0, paint); drawCells(canvas); } @Override protected void onSizeChanged(int width, int height, int oldw, int oldh) { super.onSizeChanged(width, height, oldw, oldh); getLayout(width, height); createBitmapCells(); createBackgroundBitmap(width, height); } @Override public boolean onTouchEvent(MotionEvent event) { return gesture.onTouchEvent(event); } private void drawCells(Canvas canvas) { paint.setTextSize(textSize); paint.setTextAlign(Paint.Align.CENTER); for (int i = 0; i < game.numSquaresX; i++) { for (int j = 0; j < game.numSquaresY; j++) { int sX = startX + gridWidth + (cellSize + gridWidth) * i; int eX = sX + cellSize; int sY = startY + gridWidth + (cellSize + gridWidth) * j; int eY = sY + cellSize; CellData currentCellData = game.grid.getCellContent(i, j); if (currentCellData != null) { int value = currentCellData.getValue(); int index = Utils.log2(value) >= numCellTypes ? numCellTypes - 1 : Utils.log2(value); bitmapCell[index].setBounds(sX, sY, eX, eY); bitmapCell[index].draw(canvas); } } } } private void getLayout(int width, int height) { cellSize = Math.min(width / (game.numSquaresX + 1), height / (game.numSquaresY + 3)); gridWidth = cellSize / 7; int screenMiddleX = width / 2; int screenMiddleY = height / 2; paint.setTextAlign(Paint.Align.CENTER); paint.setTextSize(cellSize); textSize = cellSize * cellSize / Math.max(cellSize, paint.measureText("0000")); cellTextSize = textSize; //Grid Dimensions double halfNumSquaresX = game.numSquaresX / 2d; double halfNumSquaresY = game.numSquaresY / 2d; startX = (int) (screenMiddleX - (cellSize + gridWidth) * halfNumSquaresX - gridWidth / 2); endX = (int) (screenMiddleX + (cellSize + gridWidth) * halfNumSquaresX + gridWidth / 2); startY = (int) (screenMiddleY - (cellSize + gridWidth) * halfNumSquaresY - gridWidth / 2); endY = (int) (screenMiddleY + (cellSize + gridWidth) * halfNumSquaresY + gridWidth / 2); } private void createBitmapCells() { Resources resources = getResources(); int[] cellRectangleIds = getCellRectangleIds(); paint.setTextAlign(Paint.Align.CENTER); for (int i = 1; i < bitmapCell.length; i++) { int value = (int) Math.pow(2, i); paint.setTextSize(cellTextSize); float tempTextSize = cellTextSize * cellSize * 0.9f / Math.max(cellSize * 0.9f, paint.measureText(String.valueOf(value))); paint.setTextSize(tempTextSize); Bitmap bitmap = Bitmap.createBitmap(cellSize, cellSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawDrawable(canvas, resources.getDrawable(cellRectangleIds[i]), 0, 0, cellSize, cellSize); drawCellText(canvas, value, 0, 0); bitmapCell[i] = new BitmapDrawable(resources, bitmap); } } private int[] getCellRectangleIds() { int[] cellRectangleIds = new int[numCellTypes]; cellRectangleIds[0] = R.drawable.cell_rectangle; cellRectangleIds[1] = R.drawable.cell_rectangle_2; cellRectangleIds[2] = R.drawable.cell_rectangle_4; cellRectangleIds[3] = R.drawable.cell_rectangle_8; cellRectangleIds[4] = R.drawable.cell_rectangle_16; cellRectangleIds[5] = R.drawable.cell_rectangle_32; cellRectangleIds[6] = R.drawable.cell_rectangle_64; cellRectangleIds[7] = R.drawable.cell_rectangle_128; cellRectangleIds[8] = R.drawable.cell_rectangle_256; cellRectangleIds[9] = R.drawable.cell_rectangle_512; cellRectangleIds[10] = R.drawable.cell_rectangle_1024; cellRectangleIds[11] = R.drawable.cell_rectangle_2048; cellRectangleIds[12] = R.drawable.cell_rectangle_4096; return cellRectangleIds; } private void createBackgroundBitmap(int width, int height) { background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(background); drawBackground(canvas); drawBackgroundGrid(canvas); } private void drawBackground(Canvas canvas) { drawDrawable(canvas, backgroundRectangle, startX, startY, endX, endY); } private void drawBackgroundGrid(Canvas canvas) { Resources resources = getResources(); Drawable backgroundCell = resources.getDrawable(R.drawable.cell_rectangle); for (int i = 0; i < game.numSquaresX; i++) { for (int j = 0; j < game.numSquaresY; j++) { int sX = startX + gridWidth + (cellSize + gridWidth) * i; int eX = sX + cellSize; int sY = startY + gridWidth + (cellSize + gridWidth) * j; int eY = sY + cellSize; drawDrawable(canvas, backgroundCell, sX, sY, eX, eY); } } } private void drawDrawable(Canvas canvas, Drawable draw, int startX, int startY, int endX, int endY) { draw.setBounds(startX, startY, endX, endY); draw.draw(canvas); } private void drawCellText(Canvas canvas, int value, int sX, int sY) { int textShiftY = Utils.centerText(paint); if (value >= 8) { paint.setColor(TEXT_WHITE); } else { paint.setColor(TEXT_BLACK); } canvas.drawText("" + value, sX + cellSize / 2, sY + cellSize / 2 - textShiftY, paint); }}
添加工具类Utils
工具类一般添加固定通用的方法,便于以后快速开发调用。
下面Utils中是对自定义MainView增加两种方法:一种是计算绘画字符串的基准线;一种是计算一个数是2的几次方
public class Utils { public static int centerText(Paint paint) { return (int) ((paint.descent() + paint.ascent()) / 2); } public static int log2(int n) { if (n <= 0) throw new IllegalArgumentException(); return 31 - Integer.numberOfLeadingZeros(n); }}
上面“计算一个数是2的几次方”还有其他方法:
(int) (Math.log10(n) / Math.log10(2))
下一篇g2048游戏3-android
- g2048游戏2-android
- g2048游戏1-android
- g2048游戏3-android
- android 游戏总结2
- Android 2D游戏引擎
- Android 游戏2:勇者喂恶龙
- android 2D游戏开发
- Android游戏
- android游戏
- Android游戏开发:游戏框架的搭建(2)
- Android游戏开发---2D游戏中背景的绘制
- Android游戏开发十日通(2)-搭建libgdx游戏引擎
- Android游戏开发:游戏框架的搭建(2)
- Android游戏开发---2D游戏中背景的绘制
- Android游戏开发实例第2步之游戏架构
- Android游戏开发:游戏框架的搭建(2)
- android游戏开发之我的小小游戏2——连连看游戏7优化
- android游戏个人经验2[转]
- 最新Android集成环信步骤详解
- LeetCode 136. Single Number
- UnityShader - 屏幕特效 - 高斯模糊(Gaussian Blur)
- HDU 3488Tour 最大完美匹配
- test
- g2048游戏2-android
- 基于Redux的ReactNative项目开发总结(一)
- 工作两周年记
- ios开发之小总结「类与对象的判断方法和遍历字典的方法」
- 欢迎使用CSDN-markdown编辑器
- 【译】Redux + React 应用程序架构的 3 条规范(内附实例)
- Spring支持邮件开发
- 设计模式(6)-适配器模式(Adapter)
- Handler消息机制