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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

一、项目概述

数独是一种逻辑解谜游戏它规则稍复杂解题过程富有挑战性。本次安卓数独小游戏主页面有继续游戏、新游戏、关于和退出四个功能下拉菜单有设置选项。新游戏可以选择简单、中等和困难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的宽度为1dpcolor是灰色radius是50dp弧形半径非常明显padding为2dp有内边距视觉效果更好最后根据state_pressed变色。

在这里插入图片描述

3.2 逻辑设计

1、背景音乐直接定义一个类定义play方法创建MediaPlayer对象播放传参resourcesetLooping设为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实现数独小游戏休闲益智👈

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android