安卓开发_数独游戏基础

学习内容来自千锋Mars老师数独教程

主要学习内容:

1、图形编程

2、自定义View类

3、FontMmetrics

4、单击触摸事件

5、碰撞检测

6、可用数据计算

图形编程基本概念:

1、颜色对象

Color 安卓系统中的颜色的表示方法

(1)、int color = Color.blue; //纯色

(2)、int color = Color.argb(188,255,255,255);//自定义颜色

(3)、在xml文件当中定义颜色

2、画笔对象

Paint 该类的对象用于控制画笔的风格和颜色等方面的信息

(1)、paint.setColor(Color.blue);

3、canvas 该类代表一块“画布”,可以在“画布”上绘制字符,图形和图片

(1)、canvas.drawcircle(300,400,100,paint);

自定义View的基本实现方法:

(1)、定义一个类,继承View

(2)、复写View的onDraw函数

(3)、在onDraw当中使用canvas和paint对象绘制图形

Paint的设置方法:

1、setAntiAlias:设置画笔的锯齿效果

2、setARGB:设置画笔的argb对象

3、setTextSize:设置字体尺寸

4、setColor:设置画笔颜色

5、setAlpha:设置透明度值

6、setStyle:设置画笔风格,空心或实心

7、getColor:得到画笔颜色

8、getApha:得到画笔的透明度值

public boolean onTouchEvent(MotionEvent event){

  //获得事件的种类

  event.getAction();

  //获取点击的坐标

  event.getX();

  event.getY();

}

直接上代码

总共四个类

一、ShuduView.java 游戏界面构画

  1 package myview;
  2
  3 import xqx.shudu.Game;
  4 import xqx.shudu.R;
  5 import xqx.shudu.SelectDialog;
  6
  7 import android.app.AlertDialog;
  8 import android.app.AlertDialog.Builder;
  9 import android.content.Context;
 10 import android.content.DialogInterface;
 11 import android.graphics.Canvas;
 12 import android.graphics.Color;
 13 import android.graphics.Paint;
 14 import android.graphics.Paint.Align;
 15 import android.graphics.Paint.FontMetrics;
 16 import android.graphics.Paint.Style;
 17 import android.view.LayoutInflater;
 18 import android.view.MotionEvent;
 19 import android.view.View;
 20 import android.widget.TextView;
 21 import android.widget.Toast;
 22
 23 public class ShuduView extends View{
 24     //记录单元格的高度和宽度
 25     private float width;
 26     private float height;
 27     private Game game = new Game();
 28     int selectx;
 29     int selecty;
 30     public ShuduView(Context context) {
 31         super(context);
 32         // TODO Auto-generated constructor stub
 33     }
 34     @Override
 35     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 36         // TODO Auto-generated method stub
 37         //计算当前单元格的宽度和高度
 38         this.width  = w/9f;//每一格的宽度
 39         this.height = h/9f;//每一格的高度
 40         super.onSizeChanged(w, h, oldw, oldh);
 41     }
 42     @Override
 43     protected void onDraw(Canvas canvas) {
 44         // TODO Auto-generated method stub
 45         //1、绘制背景
 46         Paint bgpaint = new Paint();
 47         bgpaint.setColor(Color.GRAY);
 48         //绘制背景色
 49         canvas.drawRect(0, 0, getWidth(), getHeight(), bgpaint);
 50
 51         Paint drakpaint = new Paint();
 52         drakpaint.setColor(Color.WHITE);
 53
 54         Paint whitepaint = new Paint();
 55         whitepaint.setColor(Color.BLACK);
 56
 57         for (int i = 0; i < 9; i++) {
 58             //绘制横向的单元格线
 59             canvas.drawLine(0, i*height, getWidth(), i*height, whitepaint);
 60             canvas.drawLine(0, i*height+1, getWidth(), i*height+1, whitepaint);
 61             //绘制纵向的单元格的线
 62             canvas.drawLine(i*width, 0, i*width, getHeight(), whitepaint);
 63             canvas.drawLine(i*width+1, 0, i*width+1, getHeight(), whitepaint);
 64         }
 65         //绘制横竖各三条分割线
 66         for (int i = 0; i < 9; i++) {
 67             if(i%3!=0)
 68             {
 69                 continue;
 70             }
 71             //绘制横向的单元格线
 72             canvas.drawLine(0, i*height, getWidth(), i*height, drakpaint);
 73             canvas.drawLine(0, i*height+1, getWidth(), i*height+1, drakpaint);
 74             //绘制纵向的单元格的线
 75             canvas.drawLine(i*width, 0, i*width, getHeight(), drakpaint);
 76             canvas.drawLine(i*width+1, 0, i*width+1, getHeight(), drakpaint);
 77         }
 78         //绘制数字
 79         Paint numberpaint = new Paint();
 80         numberpaint.setColor(Color.BLACK);
 81         numberpaint.setStyle(Style.STROKE);
 82         numberpaint.setTextSize((float) (height*0.75));
 83         numberpaint.setTextAlign(Align.CENTER);//居中对齐
 84
 85         FontMetrics fm = numberpaint.getFontMetrics();
 86         float x = width/2;
 87         float y = height/2-(fm.ascent-fm.descent)/2;
 88         // 计算文字高度
 89         float fontHeight = fm.bottom - fm.top;
 90         // 计算文字baseline
 91         float textBaseY = height - (height - fontHeight) / 2 - fm.bottom;
 92         //canvas.drawText("1", 3*width+x, textBaseY, numberpaint);
 93         //绘制数字
 94         for(int i=0;i<9;i++)
 95         {
 96             for(int j=0; j<9;j++)
 97             {
 98                 canvas.drawText(game.getTitlStringe(i,j), i*width+x, j*height+textBaseY, numberpaint);
 99             }
100         }
101         super.onDraw(canvas);
102     }
103     //触摸事件
104     @Override
105     public boolean onTouchEvent(MotionEvent event) {
106         // TODO Auto-generated method stub
107         if(event.getAction()!=MotionEvent.ACTION_DOWN)
108         {
109             return super.onTouchEvent(event);
110         }
111
112         //得到点击位置的x,y坐标
113          selectx = (int) (event.getX()/width);
114          selecty = (int) (event.getY()/height);
115
116         int used[] = game.getused(selectx,selecty);
117         StringBuffer strbuf = new StringBuffer();
118         for(int i=0;i<used.length;i++)
119         {
120             strbuf.append(used[i]+"、");
121         }
122
123
124         SelectDialog seldia = new SelectDialog(getContext(),used,this);
125         seldia.show();
126         return true;
127
128     }
129
130     //View类接受KeyDialog传递过来的数据,调用业务逻辑Game类,进行处理
131     public void setSelectTile(int tile)
132     {
133         if(game.setTileIfValid(selectx,selecty,tile))
134         {
135             invalidate();//重新绘制View对象
136         }
137     }
138 }

二、Game.java 用于处理数独数据

  1 package xqx.shudu;
  2
  3 public class Game {
  4     //数独数据初始化
  5     private final String str = "360000000" +
  6                                "004230800" +
  7                                "000004200" +
  8                                "070460003" +
  9                                "820000014" +
 10                                "500013020" +
 11                                "001900000" +
 12                                "007048300" +
 13                                "000000045";
 14     private int shuduku[]=new int[9*9];
 15     //用来存储每个单元格不可填写的数字
 16     //1维 x坐标 2维 y坐标 3维 不可填写数字
 17     private int used[][][]=new int[9][9][];
 18     public Game(){
 19         shuduku = fromPuzzleString(str);
 20         calAllused();
 21     }
 22
 23     //根据字符串数据生成整型数组
 24     public int[] fromPuzzleString(String str2) {
 25         // TODO Auto-generated method stub
 26         int shudu[] = new int[str2.length()];
 27         for(int i=0;i<shudu.length;i++)
 28         {
 29             shudu[i]=str2.charAt(i)-‘0‘; //吧字符转换为数字
 30         }
 31         return shudu;
 32     }
 33
 34     //根据九宫格坐标返回该坐标所应该填写的数字
 35     public int getTitile(int x,int y){
 36         return shuduku[y*9+x];
 37     }
 38
 39     public String getTitlStringe(int x,int y){
 40         int v = getTitile(x, y);
 41         if(v==0){
 42             return "";
 43         }
 44         else
 45         {
 46             return String.valueOf(v);
 47         }
 48     }
 49
 50     //计算某单元格已经不可填写的数字
 51     public int[] calUsed(int x,int y){
 52         int c[]= new int[9];
 53
 54         //判断y这一列,如果遍历他自己 ,跳过,如果遍历单元格数字不为0,则放入数组中
 55         for(int i=0;i<9;i++)
 56         {
 57             if(i==y)
 58                 continue;
 59             int t = getTitile(x, i);
 60             if(t!=0)
 61                 c[t-1]=t;
 62         }
 63         //判断x这一行,如果遍历他自己 ,跳过,如果遍历单元格数字不为0,则放入数组中
 64         for(int i=0;i<9;i++)
 65         {
 66             if(i==x)
 67                 continue;
 68             int t = getTitile(i, y);
 69             if(t!=0)
 70                 c[t-1]=t;
 71         }
 72         //判断该单元格所在的九宫格出现的数字并放入不可填写数字数组当中
 73         int startx = (x/3)*3;
 74         int starty = (y/3)*3;
 75         for(int i=startx;i<startx+3;i++)
 76         {
 77             for(int j=starty;j<starty+3;j++)
 78             {
 79                 if(i==x&&j==y)
 80                     continue;
 81                 int t = getTitile(i, j);
 82                 if(t!=0)
 83                 {
 84                     c[t-1]=t;
 85                 }
 86             }
 87         }
 88
 89         int nused = 0;
 90         for(int t:c){
 91             if(t!=0)
 92                 nused++;
 93         }
 94         int c1[] = new int[nused];
 95         nused=0;
 96         for(int t:c){
 97             if(t!=0)
 98             {
 99                 c1[nused++]=t;
100             }
101         }
102
103         return c;
104     }
105
106     //计算所有单元格不可用数字数组
107     public void calAllused(){
108         for(int x=0;x<9;x++)
109         {
110             for(int y=0;y<9;y++){
111                 used[x][y]=calUsed(x, y);
112             }
113         }
114     }
115
116     //得到该单元格不可用数字
117     public int[] getused(int x,int y){
118         return used[x][y];
119     }
120      //接收KeyDialog中点击的数字
121     public boolean setTileIfValid(int x, int y, int value)
122     {
123         int[] tiles = getused(x, y);//得到不可用的数据
124
125
126         if (value != 0)
127         {
128             for (int t : tiles)
129             {
130                 if (t == value)
131                     return false;
132             }
133         }
134         setSelectNum(x, y, value);//将对应的值value绘制在xy对应的格子中
135         calAllused();//重新计算所有格子的不可用数据
136
137         return true;
138     }
139
140     //在数独数组中更改填写后的数字
141     private void setSelectNum(int x, int y, int num) {
142         // TODO Auto-generated method stub
143         shuduku[y*9+x]=num;
144     }
145 }
146                             

三、SelectDialog.java  用于设置填写数字的对话框

 1 package xqx.shudu;
 2
 3 import myview.ShuduView;
 4 import android.app.Dialog;
 5 import android.content.Context;
 6 import android.os.Bundle;
 7 import android.view.View;
 8 import android.widget.Toast;
 9
10 public class SelectDialog extends Dialog{
11     int q;
12     //当dialog第一次显示时会调用其onCreate方法
13     //用来存放对话框中按钮对象
14     private ShuduView shuduview;
15     private  View key[] = new View[9];
16     private  int used[];
17     public SelectDialog(Context context, int used[],ShuduView shuduview) {
18
19
20         super(context);
21         this.used=used;
22         this.shuduview = shuduview;
23         // TODO Auto-generated constructor stub
24     }
25
26     @Override
27     protected void onCreate(Bundle savedInstanceState) {
28         // TODO Auto-generated method stub
29         super.onCreate(savedInstanceState);
30         setTitle("选择填入的数字");
31         setContentView(R.layout.shudu_diolag);//设置布局文件
32         findView();
33
34         for(int i=0;i<used.length;i++)
35         {
36             if(used[i]!=0)
37             {
38                 key[used[i]-1].setVisibility(View.INVISIBLE);
39             }
40         }
41         //为对话框中所有内容设置监听器
42         setListener();
43     }
44
45     //为按钮设置监听器
46         public void setListener()
47         {
48             for(int i = 0; i<key.length; i++)
49             {
50                 final int t = i+1;
51                 key[i].setOnClickListener(new View.OnClickListener()
52                 {
53
54                     @Override
55                     public void onClick(View v)
56                     {
57                         // TODO Auto-generated method stub
58                         returnResult(t);
59                     }
60                 });
61             }
62         }
63
64         //对话框将选择的数据传递给View对象,让其处理业务逻辑
65         public void returnResult(int tile)
66         {
67             shuduview.setSelectTile(tile);
68             dismiss();
69         }
70
71
72     private void findView() {
73         // TODO Auto-generated method stub
74         key[0] = findViewById(R.id.btn_1);
75         key[1] = findViewById(R.id.btn_2);
76         key[2] = findViewById(R.id.btn_3);
77         key[3] = findViewById(R.id.btn_4);
78         key[4] = findViewById(R.id.btn_5);
79         key[5] = findViewById(R.id.btn_6);
80         key[6] = findViewById(R.id.btn_7);
81         key[7] = findViewById(R.id.btn_8);
82         key[8] = findViewById(R.id.btn_9);
83     }
84 }

四、MainActivty.java 在主类中调用MyView对象

 1 package xqx.shudu;
 2 import myview.*;
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.view.Menu;
 6
 7 public class MainActivity extends Activity {
 8
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(new ShuduView(this));
13 //        setContentView(R.layout.activity_main);
14     }
15
16
17     @Override
18     public boolean onCreateOptionsMenu(Menu menu) {
19         // Inflate the menu; this adds items to the action bar if it is present.
20         getMenuInflater().inflate(R.menu.main, menu);
21         return true;
22     }
23
24 }

五:布局文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:layout_gravity="center_horizontal"
 6     android:stretchColumns="*"
 7     android:orientation="vertical" >
 8
 9     <TableRow >
10         <Button android:id="@+id/btn_1"
11             android:text="1"/>
12         <Button android:id="@+id/btn_2"
13             android:text="2"/>
14         <Button android:id="@+id/btn_3"
15             android:text="3"/>
16     </TableRow>
17     <TableRow >
18         <Button android:id="@+id/btn_4"
19             android:text="4"/>
20         <Button android:id="@+id/btn_5"
21             android:text="5"/>
22         <Button android:id="@+id/btn_6"
23             android:text="6"/>
24     </TableRow>
25     <TableRow >
26         <Button android:id="@+id/btn_7"
27             android:text="7"/>
28         <Button android:id="@+id/btn_8"
29             android:text="8"/>
30         <Button android:id="@+id/btn_9"
31             android:text="9"/>
32     </TableRow>
33
34     <Button
35         android:id="@+id/btn_cannel"
36         android:layout_width="wrap_content"
37         android:layout_height="wrap_content"
38         android:text="取消" />
39
40 </TableLayout>

效果图:

时间: 2024-10-10 23:50:37

安卓开发_数独游戏基础的相关文章

安卓开发_数独游戏基础(二)

老师视频教程结束了,但是游戏并未完成.下面便开始自己动手完善部分功能 需要完善的功能: 1.设置给定的数独数据数字不可改变 2.设置给定的数独数据数字和玩家填入的数字颜色不同,方便区分 3.判断填写后的数独是否符合数独游戏规则 解决方法: 1.设置给定的数独数据数字不可改变 我的思路,因为给定的数据数字是给定的,而数据是放在一个字符串里的,如下:0代表需要玩家输入的,非0则是给定的 1 private final String str = "061030020050008107000007034

安卓开发_慕课网_百度地图_添加覆盖物

学习内容来自“慕课网” 本片学习内容接自前四篇基础 安卓开发_慕课网_百度地图 安卓开发_慕课网_百度地图_实现定位 安卓开发_慕课网_百度地图_实现方向传感器 安卓开发_慕课网_百度地图_实现模式转换 请先学习前4篇再学习本篇,因为本篇在前四篇的基础上进行代码的编写 一.新建一个类用来存放数据(距离,点赞数,介绍图等信息) 1 package com.example.map; 2 3 import java.io.Serializable; 4 import java.util.ArrayLi

安卓开发_慕课网_百度地图_实现方向传感器

学习内容来自“慕课网” 这里学习百度地图方向传感器功能 就是当转动手机的时候,地图上显示个人所在位置的图标的箭头变动 学习接自前两篇 安卓开发_慕课网_百度地图 安卓开发_慕课网_百度地图_实现定位 思路: 传感器随着定位的开始而开启,随着定位的结束而结束 传感器获得位置的移动而更新方向 代码在前两篇的基础上修改 一.讲原本坐标的图标改成箭头图标 二.引入方向传感器 首先增添MainActivity.java中的自定义图标和方向传感器代码 看红色字体的部分 1 package com.examp

安卓开发_数据存储技术_sqlite

一.SQLite SQLite第一个Alpha版本诞生于2000年5月,它是一款轻量级数据库,它的设计目标是嵌入式的,占用资源非常的低,只需要几百K的内存就够了.SQLite已经被多种软件和产品使用 二.SQLite特性 1 2 1.轻量级 3 SQLite和C\S模式的数据库软件不同,它是进程内的数据库引擎,因此不存在数据库的客户端和服务器.使用SQLite一般只需要带上它的一个动态库,就可以享受它的全部功能.而且那个动态库的尺寸也相当小. 4 2.独立性 5 SQLite数据库的核心引擎本身

安卓开发_浅谈ListView(自定义适配器)

ListView作为一个实际开发中使用率非常高的视图,一般的系统自带的适配器都无法满足开发中的需求,这时候就需要开发人员来自定义适配器使得ListView能够有一个不错的显示效果 有这样一个Demo ,实现图片文字混合列表 1 package com.example.work; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.List; 6 7 8 import android.R.in

安卓开发_浅谈Android动画(四)

Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1.  ValueAnimator 基本属性动画类 方法 描述 setDuration(long duration) 设置动画持续时间的方法 setEvaluator(TypeEvaluator value) 设置插值计算的类型 setInterpolator(TimeInterpolator value) 设置时间插值器的类型 addUp

安卓开发_慕课网_百度地图_实现模式转换

学习内容来自“慕课网” 模式转换,即地图的普通模式,罗盘模式,跟随模式之间的转换 学习内容接自前三篇 安卓开发_慕课网_百度地图 安卓开发_慕课网_百度地图_实现定位 安卓开发_慕课网_百度地图_实现方向传感器 一.模式转换通过菜单按钮来控制 所以添加对应的菜单项(红色字体部分) 1 <menu xmlns:android="http://schemas.android.com/apk/res/android" > 2 3 <item 4 android:id=&qu

安卓开发_深入理解Content Provider

一.Content Provider概述 Content Provider用于保存和获取数据,并使其对所有应用程序可见,这是不同应用程序之间共享数据的唯一方式,因为在Android中没有提供所有应用可以共同访问的公共存储区域 1.  Content Provider内部的数据如何保存是由其设计者决定的,而所有的的Content Provider都实现一组通用的方法,用来提供数据的增删改查操作 2.  客户端如果要使用这些操作方法,可以通过ContentProvider对象实现对 Content

安卓开发_单选按钮控件(RadioButton)的简单使用

最近复习安卓基础的时候发现没有写关于单选按钮.复选按钮的博客,可能因为以前学习的时候感觉太简单了就没有写,现在补上吧 当我们在各种客户端注册账号的时候,会有几项单选项,比如选择您的性别.下面就是学习怎么实现这种效果 一.安卓中,单选按钮用RadioButton表示,因为RadioButton是Button的子类,所以可以使用Button的各种属性 RadioButton一般是不单独使用的需要结合RadioGroup控件一起使用,将若干个RadioButton放在一个RadioGroup中,那么将