Android 游戏开发之 数独游戏

       数独游戏(日语:数独 すうどく)是一种源自18世纪末的瑞士的游戏,后在美国发展、并在日本得以发扬光大的数学智力拼图游戏。在每一个小九宫格中,分别填上1至9的数字,让整个大九宫格每一列、每一行的数字都不重复。 数独的玩法逻辑简单,数字排列方式千变万化,是锻炼脑筋的好方法。

      本文实现简单的数独游戏,通过mars的视频教程完成编程

1.自定义View:

package com.example.administrator.shudugame;

/**
 * Created by Administrator on 2016/9/19.
 */

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View{

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    //方格长宽
    float width;
    float height;
    //选定的坐标
    int selectX;
    int selectY;
    MyGame mGame=new MyGame();

    //获得屏幕尺寸
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //每一个小格的长宽
        this.width=w/9f;
        this.height=h/9f*2/3;
    }


    //绘图函数
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景
        Paint bgPaint=new Paint();
        bgPaint.setColor(getResources().getColor(R.color.bg));
        canvas.drawRect(0,0,getWidth(),getHeight()*2/3f, bgPaint);
        //线条画笔
        Paint darkPaint =new Paint();
        darkPaint.setColor(getResources().getColor(R.color.dark));
        Paint hilitePaint =new Paint();
        hilitePaint.setColor(getResources().getColor(R.color.hilite));
        Paint lightPaint =new Paint();
        lightPaint.setColor(getResources().getColor(R.color.light));
        //绘制线条
        for(int i=0;i<9;i++){
            canvas.drawLine(0, i*height,getWidth(),i*height,lightPaint);
            canvas.drawLine(0, i*height+1,getWidth(),i*height+1,hilitePaint);
            canvas.drawLine(i*width, 0,i*width,getWidth()+width*0.4f,lightPaint);
            canvas.drawLine(i*width+1,0,i*width+1,getWidth()+width*0.4f,hilitePaint);
            if(i%3==0){
                canvas.drawLine(0, i*height,getWidth(),i*height,darkPaint);
                canvas.drawLine(0, i*height+3,getWidth(),i*height+3,hilitePaint);
                canvas.drawLine(i*width, 0,i*width,getWidth()+width*0.4f,darkPaint);
                canvas.drawLine(i*width+3, 0,i*width+3,getWidth()+width*0.4f,hilitePaint);
            }
        }
        //绘制数字
        Paint numberPaint =new Paint();
        numberPaint.setColor(Color.BLACK);
        numberPaint.setStyle(Paint.Style.STROKE);
        numberPaint.setTextSize(height*0.75f);
        numberPaint.setTextAlign(Align.CENTER);

        //调节文字居中
        FontMetrics fMetrics=numberPaint.getFontMetrics();
        float x=width/2;
        float y=height/2-(fMetrics.ascent+fMetrics.descent)/2;
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                canvas.drawText(mGame.getNumber(i+1, j+1), i*width+x, y+j*height, numberPaint);
            }
        }

    }
    //触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x=(int)(event.getX()/width);
        int y=(int)(event.getY()/height);
        if(x<=8 && y<=8){  //判断点击的是否是游戏界面
            int []t=mGame.getUsed(x, y);
            selectX=x;
            selectY=y;
            MyDialog mDialog=new MyDialog(getContext(), t, this); //调用自定义Dialog
            mDialog.show();
        }
        return super.onTouchEvent(event);
    }
    public void setTitle(int i){
        mGame.setTitle(i,selectX,selectY);
        invalidate();  //每次填写一个数 都要重新进行绘制
        mGame.youWin();
    }
}
2.新建MyGame类:
package com.example.administrator.shudugame;

import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;

/**
 * Created by Administrator on 2016/9/19.
 */
public class MyGame {

    Context context;
    String data="008309100" +
            "900060004" +
            "007504800" +
            "036000540" +
            "001000600" +
            "042000970" +
            "005907300" +
            "600010008" +
            "004608200";
    int numbers[][] =new int[9][9];
    public MyGame(){
        //初始化data
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                numbers[i][j]=data.charAt(i+j*9)-'0'; //字符转化为整形
            }
    }
    //得到值
    public String getNumber(int x,int y){
        if(numbers[x-1][y-1]==0)
            return "";
        else
            return ""+numbers[x-1][y-1];
    }
    //算出已经被用的数字
    public int[] getUsed(int x,int y){
        int c[]=new int[9];
        //x列
        for(int i=0;i<9;i++)
        {
            if(numbers[x][i]!=0)
            {
                c[numbers[x][i]-1]=numbers[x][i];
            }
        }
        //y排
        for(int i=0;i<9;i++)
        {
            if(numbers[i][y]!=0)
            {
                c[numbers[i][y]-1]=numbers[i][y];
            }
        }
        //小九宫格
        x=(x/3)*3;
        y=(y/3)*3;
        for(int i=0;i<9;i++)
        {
            if(numbers[x+i%3][y+i/3]!=0)
            {
                c[numbers[x+i%3][y+i/3]-1]=numbers[x+i%3][y+i/3];
            }
        }
        return c;
    }
    //设置选定的数字
    public void setTitle(int i,int x,int y){
        numbers[x][y]=i;
    }
    //判断游戏结束
    public void youWin(){
        int t=0;
        for (int i=0;i<9;i++){
            for (int j=0;j<9;j++){
                if (numbers[i][j]!=0){
                     t++;
                }
            }
        }
        if (t==81){
            AlertDialog.Builder builder=new AlertDialog.Builder(context);
            builder.setTitle("Tips")
                    .setMessage("You Win !")
                    .setPositiveButton("Restart", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .setNegativeButton("Exit", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            System.exit(0);
                        }
                    }).show();
        }
    }
}
3.自定义Dialog类:
package com.example.administrator.shudugame;

/**
 * Created by Administrator on 2016/9/19.
 */
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;

public class MyDialog extends Dialog{

    MyView mView;
    View keys[]=new View[9];
    int []used=new int[9];

    //传入已经使用过的数字
    public MyDialog(Context context, int[] useed, MyView m) {
        super(context);
        this.mView=m;
        this.used=useed;

    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置标题
        setTitle("可选数字");
        //设置布局文件
        setContentView(R.layout.table);
        int id[]=new int[]{R.id.bt1,R.id.bt2,R.id.bt3,R.id.bt4,
                R.id.bt5,R.id.bt6,R.id.bt7,R.id.bt8,R.id.bt9};
        for(int i=0;i<9;i++)
        {
            final int t=i+1;
            keys[i]=findViewById(id[i]);
            keys[i].setOnClickListener(new View.OnClickListener() {

                public void onClick(View v) {
                    mView.setTitle(t);
                    dismiss(); //取消对话框
                }
            });
        }
        for(int i=0;i<9;i++)
        {
            if(used[i]!=0)
                keys[used[i]-1].setVisibility(View.INVISIBLE); //将不可使用的数字对应的Button设置为隐藏
        }
    }
}
4.在MainActivity中,在onCreate()方法: 更改:setContentView(R.layout.activity_main); 为 setContentView(new MyView(this,attrs));
5.新建table.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:stretchColumns="*" >

    <TableRow
        android:id="@+id/row1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >




        <Button
            android:id="@+id/bt1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1" />


        <Button
            android:id="@+id/bt2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2" />


        <Button
            android:id="@+id/bt3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3" />

    </TableRow>


    <TableRow
        android:id="@+id/row2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >



        <Button
            android:id="@+id/bt4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="4" />



        <Button
            android:id="@+id/bt5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5" />



        <Button
            android:id="@+id/bt6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="6" />

    </TableRow>


    <TableRow
        android:id="@+id/row3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >



        <Button
            android:id="@+id/bt7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="7" />



        <Button
            android:id="@+id/bt8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="8" />



        <Button
            android:id="@+id/bt9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="9" />

    </TableRow>

</TableLayout>
6.结果展示:
                             

 
 
 

  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值