Android开发——手把手写APP(四)——数独游戏编写(六)——进行游戏的功能优化

进行游戏的功能优化


优化数字键盘

出现的问题:
1.数字键盘里没有删除键,这就很尴尬了,选上了不能去掉。
2.按钮丑陋

给按钮设置drawablebackground,使之美化

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#980729"/>
            <stroke android:width="1px"
                android:color="#cf1116"/>
            <padding android:top="1px"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffffff"/>
            <stroke android:width="1px"
                android:color="#cfcfd2"/>
            <padding android:top="1px"/>
        </shape>
    </item>
</selector>

添加删除按钮,并能够实现点击之后删除的操作。
说白了,就是跟上一文差不多,点击删除键后,把该单元格的数独数组数据设为0,并重绘画布即可。
dialog里:

//删除按钮的监听器
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调用shuduView的setDeleteTile方法
                shuduView.setDeleteTile();
            }
        });

shuduView里:

//删除用户所选数字
    public void setDeleteTile() {

        game.deleteTile(selectedX,selectedY);
        //重绘整个画布
        invalidate();
    }

game里:

//删除数独数组的一个数据
    public void deleteTile(int selectedX, int selectedY) {
        //该单元格设置为0
        setTile(selectedX,selectedY,0);
        //重新计算各个单元格的不可用数据
        calculateAllUsedTiles();
    }

在这里插入图片描述

优化所选数字颜色

问题:全部的数字在九宫格上都是黑色,不能区分哪个是原有的,哪个是自己填的。
解决办法:分别用不同的画笔画出固有数字和后填数字,把固有数字单独存储。
这就比较麻烦了,需要把数独数据分为三个模块,第一,初始数独数据,永远不变;第二,玩家所选数独数据,初始全为0,玩家添加和删除时更新此数组;第三,初始 + 玩家所选 = 全部数据,这个用于每个单元格不可用数据的计算。
可能这个方面听起来比较楞,慢慢理解一下,重绘是重新调用onDraw绘制全图,所有要把初始和所选分开,但是计算不可用又需要整合。
下面是三个数独数组成员变量

    /**
     * 写了三个sudoku数组,可能难理解,介于要给玩家所选数组更替颜色,所以需要把初始数据和玩家所选数据分离,
     * 但是这两个用于界面的更新,不涉及的计算不可用数据,计算不可用数据需要它俩的结合,这个结合只涉及到逻辑计算,不涉及到界面,
     * 因此产生了三个数组。
     */
    //数独初始数据的存储
    protected int sudoku [] = new int [9 * 9];
    //数独玩家所选数据的存储
    protected int sudoku1 [] = new int [9 * 9];
    //数独全部数据的存储 初始+所选
    protected int sudoku2 [] = new int [9 * 9];

其中简单说一下
1.在onDraw调用数据时,第一步,调用原有数独的值,设置黑色画笔,第二步,调用玩家所选数独值,设置蓝色画笔。
2.在玩家点击数字按钮进行选择数字时,把game的添加数据方法设置为玩家所选数独 & 全部数独 都增加进去
3.计算不可用数据时,调用的是 全部数独
在这里插入图片描述

光这么说很难理解,具体的可以参考我的源码文件,最下面

扫描二维码关注公众号,回复: 8611582 查看本文章

不可点击初始数据

问题:游戏竟然能点击初始生成的数据,并能修改它,天大的bug…
解决办法:判断所点击位置的初始数独是否为0,为0方可弹出数字键盘,不为0,则是初始数据,不弹出键盘。

//如果点击的不是初始数独的数据
        if(game.sudoku[selectedY * 9 + selectedX] == 0){
            //获取点击格子不可用数据
            int used[] = game.getUsedTiles(selectedX,selectedY);

            StringBuffer stringBuffer = new StringBuffer();
            //输出不可用数据
            for(int i = 0;i < used.length;i++){
                stringBuffer.append(used[i]);
            }

            KeyDialog keyDialog = new KeyDialog(getContext(),used,this);
            keyDialog.show();
        }

优化通关结果

问题:如果数独完成了,会出现什么结果?没结果
解决办法:当全部数独数组中没有0值时,则判断为数独填满,弹出一个对话框,告诉玩家,已经通关。判断是否通关位置:在玩家点击数字按钮时调用。

但是…小编玩了半天没通关!!!哈哈哈哈哈!!不会玩这个东西,总是会数字卡死,没数字选了,尴尬,这个代码是写好了的,可惜效果图显示不了了

核心代码很简单,首先布局文件,就大概这个样子
在这里插入图片描述
然后自定义passGameDialog类,获取这个布局文件,并为确定按钮设置监听,监听内容是点击之后触发让对话框消失的事件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("提示");
        //设置布局
        setContentView(R.layout.pass);

        //点击确定按钮,对话框消失
        button = findViewById(R.id.btn_passGame);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });
    }

game类写一个判断是否完整的方法
也很简答,检测 数独数组 中是否存在0,有0则没满,未完成

    //通关判断 全部数独 中有无0,来判断这个数独是否完成
    public boolean ifPassGame(){
        for(int i = 0;i < 9;i++){
            for(int j = 0; j < 9;j++){
                if(sudoku2[j * 9 + i] == 0)
                    return false;
            }
        }
        return true;
    }

shuduView中,在用户按下数字键盘时调用这个方法

//设置用户所选的数字,用户按下数字键盘时调用
    public void setSelectedTile(int tile) {
        if(game.setTileIfValid(selectedX,selectedY,tile)){
            //重绘整个画布
            invalidate();
            //判断游戏是否通关,如果通关则显示通关的dialog
            if(game.ifPassGame()){
                PassGameDialog passGameDialog = new PassGameDialog(getContext());
                passGameDialog.show();
            }
        }
    }

因为博主通不了关…所以发布了blink请CSDN上的朋友们帮忙做,感谢好心人把答案发给了我!
在这里插入图片描述
好了,最后,照常附上源码,里面有详细备注。

链接:https://pan.baidu.com/s/1TivpTlvVbaWlxR-j7vOaOQ

提取码:sw5p

在这里插入图片描述

发布了230 篇原创文章 · 获赞 250 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/weixin_42247720/article/details/103518348