文章目录

  • 一、项目概述
  • 二、开发环境
  • 三、详细设计
    • 3.1 界面设计
    • 3.2 逻辑设计
  • 四、运行演示
  • 五、源码获取

一、项目概述

数独是一种逻辑解谜游戏,它规则稍复杂,解题过程富有挑战性。本次安卓数独小游戏,主页面有继续游戏、新游戏、关于和退出四个功能,下拉菜单有设置选项。新游戏可以选择简单、中等和困难3个模式,进入游戏后可以随时退出,然后点继续游戏就能回到上一次的游戏状态。关于是对数独游戏的规则介绍,在设置中可以开启或者关闭背景音乐,开启或关闭游戏提示。游戏界面,每个3x3的方块区域都被实线给分隔开,方便玩家观察填入数字。

涉及知识点:AlertDialog、KeyEvent、MediaPlayer、Canvas、Paint、Parcelable、Fragment、Menu、PreferenceManager、Bundle

二、开发环境

开发环境依旧是3.6.1,属于2020年的版本,基本上大家都满足版本要求。

三、详细设计

3.1 界面设计

1、关于界面,非常简单,描述游戏规则只需要TextView即可。

2、键盘界面,一共3行,每行3列。用到3个TableRow控件,每个TableRow包含3个Button,在输入数字时候会作为对话框弹出。核心代码是button的style。

// 设置主界面的button的样式<style name="number_button"><item name="android:layout_width">0dp</item><item name="android:layout_weight">1.0</item><item name="android:layout_height">40dp</item><item name="android:layout_margin">3dp</item><item name="android:textSize">30sp</item><item name="android:background">@drawable/select_number_click</item><item name="android:textColor">#fff</item></style>

3、主界面,其实设计也不难,主要是四个垂直排列的Button,主要内容还是在background中,solid的颜色为渐变色,stroke的宽度为1dp,color是灰色,radius是50dp,弧形半径非常明显,padding为2dp,有内边距视觉效果更好,最后根据state_pressed变色。

3.2 逻辑设计

1、背景音乐,直接定义一个类,定义play方法,创建MediaPlayer对象,播放传参resource,setLooping设为true就是循环播放。代码如下:

public class Music {private static MediaPlayer mp = null;// stop old song and start a new songpublic static void play(Context context, int resource){stop(context);if(Settings.getMusic(context)){mp = MediaPlayer.create(context, resource);mp.setLooping(true);mp.start();}}// stop the musicpublic static void stop(Context context) {if(mp != null){mp.stop();mp.release();mp = null;}}
}

在应用启动时开始播放音乐,退出时停止播放。

 @Overrideprotected void onResume() {super.onResume();// 程序开始时,调用music activity开始播放音乐Music.play(this, R.raw.nothing_to_lose);}@Overrideprotected void onPause() {super.onPause();// 程序暂停或退出时,停止播放音乐Music.stop(this);}

2、小键盘,绑定每个数字按钮,设置监听器,在显示键盘前会进行逻辑判断,只显示可以填入该方块内的数字,其余数字不显示。

// 为小键盘设置监听函数
private void setListeners(){for(int i = 0; i < keys.length; i++){final int t = i + 1;keys[i].setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {returnResult(t);}});}keypad.setOnClickListener(new View.OnClickListener() {public void onClick(View arg0) {returnResult(0);}});
}
// 返回结果函数
private void returnResult(int tile) {// 绘制用户选择的数字puzzleView.setSelectedTile(tile);dismiss();
}

在PuzzleView类中,有显示软键盘和手机屏幕点击事件的处理方法,该方法处理三种情况的事件:屏幕被按下时,屏幕被抬起时,屏幕中拖动,根据触摸位置的坐标选中对应区域的按钮。

 @Overridepublic boolean onTouchEvent(MotionEvent event) {// 参数event为手机屏幕触摸事件封装类的对象,其中封装了该事件的所有信息,// 例如触摸的位置、触摸的类型以及触摸的时间等。该对象会在用户触摸手机屏幕时被创建。// 该方法处理三种情况的事件:屏幕被按下时,屏幕被抬起时,屏幕中拖动if(event.getAction() != MotionEvent.ACTION_DOWN)//如果屏幕没有被按下return super.onTouchEvent(event);select((int)(event.getX()/width),(int)(event.getY()/height));game.showKeypadOrError(selX, selY);Log.d(TAG, "onTouchEvent:x"+selX+",y"+selY);return true;}

3、PuzzleView是用来绘制游戏界面,当前活动主窗口大小改变时调用onSizeChanged,获取width和height,然后分成一共9x9个小方块。

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {// 计算单元格的宽和高(横向是宽度,纵向是高度)width = w / 9f;height = h / 9f;getRect(selX, selY, selRect);Log.d(TAG, "onSizeChanged:width" + width + ",height" + height);super.onSizeChanged(w, h, oldw, oldh);
}

创建画笔对象,绘制数字,设置字体颜色,设置字体大小和对齐方式,定义了字体规格对象,该对象封装了有关在特定屏幕上呈现特定字体的信息。再创建选择的对象的画笔,按下变色的颜色,根据每个单元格可填的数目给出不同颜色的提示。

   // draw numbers 绘制数字Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);// 生成画数字的画笔foreground.setColor(getResources().getColor(R.color.puzzle_foreground));// 设置字体颜色foreground.setStyle(Style.FILL);foreground.setTextSize(height * 0.75f);foreground.setTextScaleX(width / height);foreground.setTextAlign(Paint.Align.CENTER);// 设置数字在框内的布局 居中对齐// draw num in the center of the tileFontMetrics fm = foreground.getFontMetrics();// 定义了字体规格对象,该对象封装了有关在特定屏幕上呈现特定字体的信息。float x = width / 2;float y = height / 2 - (fm.ascent + fm.descent) / 2;// 横竖都居中// Ascent: 字符顶部到baseLine的距离。// Descent: 字符底部到baseLine的距离。for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {canvas.drawText(this.game.getTitleString(i, j), i * width + x,j * height + y, foreground);// 画数字}}// draw the selectionLog.e(TAG, "selRect=" + selRect);Paint selected = new Paint();// 生成选择的对象的画笔 按下变色的颜色selected.setColor(getResources().getColor(R.color.puzzle_selected));canvas.drawRect(selRect, selected);// draw the hints pick a hint color based on moves left// 根据每个单元格可填的数目给出不同颜色的提示if(Settings.getHints(getContext())){Paint hint=new Paint();int c[] = {getResources().getColor(R.color.puzzle_hint_0),// 表示目前填入不合适  需要从新填入getResources().getColor(R.color.puzzle_hint_1),// 表示只有一个数字可以填入getResources().getColor(R.color.puzzle_hint_2),// 不同颜色的提醒  表示有两个数字可以填入};Rect r = new Rect();for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {int movesleft = 9 - game.getUsedTiles(i, j).length;if(movesleft < c.length){getRect(i, j, r);hint.setColor(c[movesleft]);canvas.drawRect(r, hint);}}}}

4、Game是游戏类,主要实现难度的选择,数字的绘制规则,一共三种游戏模式,每一种都是定义好的字符串,0表示当前没有填充数字,0之外表示有,然后遍历字符串,在PuzzleView中调用画笔绘制9x9的网格,并在每个方块中绘制数字,这样数独的界面就绘制好了。然后选中某一个方块,就会调用小键盘进行输入。

   // 获取难度 difficulty easy = 0  默认为简单int diff = getIntent().getIntExtra(KEY_DIFFICULTY, DIFFICULTY_EASY);puzzle = getPuzzle(diff);//获取当前数据calculateUsedTiles();//获取当前关的不可用数字数组puzzleView = new PuzzleView(this);//获取画图的对象setContentView(puzzleView);//设置内容画图puzzleView.requestFocus();//画的图,获取焦点// if the activity is restarted ,do a continue next timegetIntent().putExtra(KEY_DIFFICULTY, DIFFICULTY_CONTINUE);

5、游戏状态保存依靠Bundle,实例状态存储在bundle中,保存当前游戏状态,parcelable是序列化的接口,方便处理窗口保存事件。

    @Overrideprotected Parcelable onSaveInstanceState() {// //用户打包需要传输的数据,然后在Binder中传输,用于跨进程传输数据Parcelable p = super.onSaveInstanceState();// 打包状态Log.d(TAG, "onSavedInstanceState");Bundle bundle = new Bundle();bundle.putInt(SELX, selX);bundle.putInt(SELY, selY);// 保存当前的坐标bundle.putParcelable(VIEW_STATE, p);// 保存当前的状态,用bundle传输return bundle;}

恢复已经保存的信息,只需要从Bundle里面取出来保存的坐标即可。

    @Overrideprotected void onRestoreInstanceState(Parcelable state) {// 处理窗口还原事件Log.d(TAG, "onRestoreInstanceState");Bundle bundle = (Bundle) state;select(bundle.getInt(SELX), bundle.getInt(SELY));// 通过bundle对象获取 保存的坐标super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE));// 通过bundle对象获取存放的状态信息return;}

四、运行演示

1、启动应用,进入主界面,有继续、新游戏、关于和退出四大选项,标题栏显示“数独游戏”,右侧是菜单项。

2、点击新游戏,选择游戏难度,分为简单、中等和困难。

3、进入游戏后,可以看到有的小方块已经填有数字,剩下的小方块就是你需要填入数字的。玩家选中的方块是浅绿色,比如左上角第一个方块。游戏提示开启时,当某一个方块能填的数字只有1~2时,方块颜色不同于默认颜色,可以看到下图左上角第一块区域数字8的左右各有1个提示方块。

4、点击任意方块,将弹出键盘,选择填入的数字,当点击下一个方块时,刷新界面。

5、菜单栏进入设置界面,有背景音乐和提示选项,背景音乐如果开启会循环播放。

6、我们关闭提示,则方块没有颜色提示,显示的颜色一致,这是困难模式,没有提示太难了。

7、关于界面介绍了游戏规则。

五、源码获取

关注公众号《萌新加油站》,后台回复:数独,即可获取源码~


Android Studio实现数独小游戏,休闲益智相关推荐

  1. Android Studio实现五子棋小游戏

    项目目录 一.项目概述 二.开发环境 三.详细设计 1.布局设计 2.验证码 3.AI人机 4.背景音乐 四.运行演示 五.项目总结 六.源码获取 一.项目概述 五子棋是一种两人对弈的策略型棋类游戏, ...

  2. Android Studio 抽卡小游戏

    https://download.csdn.net/download/weixin_45609946/86405765 Hello 大家好,此项目是我学习Android时完成的大作业. 首先我来介绍一 ...

  3. 解决一个Android Studio gradle的小问题

    解决一个Android Studio gradle的小问题 参考文章: (1)解决一个Android Studio gradle的小问题 (2)https://www.cnblogs.com/xzha ...

  4. 第50篇 Android Studio实现生命数字游戏(五)计算星座数

    第50篇 Android Studio实现生命数字游戏(五)计算星座数 1.变量说明: 1.1.统计圈数 2.计算命数 2.1.使用的数据 2.2.星座对应日期和数字 2.3.说明 2.4.代码 1. ...

  5. C语言编写数独小游戏

    文章目录 1.前言 2.效果展示 3.代码 1.前言 这次数独小游戏的灵感来源于上次力扣做的题目,解数独.正好利用题目余热写了这一款小小游戏. 感兴趣的可以看看题目,哈哈 2.效果展示 3.代码 #p ...

  6. Android 实现扑克牌动画,Android扑克牌猜点小游戏源码

    Android扑克牌猜点小游戏源码分享. 该游戏是简单的猜点游戏, 1点为正确的点数 点重新开始后进行洗牌 每次牌的顺序不同 Java代码: package com.mrzhu.test0109_pr ...

  7. matlab 版 数独小游戏 GUI界面设计

    近期,由于各种原因,接触到了matlab版的数独小游戏,需要做GUI界面.由于之前本科的时候自己也做过简单的界面涉及,就以为很简单,结果,piapia打脸.数独中的数字是在table中显示的,为了将题 ...

  8. 第52篇 Android Studio实现生命数字游戏(七)ListView与适配器

    第52篇 Android Studio实现生命数字游戏(七)ListView与适配器 1.ListView 1.1.适配界面 1.2.适配器 1.ListView 在布局中直接添加. 没有什么好说明, ...

  9. 第46篇 Android Studio实现生命数字游戏(一)数据分析

    第46篇 Android Studio实现生命数字游戏(一)数据分析 1.数据 1.1.生日 1.2.生日数 1.3.天赋数 1.4.命数 1.5.星座数 2.数字对应的解析 1.数据 数据是在生命数 ...

最新文章

  1. 【转】jqGrid学习之参数
  2. 数据库中的乐观锁与悲观锁详解
  3. C++容器的选择和详细操作方法总结(有自己总结)
  4. C#修改系统环境变量,调用批处理bat
  5. 【dfs】I Like Matrix!
  6. 如何设计一个高可用的运营系统
  7. Codeforces Round #143 (Div. 2) C
  8. Day-5: Python高级特性
  9. XOS 详解1: os_s_xxxx.s
  10. 2D转换中心点transform-origin(CSS3)
  11. [转载] python字符串处理函数汇总
  12. java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的区别
  13. 安装Selenium+Firefox+Firepath+Firebug
  14. SPSS中的数据分析—描述性统计分析【1】
  15. 网络端口号和协议号(大全)
  16. 微信小程序点播音频服务器,微信小程序无法播放本地音频
  17. tbslog乱码转换_tbslog乱码转换
  18. 【UI设计】扁平化设计之流行色值
  19. 使用xshell连接腾讯云服务器
  20. Bootstrap 新手学习手册---环境部署与网格系统

热门文章

  1. 秒懂FPGA、单片机、DSP、ASIC的区别
  2. 微信代码错误:40164,加入白名单仍不起作用。
  3. tensorflow 学习笔记使用CNN做英文文本分类任务
  4. 016.从中序与后序遍历序列构造二叉树
  5. 什么是GRAY色彩空间
  6. php删除头尾空,分享php中去除头尾空格的2种方法
  7. 2023临沂大学计算机考研信息汇总
  8. linux一键分区脚本,【Shell】Linux中分区脚本
  9. 虚拟现实技术利用计算机,虚拟现实 虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统它利用计算机生...
  10. python初学者学习简单教程