• Android 数独游戏 记录


    Android图形编程基本概念

    1. 颜色对象

      Color 类

      int color = Color.bule    //蓝色

      int color = Color.argb(255,255,255,255);        //透明度,红,绿,蓝

      在XML文件中定义颜色

    2. 画笔对象

      Paint 类

      Paint.setColor(Color.blue);

       

    3. 画布对象

      Canvas 类

      Canvas.drawCircle(300, 400, 100, paint);

       

    自定义View的基本实现方法

    1. 定义一个类,继承View
    2. 复写View中的onDraw()方法
    3. 在onDraw()中使用Canvas和Paint绘制图形

       

      矩形。圆形、空心、实心、线、文字、……

    @Override

        protected void onDraw(Canvas canvas) {

            Paint paint = new Paint();

            paint.setARGB(255, 0, 255, 0);

            paint.setStyle(Paint.Style.STROKE);// 空心

            paint.setStrokeWidth(10);// 边的宽度

            canvas.drawRect(100, 100, 500, 500, paint);// 矩形

            paint.setStyle(Paint.Style.FILL);// 实心

            paint.setColor(Color.CYAN);

            canvas.drawCircle(500, 500, 100, paint);// 圆形

            paint.setTextSize(100);

            paint.setColor(Color.BLUE);

            canvas.drawText("Apple ggGG", 50, 800, paint);

            paint.setColor(Color.RED);

            paint.setStrokeWidth(5);// 边的宽度

            canvas.drawLine(0, 800, 720, 800, paint);

            canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),

                    R.drawable.ic_launcher), 200, 200, paint);

            super.onDraw(canvas);

        }

     

    绘制九宫格

    @Override

        protected void onDraw(Canvas canvas) {

            // 首先取得屏幕的宽度和高度

            width = this.getWidth();

            cell_width = width / 9f;

            height = this.getHeight();

            cell_height = height / 9f;

            // 首先画出背景

            Paint bgPaint = new Paint();// 用于绘制背景

            bgPaint.setColor(getResources().getColor(R.color.shudu_background));

            canvas.drawRect(0, 0, width, height, bgPaint);

            // 画出九宫格

            Paint darkPaint = new Paint();// 暗色

            darkPaint.setColor(getResources().getColor(R.color.shudu_dark));

            Paint lightPaint = new Paint();// 亮色

            darkPaint.setColor(getResources().getColor(R.color.shudu_light));

            Paint hilitePaint = new Paint();// 线条

            darkPaint.setColor(getResources().getColor(R.color.shudu_hilite));

            for (int i = 0; i < 9; i++) {

                if (i % 3 == 0) {

                    canvas.drawLine(0, i * cell_height, width, i * cell_height,

                            lightPaint);

                    canvas.drawLine(i * cell_width, 0, i * cell_width, height,

                            lightPaint);

                } else {

                    canvas.drawLine(0, i * cell_height, width, i * cell_height,

                            darkPaint);

                    canvas.drawLine(i * cell_width, 0, i * cell_width, height,

                            darkPaint);

                }

                canvas.drawLine(0, i * cell_height + 1, width, i * cell_height + 1,

                        hilitePaint);

                canvas.drawLine(i * cell_width + 1, 0, i * cell_width + 1, height,

                        hilitePaint);

            }

            // 绘制文字

            Paint numPaint = new Paint();

            numPaint.setColor(Color.BLUE);

            numPaint.setStyle(Paint.Style.STROKE);

            numPaint.setTextSize(cell_height * 0.25f);

            numPaint.setTextAlign(Paint.Align.CENTER);

            float x = cell_width / 2;

            float y = cell_height / 2;

            for (int i = 0; i < 9; i++) {

                for (int j = 0; j < 9; j++) {

                    canvas.drawText("" + i + "," + j, i * cell_width

                            + x, j * cell_height + y, numPaint);

                }

            }

            super.onDraw(canvas);

        }

    文字居中显示

    FontMtrics类

    FontMetrics fontMetrics = paint.get FontMetrics();

            FontMetrics fm = numPaint.getFontMetrics();

            float x = cell_width / 2;

            float y = cell_height / 2 - (fm.ascent + fm.descent) / 2;

    显示数据

    把逻辑处理放在Activity外部,新建一个类

    package com.arlen.android.game.shudu03;

    public class Game {

        private final String str = "450890000000000000008700090607005030090020040040900102070006300000000000000048016";

        private int shuduku[] = new int[81];

        public Game() {

            shuduku = fromPuzzleString(str);

        }

        private int getTitle(int x, int y) {

            return shuduku[y * 9 + x];

        }

        public String getTitleString(int x, int y) {

            int v = getTitle(x, y);

            if (v == 0) {

                return "";

            } else {

                return String.valueOf(v);

            }

        }

        protected int[] fromPuzzleString(String src) {

            int sudu[] = new int[src.length()];

            for (int i = 0; i < sudu.length; i++) {

                sudu[i] = src.charAt(i) - '0';

            }

            return sudu;

        }

    }

    在View中调用

            for (int i = 0; i < 9; i++) {

                for (int j = 0; j < 9; j++) {

                    canvas.drawText(game.getTitleString(i, j), i * cell_width + x,

                            j * cell_height + y, numPaint);

                }

            }

    单点触摸事件

    在为初始化数字的空格中点击,然后输入数字

    public Boolean onTouchEvent(MotionEvent event){

    //获取事件的类型

    event.getAction();

    //获取点击坐标

    Event.getX();

    Event.getY();

    }

            // 生成一个layoutInflater对象

            LayoutInflater layoutInflater = LayoutInflater.from(this.getContext());

            // 使用layoutInflater对象更具一个布局文件生成一个view对象

            View layoutView = layoutInflater.inflate(R.layout.dialog, null);

            // 从生成好的textView中取出相应的控件

            TextView textView = (TextView) layoutView

                    .findViewById(R.id.textViewUsedId);

            // 设置textView的内容

            textView.setText(sb.toString());

            // 生成一个对话框的builder对象

            AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());

            // 设置地对话框所要显示的内容

            builder.setView(layoutView);

            // 生成对话框对象并将其显示出来

            AlertDialog dialog = builder.create();

            dialog.show();

    碰撞检测

    用户点击屏幕之后,确定用户点击的位置属于哪一个格子

    取得用户点击的坐标,判断是否在startX、startY与stopX、stopY之间

        @Override

        public boolean onTouchEvent(MotionEvent event) {

            if (event.getAction() != MotionEvent.ACTION_DOWN) {

                return super.onTouchEvent(event);

            }

            int selectX = (int) (event.getX() / cell_width);

            int selectY = (int) (event.getY() / cell_height);

            int used[] = game.getUsedTileByCoor(selectY, selectY);

            for (int i = 0; i < used.length; i++) {

                System.out.println(used[i]);

            }

            return true;

        }

    可用数据计算

    在每一行、每一列、每一个小的九宫格中已有的数据禁止重复输入,

        //用于计算所有单元格对应的不可用的数据

        public void calculateAllUsedTitles() {

            for (int x = 0; x < 9; x++) {

                for (int y = 0; y < 9; y++) {

                    used[x][y] = calculateUsedTiles(x, y);

                }

            }

        }

        //取出某一单元格已经不可用的数据

        public int[] getUsedTileByCoor(int x, int y) {

            return used[x][y];

        }

        // 计算某一单元格中已经用过的数据

        public int[] calculateUsedTiles(int x, int y) {

            int c[] = new int[9];

            for (int i = 0; i < 9; i++) {

                if (i == y) {

                    continue;

                }

                int t = getTitle(x, i);

                if (t != 0) {

                    c[t - 1] = t;

                }

            }

            for (int i = 0; i < 9; i++) {

                if (i == x) {

                    continue;

                }

                int t = getTitle(i, y);

                if (t != 0) {

                    c[t - 1] = t;

                }

            }

            int startX = (x / 3) * 3;

            int startY = (y / 3) * 3;

            for (int i = startX; i < startX + 3; i++) {

                for (int j = startY; j < startY + 3; j++) {

                    if (i == x && j == y) {

                        continue;

                    }

                    int t = getTitle(i, y);

                    if (t != 0) {

                        c[t - 1] = t;

                    }

                }

            }

            // compress

            int nused = 0;

            for (int t : c) {

                if (t != 0) {

                    nused++;

                }

            }

            int c1[] = new int[nused];

            nused = 0;

            for (int t : c) {

                if (t != 0) {

                    c1[nused++] = t;

                }

            }

            return c1;

        }

    弹出交互对话框

    布局文件

    <?xml version="1.0" encoding="utf-8"?>

    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/keypad"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:orientation="vertical" >

    <TableRow>

    <Button

    android:id="@+id/button1"

    android:text="1" />

    <Button

    android:id="@+id/button2"

    android:text="2" />

    <Button

    android:id="@+id/button3"

    android:text="3" />

    </TableRow>

    <TableRow>

    <Button

    android:id="@+id/button4"

    android:text="4" />

    <Button

    android:id="@+id/button5"

    android:text="5" />

    <Button

    android:id="@+id/button6"

    android:text="6" />

    </TableRow>

    <TableRow>

    <Button

    android:id="@+id/button7"

    android:text="7" />

    <Button

    android:id="@+id/button8"

    android:text="8" />

    <Button

    android:id="@+id/button9"

    android:text="9" />

    </TableRow>

    </TableLayout>

    根据点击的位置不同,弹出的窗口不同

    package com.arlen.android.game.shudu03;

    import android.app.Dialog;

    import android.content.Context;

    import android.os.Bundle;

    import android.view.View;

    public class KeyDialog extends Dialog {

        // 用来存放代表对话框中按钮的对象

        private final View keys[] = new View[9];

        private final int used[];

        // 构造函数的第二个参数保存当前单元格已经用过的数据

        public KeyDialog(Context context, int[] used) {

            super(context);

            this.used = used;

        }

        // 当对话框第一次被调用的时候,会调用其onCreate方法

        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            // 标题

            this.setTitle("Key Dialog");

            // 为该对话框设置布局文件

            this.setContentView(R.layout.keypad);

            findViews();

            // 便利整个used数组

            for (int i = 0; i < used.length; i++) {

                if (used[i] != 0) {

                    keys[used[i] - 1].setVisibility(View.INVISIBLE);

                }

            }

        }

        private void findViews() {

            keys[0] = findViewById(R.id.button1);

            keys[1] = findViewById(R.id.button2);

            keys[2] = findViewById(R.id.button3);

            keys[3] = findViewById(R.id.button4);

            keys[4] = findViewById(R.id.button5);

            keys[5] = findViewById(R.id.button6);

            keys[6] = findViewById(R.id.button7);

            keys[7] = findViewById(R.id.button8);

            keys[8] = findViewById(R.id.button9);

        }

    }

  • 相关阅读:
    cenos7 安装samba
    Cenos7 学习笔记
    mysql学习笔记(一)
    Qt 程序打包发布总结 转
    主机名由localhost变成bogon是怎么回事,怎样变回localhost这个名字?
    Heap Size 与 Stack Size
    数据字节对齐案例
    C语言进阶日志二
    位带操作
    Stm32高级定时器(转自:luowei_memory)
  • 原文地址:https://www.cnblogs.com/zhangtingkuo/p/3424578.html
Copyright © 2020-2023  润新知