g2048游戏2-android

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

j\i0123
042
14
22
32

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值