<数独游戏>之绘制九宫格,并初始化数据
1.在工程里的res/values目录下新建一个colors.xml来存放具体颜色值,已供程序通过R.color.颜色名 来调用
this.getResources().getColor(R.color.shudu_background) 获取配置文件中的颜色值
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="shudu_background">#ffe6f0ff</color>
<color name="shudu_hilite">#ffffffff</color>
<color name="shudu_light">#64c6d4ef</color>
<color name="shudu_dark">#6456648f</color>
</resources>
2.新建一个自定义图形类ShuduView继承View父类
package com.shudu; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.view.View; public class ShuduView extends View { //单元格的宽度和高度 private float width ; private float height ; private Game game = new Game(); public ShuduView(Context context) { super(context); } //涉及到手机屏幕的切换问题比如 横屏 和竖屏,需要进行调整 w:整个 veiw 的宽度; h:整个 veiw 的高度 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { // TODO Auto-generated method stub //把整个屏幕分成 九宫格 的每个格子的宽度和高度 this.width = w/9f ; this.height = h/9f ; super.onSizeChanged(w, h, oldw, oldh); } @Override public void onDraw(Canvas canvas) { Paint backgroundPaint = new Paint(); //从配置文件中 获取颜色值 backgroundPaint.setColor(this.getResources().getColor(R.color.shudu_background)); //画出整个手机屏幕的 的背景色 canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), backgroundPaint); //---------------------------------------- Paint darkPaint = new Paint(); darkPaint.setColor(this.getResources().getColor(R.color.shudu_dark)); Paint hilitePaint = new Paint(); hilitePaint.setColor(this.getResources().getColor(R.color.shudu_hilite)); Paint lightPaint = new Paint(); lightPaint.setColor(this.getResources().getColor(R.color.shudu_light)); //画九宫格里面的 横线,纵线,每次画出的线要想达到某种效果,需画两条 之间格1像素的位置,且颜色也要搭配好 for(int i = 0 ; i < 9 ; i++ ) { canvas.drawLine(0, i*height, this.getWidth(), i*height, lightPaint); canvas.drawLine(0, i*height+1, this.getWidth(), i*height+1, hilitePaint); canvas.drawLine(i*width,0, i*width, this.getHeight(), lightPaint); canvas.drawLine(i*width+1,0, i*width+1, this.getHeight(), hilitePaint); } //把整个 屏幕的格子 分成9个大的 9 宫格,每个大的9宫格 里面又有9个小格, 实际上就是 用颜色比较深的线隔开 for(int i = 0 ; i < 9 ; i ++) { if(i%3 != 0) { continue ; } canvas.drawLine(0, i*height, this.getWidth(), i*height, darkPaint); canvas.drawLine(0, i*height+1, this.getWidth(), i*height+1, hilitePaint); canvas.drawLine(i*width,0, i*width, this.getHeight(), darkPaint); canvas.drawLine(i*width+1,0, i*width+1, this.getHeight(), hilitePaint); } //设置在表格上显示的数字 Paint numberPaint = new Paint(); numberPaint.setColor(Color.BLACK); numberPaint.setStyle(Paint.Style.STROKE); //让其画出来的东西是 空的 numberPaint.setTextSize(height*0.75f); //设置字体大小 numberPaint.setTextAlign(Paint.Align.CENTER); //让字体居中 float x = width/2f ; //调整字体的位置 ( 度量) 比如居中,调整垂直方向上的居中 FontMetrics fm = numberPaint.getFontMetrics(); // 这些 fm.ascent 都是基于 基准线 而言 float y = height/2f - (fm.ascent+fm.descent)/2 ; //System.out.println("y:"+y+"fm.ascent:"+fm.ascent+"fm.descent:"+fm.descent); //初始化数据 for(int i = 0 ; i < 9 ; i ++) { for(int j = 0 ; j < 9 ; j ++) { canvas.drawText(game.getTileString(i, j), i*width+x,j*height+y , numberPaint); } } super.onDraw(canvas); } }
1)画九宫格里面的 横线,纵线,每次画出的线要想达到某种效果,需画两条 之间格1像素的位置,且颜色也要搭配好
2)要想让字在单元格中居中,这是一个问题,得设置一下偏移量
X轴方向:比较好设置,就是单元格宽度除以2 , float x = width/2f ;
Y轴方向:并不是通过单元格高度除以2,因为涉及到基准线的概念,通过画笔对象调用 getFontMetrics() 方法,获取FontMetrics 对象,也就是获取了 ascent,top,descent,bottom 等属性,四个属性的值都是基于基准线而言
公式:float y = height/2f - (fm.ascent+fm.descent)/2 ; 通过单元格高度除以2,加上(ascent的高度减去descent)除以2
之所以上面的公式中出现减号,是因为 基准线的上方 是负数,
3.Game类,存放一些初始化的数据等等
package com.shudu; public class Game { //初始化 九宫格的数据 private final String initStr = "360000000004230800000004200"+ "070460003820000014500013020"+ "001900000007048300000000045"; //定义一个 数组 存放 初始化数据,首先 要将 initStr里面的数据分离开,存放在数组里 private int[] shuduku = new int[9*9] ; public Game() { shuduku = fromPuzzleString(initStr) ; } //通过传来的坐标值,获取 该坐标 的 具体值(整数) private int getTile(int x , int y) { return shuduku[y*9+x] ; } public String getTileString(int x , int y) { int v = getTile(x , y); if(0 == v) return "" ; else return String.valueOf(v); //把获取的 整数 转成 字符串 } //把字符串 一个个分离出来,存放至 shudu数组中,通过返回值,赋值给 shuduku数组中 public int[] fromPuzzleString(String str) { int[] shudu = new int[str.length()] ; for(int i = 0 ; i < str.length() ; i++) { shudu[i] = str.charAt(i) - '0' ; //把获取的单个字符减去 '0' 转成整数,赋给 整形 shudu数组中 } return shudu ; } }
4.Activty类
package com.shudu; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new ShuduView(this)); } }
5.运行效果: