出现的问题:
1.数字键盘里没有删除键,这就很尴尬了,选上了不能去掉。
2.按钮丑陋
给按钮设置drawable
的background
,使之美化
<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.计算不可用数据时,调用的是 全部数独
光这么说很难理解,具体的可以参考我的源码文件,最下面
问题:游戏竟然能点击初始生成的数据,并能修改它,天大的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