Android学习笔记(12)-开始做一个数独游戏[补充]

本文介绍如何使用Android的MediaPlayer类为游戏添加背景音乐。通过创建MediaService服务并利用MediaPlayer进行音乐播放,文中详细展示了代码实现过程及注意事项。
再补充一点吧,如果需要给游戏加上背景音乐,其实也是非常容易的事情。因为Android提供了一个 MediaPlayer类可以方便的播放音乐文件。

android.media.MediaPlayer类没有构造函数,一般是用它的静态方法create生成实例,简单地告诉它音乐文件的资源ID即可(支持mp3/wav/midi等)。

首先,我们得建立一个Service,就叫MediaService吧,它的代码如下:
public class MediaService extends Service implements MediaPlayer.OnErrorListener,MediaPlayer.OnCompletionListener,MediaPlayer.OnPreparedListener {
      
      ... ...    

    
private MediaPlayer player;
    
    @Override
    
protected void onDestroy() {
        
// TODO Auto-generated method stub
        super.onDestroy();
        
if(player!=null){
            player.stop();
            player.release();
        }

    }


    @Override
    
protected void onStart(int startId, Bundle arguments) {
        
// TODO Auto-generated method stub
        Log.d("Media","onStart");
            
        player
=MediaPlayer.create(this.getApplication(),R.raw.tonhua);
        
if(player!=null){
            player.setAudioStreamType(AudioSystem.STREAM_MUSIC);
            
            player.setOnCompletionListener(
this);
            player.setOnPreparedListener(
this);
            player.setOnErrorListener(
this);
            
            player.prepareAsync();
        }

    }


    @Override
    
public void onCompletion(MediaPlayer arg0) {
        
// TODO Auto-generated method stub
        Log.d("Media","finished.");
    }


    @Override
    
public void onPrepared(MediaPlayer arg0) {
        
// TODO Auto-generated method stub
        Log.d("Media","prepared.");
        player.start();
    }

    
    @Override
    
public void onError(MediaPlayer arg0,int what, int extra) {
                
        Log.d(
"Media","onError");
        player.stop();
    }

}

这个服务主要就是用一个MediaPlayer去播放资源中的tonghua(一首MP3音乐)。次序一般是先create出这个实例,然后prepare一下(如果是文件直接prepare,如果是流则最好异步parepareAsync),接着就可以start了,同步可以直接start,异步则必须放到onPrepared中再start。

在MainActivity中启动这个服务即可。
mediaServiceIntent= new Intent();
mediaServiceIntent.setClass(
this, MediaService.class);
        
 
this.startService(mediaServiceIntent, new Bundle());

当前,在Activity停止时也别忘了将这个Service停掉,而在Service停止时关掉MediaPlayer。

在模拟器上试了,效果不是太好,声音有点断断续续,不知道是不是我的解码器的问题(Vista系统)。


好的,下面是一个Android Studio中实现数独游戏的完整解决方案。 ### 回答问题 #### 1. 创建项目 首先,在 Android Studio 中创建一个新的项目,选择 "Empty Activity" 模板。 #### 2. 设计界面 使用 XML 文件设计一个简单的数独游戏界面。我们可以使用 `GridLayout` 来表示数独的 9x9 网格。 ```xml <!-- res/layout/activity_main.xml --> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="9" android:rowCount="9"> </GridLayout> ``` #### 3. 动态生成数独网格 在 Java 或 Kotlin 中动态生成 81 个 `EditText` 控件来填充这个 `GridLayout`。 以下是使用 Kotlin 实现的代码: ```kotlin // MainActivity.kt package com.example.sudokugame import android.os.Bundle import android.widget.EditText import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化数独网格 initSudokuGrid() } private fun initSudokuGrid() { val gridSize = 9 for (i in 0 until gridSize * gridSize) { val editText = EditText(this).apply { layoutParams = GridLayout.LayoutParams().apply { width = GridLayout.LayoutParams.MATCH_PARENT height = GridLayout.LayoutParams.MATCH_PARENT } setSingleLine() inputType = android.text.InputType.TYPE_CLASS_NUMBER maxLength = 1 } gridLayout.addView(editText) } } } ``` #### 4. 数独生成逻辑 为了生成一个有效的数独谜题,我们需要一个算法来生成完整的数独网格,然后从中移除一些数字以形成谜题。 以下是一个简单的数独生成器(Java 版本): ```java // SudokuGenerator.java public class SudokuGenerator { private static final int GRID_SIZE = 9; private static final int EMPTY = 0; private int[][] grid = new int[GRID_SIZE][GRID_SIZE]; public SudokuGenerator() { generateSudoku(); } public int[][] getGrid() { return grid; } private boolean generateSudoku() { for (int row = 0; row < GRID_SIZE; row++) { for (int col = 0; col < GRID_SIZE; col++) { if (grid[row][col] == EMPTY) { int[] possibleNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9}; shuffleArray(possibleNumbers); for (int num : possibleNumbers) { if (isValid(num, row, col)) { grid[row][col] = num; if (generateSudoku()) { return true; } else { grid[row][col] = EMPTY; } } } return false; } } } return true; } private boolean isValid(int number, int row, int col) { // 检查行和列是否有重复数字 for (int i = 0; i < GRID_SIZE; i++) { if (grid[row][i] == number || grid[i][col] == number) { return false; } } // 检查3x3子网格是否有重复数字 int startRow = row - row % 3; int startCol = col - col % 3; for (int i = startRow; i < startRow + 3; i++) { for (int j = startCol; j < startCol + 3; j++) { if (grid[i][j] == number) { return false; } } } return true; } private void shuffleArray(int[] array) { for (int i = array.length - 1; i > 0; i--) { int index = (int) (Math.random() * (i + 1)); int temp = array[index]; array[index] = array[i]; array[i] = temp; } } } ``` #### 5. 将生成的数独加载到界面上 在 `MainActivity` 中,将生成的数独网格加载到界面上,并允许用户填写答案。 ```kotlin // 在 MainActivity 中添加以下代码 private fun loadSudokuPuzzle() { val sudokuGenerator = SudokuGenerator() val puzzle = sudokuGenerator.getGrid() for (i in 0 until gridSize * gridSize) { val row = i / gridSize val col = i % gridSize val editText = gridLayout.getChildAt(i) as EditText if (puzzle[row][col] != 0) { editText.setText(puzzle[row][col].toString()) editText.isEnabled = false // 固定初始数字 } else { editText.text.clear() editText.isEnabled = true } } } ``` #### 6. 添加检查功能 最后,可以添加一个按钮来检查用户的答案是否正确。 ```kotlin // 添加按钮并绑定点击事件 val checkButton = Button(this).apply { text = "Check Solution" setOnClickListener { if (checkSolution()) { Toast.makeText(this@MainActivity, "Correct!", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this@MainActivity, "Incorrect!", Toast.LENGTH_SHORT).show() } } } linearLayout.addView(checkButton) private fun checkSolution(): Boolean { val gridSize = 9 val userGrid = Array(gridSize) { IntArray(gridSize) } for (i in 0 until gridSize * gridSize) { val row = i / gridSize val col = i % gridSize val editText = gridLayout.getChildAt(i) as EditText val value = editText.text.toString().toIntOrNull() ?: 0 userGrid[row][col] = value } // 验证用户输入的数独是否有效 for (row in 0 until gridSize) { for (col in 0 until gridSize) { if (userGrid[row][col] == 0 || !isValid(userGrid[row][col], row, col, userGrid)) { return false } } } return true } private fun isValid(number: Int, row: Int, col: Int, grid: Array<IntArray>): Boolean { // 检查行和列是否有重复数字 for (i in 0 until 9) { if (grid[row][i] == number && i != col) return false if (grid[i][col] == number && i != row) return false } // 检查3x3子网格是否有重复数字 val startRow = row - row % 3 val startCol = col - col % 3 for (i in startRow until startRow + 3) { for (j in startCol until startCol + 3) { if (grid[i][j] == number && (i != row || j != col)) return false } } return true } ``` --- ### 给出解释 上述代码实现了以下功能: 1. 使用 `GridLayout` 创建了一个 9x9 的数独网格。 2. 动态生成了 81 个 `EditText` 控件,用于用户输入。 3. 使用递归回溯算法生成了一个有效的数独谜题。 4. 将生成的数独谜题加载到界面上,并固定初始数字。 5. 添加了一个按钮,用于检查用户的答案是否正确。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值