数独游戏(1)之绘制九宫格,并初始化数据

<数独游戏>之绘制九宫格,并初始化数据

 

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

之所以上面的公式中出现减号,是因为 基准线的上方 是负数,

《数独游戏(1)之绘制九宫格,并初始化数据》

 

 

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.运行效果

《数独游戏(1)之绘制九宫格,并初始化数据》

 

 

 

    原文作者:九宫格问题
    原文地址: https://blog.csdn.net/hzc543806053/article/details/7675126
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞