Android Studio实现数独小游戏,休闲益智

news2024/11/28 8:31:00

文章目录

  • 一、项目概述
  • 二、开发环境
  • 三、详细设计
    • 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 song
    public 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 music
    public static void stop(Context context) {
        if(mp != null){
            mp.stop();
            mp.release();
            mp = null;
        }
    }
}

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

 @Override
 protected void onResume() {
     super.onResume();
     // 程序开始时,调用music activity开始播放音乐
     Music.play(this, R.raw.nothing_to_lose);
 }
 @Override
 protected 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() {
            @Override
            public 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类中,有显示软键盘和手机屏幕点击事件的处理方法,该方法处理三种情况的事件:屏幕被按下时,屏幕被抬起时,屏幕中拖动,根据触摸位置的坐标选中对应区域的按钮。

 @Override
 public 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 tile
   FontMetrics 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 selection
   Log.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 time
   getIntent().putExtra(KEY_DIFFICULTY, DIFFICULTY_CONTINUE);

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

    @Override
    protected 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里面取出来保存的坐标即可。

    @Override
    protected 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实现学生信息系统❤️

  • ❤️Android Studio实现学生选课系统❤️

  • ❤️Android Stduio实现天气预报APP❤️

  • ❤️Android Studio实现仓库管理系统❤️

  • ❤️Android Studio实现校园二手交易系统❤️

从追求效率的角度看,只有真正有价值的事情,才值得你这样耗用自己宝贵的时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/85579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【实训项目】教师工作量管理系统(超级详细)

目录 一、需求与分析 1. 项目概述 1.1 教师信息处理 1.2 教师工作量数据处理&#xff1a; 1.3 教师综合信息输出 2. 需求分析 3. 模块设计 3.1 功能模块 3.2 所有功能模块的流程图 二、设计与实现 1. 程序设计 1.1 教师工作量管理系统 1.2 登录系统 1.3 主函数…

初级算法之字符串

344. 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 思路一: 从中间开始向两边遍历,然后两边交换位置,最终获得字符串的反转 // class Solution {public void reverseString(char[] s) {int len s.length,siz…

二、JavaScript——Hello World

1. 创建文件 提前在本地新建好文件夹用于存储项目代码&#xff0c;再通过VSode打开指定存储代码的指定文件夹&#xff0c;并新建HelloWorld.html文件 HelloWorld.html文件新建成功之后&#xff0c;输入“&#xff01;”点击自动生成标签 自动生成的标签如下&#xff1a; <!…

02Golang执行流程简介

Golang执行流程简介Golang执行流程的分析两种流程的方式区别什么是编译什么是运行Go程序开发注意事项Golang执行流程的分析 如果是对源码编译后&#xff0c;再执行&#xff0c;go的执行流程如下 如果对源码直接执行go run源码&#xff0c;go的执行流程如下 两种流程的方式区…

副业想做自媒体可以选择什么领域,适合宝妈的三个自媒体领域推荐

大家好&#xff0c;我是蝶衣王的小编&#xff0c;今天说说自媒体可以选择的领域 在过去的两年里&#xff0c;最受欢迎的职业之一必须属于自媒体。无论是全职还是副业&#xff0c;每个人都可以这样做。许多人经常在互联网上看到&#xff0c;通过自媒体&#xff0c;月收入数千或…

【汽车电子】can报文和can database(candbc)

1.can就是controller area network&#xff0c;是面向汽车的通信协议&#xff0c;通俗来讲就是在汽车电子控制领域中的不同部分进行通信的&#xff08;传输数据&#xff09;。 2.can报文有标准帧和扩展帧两种&#xff0c;也就是can和canfd&#xff0c;canfd是can的升级版&…

vscode git拉下来后LF CRLF问题

点击这里可以更改红色报错&#xff0c; windows下默认是CRLF, 类unix下LF 若CRLF数量非常多&#xff0c;解决方法&#xff1a; vscode 1. 在设置里Eol 选\n 2. 在根路径.editorconfig 里end_of_line lf 以上都不生效 可以有两种解决方案&#xff1a; 一. 下载插件EditorCo…

linux系统中如何挂载数据盘

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 前言 作为一个开发人员&#xff0c;和服务器打交道是必不可少的&#xff0c;当然要和运维相比的话还是差点儿。 但是&#xff0c;在公司&#xff0c;作为一个程序员&#xff0c;难免会遇…

微电网优化调度|基于多目标粒子群算法的微电网优化调度【风、光、储能、柴油机、电网交互燃汽轮机】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f389;作者研究&#xff1a;&#x1f3c5;&#x1f3c5;&#x1f3c5;本科计算机专业&#xff0c;研究生电气学硕…

(十三)Vue之监测数据改变的原理

文章目录监测数据改变的原理之对象vue.set的使用监测数据改变的原理之数组Vue学习目录 上一篇&#xff1a;&#xff08;十二&#xff09;Vue之列表渲染 先看一个需求&#xff1a;使用列表渲染出一组数据&#xff0c;然后点击按钮更新其中一个信息 <!--准备好一个容器--&…

微服务中统一日志-ELK

微服务中统一日志-ELK一.简介1.介绍2.流程3.要求4.下载地址二.安装Elasticsearch1.创建文件存放目录2.进入目录3.下载4.解压5.修改配置5.1.介绍5.2.系统配置5.3修改es配置5.4启动&#xff0c;测试三.安装Kibana1.进入目录2.下载3.解压4.修改配置4.1介绍4.2修改kibana配置4.3启动…

面试八股-JVM

1.Java代码编译过程 准备过程&#xff1a;初始化插入式注解处理器解析与填充符号表过程 词法、语法分析&#xff0c;将字符流转为标记集合&#xff0c;构造抽象语法树填充符号表&#xff0c;产生符号地址和符号信息 插入式注解处理器的注解处理分析与字节码生成过程 标注检查&…

描述统计 | 学习笔记

一.导论 统计学是通过收集&#xff0c;整理&#xff0c;分析&#xff0c;描述数据等手段&#xff0c;以达到推断所测对象的本质&#xff0c;甚至预测对象未来的一门综合性科学。其目的是探索数据的内在数量规律性&#xff0c;以达到对客观事物的科学认识 统计的本业是消化数据…

java语言【#107. 七的奇倍数】(已通过)

题目描述 ​ 如果一个数既是 7 的倍数又不能被 2 整除&#xff0c;那么我们称之为七的奇倍数。 ​ 输入一个正整数 n&#xff0c;判断它是否是 7 的奇倍数。 输入 ​ 输入一个正整数 n &#xff08;0≤n≤100&#xff09; 输出 ​ 如果 n 是 7 的奇倍数 输出 YES 否则输出 NO…

校园二手市场开题报告范文

目录 一、课题意义&#xff08;包括课题的理论意义和现实意义&#xff09; &#xff08;一&#xff09;理论意义 &#xff08;二&#xff09;现实意义 二、文献综述&#xff08;包括&#xff1a;1.理论的渊源及演进过程2.国内外对本课题的研究现状和有待解决的问题3.本人对所…

适合rv1109+rv1126使用基于RKmedia的人脸和车牌识别的SDK及使用介绍说明

基于RKmedia开发的人脸识别和车牌识别SDK简介及使用 一、功能简介 SDK下载&#xff1a;https://download.csdn.net/download/DeepLearning_/87272848 人脸检测&识别 对于人脸部分&#xff0c;SDK 提供了以下能力&#xff1a; 1. 人脸检测 1.1 人脸是否带口罩判定 1.2…

路由器的安装方法步骤

路由器的安装和设置如下&#xff1a; 1.首先连接线路&#xff0c;可以参考下图 2.线路连接完毕后&#xff0c;打开浏览器输入路由器的管理地址和管理密码然后进入路由器后台&#xff08;具体路由器的登录地址和登录密码可以参考说明书或者是路由器背面的标签&#xff09; 3.…

Nacos配置管理-配置热更新

Nacos配置自动刷新 Nacos中的配置文件变更后&#xff0c;微服务无需重启就可以感知。不过需要通过下面两种配置实现&#xff1a; 热更新-方法一&#xff1a;使用RefreshScope注解 在Value注入的变量所在类上添加RefreshScope注解&#xff1b; RestController RequestMapping(&…

直播|BIA Separations 和元生物两位大咖关于质粒DNA的制造工艺和质量控制

质粒 DNA&#xff08;pDNA&#xff09; 是生物研究和治疗开发中用于转移或表达基因的一个基本组成部分。细胞与基因治疗中最常用的载体AAV和慢病毒的生产都需要质粒作为起始材料&#xff0c;随着基因治疗&#xff0c;细胞治疗及DNA疫苗的快速发展&#xff0c;快速高效的大规模工…

腾讯云原生数据湖存储服务能力再上新,三级加速体系助力企业用数赋智

随着数据价值被越来越多企业认可&#xff0c;数据湖存储已成为企业级存储的首选和新一代提升生产力的服务。12月1日&#xff0c;在2022腾讯数字生态大会存储专场&#xff0c;腾讯云升级了云原生数据湖产品能力&#xff0c;并详细阐释了其设计理念&#xff0c;对其在多个行业的应…