如何在Android Studio中为Tic Tac Toe创建SQLite数据库并实现玩家计分?
嘿,这个需求其实很清晰,我来一步步带你实现Android Studio里用SQLite存储井字棋玩家的姓名和分数,并且在获胜时自动加分的功能~
1. 先写核心的SQLite数据库管理类(SQLiteOpenHelper子类)
首先你需要一个继承自SQLiteOpenHelper的类,用来创建数据库、管理表结构,这是操作SQLite的标准方式。
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class ScoreDBHelper extends SQLiteOpenHelper { // 数据库名和版本号 private static final String DATABASE_NAME = "TicTacToeScores.db"; private static final int DATABASE_VERSION = 1; // 玩家表的结构 private static final String TABLE_PLAYERS = "players"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_NAME = "name"; private static final String COLUMN_SCORE = "score"; // 创建表的SQL语句 private static final String CREATE_TABLE_PLAYERS = "CREATE TABLE " + TABLE_PLAYERS + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " TEXT UNIQUE NOT NULL, " + COLUMN_SCORE + " INTEGER DEFAULT 0)"; public ScoreDBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建玩家表 db.execSQL(CREATE_TABLE_PLAYERS); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 如果数据库版本更新,这里可以处理表结构变更(简单场景下直接删除旧表重建) db.execSQL("DROP TABLE IF EXISTS " + TABLE_PLAYERS); onCreate(db); } }
这里我把name设为UNIQUE,确保每个玩家姓名唯一,避免重复存储。
2. 封装数据库的增、查、改操作方法
接下来在ScoreDBHelper里添加具体的操作方法,方便主Activity调用:
import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; // 继续在ScoreDBHelper类里添加以下方法: // 添加新玩家(如果玩家已存在则不做操作) public void addPlayer(String playerName) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_NAME, playerName); // insertWithOnConflict避免重复插入,当name重复时忽略 db.insertWithOnConflict(TABLE_PLAYERS, null, values, SQLiteDatabase.CONFLICT_IGNORE); db.close(); } // 根据玩家姓名获取当前分数 public int getPlayerScore(String playerName) { int score = 0; SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_PLAYERS, new String[]{COLUMN_SCORE}, COLUMN_NAME + "=?", new String[]{playerName}, null, null, null); if (cursor != null && cursor.moveToFirst()) { score = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_SCORE)); cursor.close(); } db.close(); return score; } // 更新玩家分数(获胜时加1) public void updatePlayerScore(String playerName) { // 先获取当前分数,再加1 int currentScore = getPlayerScore(playerName); int newScore = currentScore + 1; SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_SCORE, newScore); // 根据姓名更新分数 db.update(TABLE_PLAYERS, values, COLUMN_NAME + "=?", new String[]{playerName}); db.close(); }
3. 在主Activity中关联数据库并处理获胜逻辑
现在回到你的主Activity,比如MainActivity,我们需要初始化数据库助手,然后在游戏检测到玩家获胜时调用分数更新方法。
第一步:初始化数据库助手
在Activity里声明全局变量:
private ScoreDBHelper dbHelper;
然后在onCreate方法里初始化:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化数据库助手 dbHelper = new ScoreDBHelper(this); // 假设你已经有玩家姓名的输入或选择逻辑,比如默认玩家叫"Player1" // 先确保玩家存在于数据库中 dbHelper.addPlayer("Player1"); }
第二步:处理游戏获胜的逻辑
假设你已经有了判断玩家获胜的方法,比如checkWin(),当这个方法返回true时,调用我们的分数更新方法:
// 示例:当检测到玩家获胜时调用这个方法 private void onPlayerWin(String winningPlayerName) { // 注意:数据库操作不能在主线程执行,否则会触发ANR,这里用Coroutines处理(需要添加Coroutines依赖) CoroutineScope(Dispatchers.IO).launch { // 更新数据库分数 dbHelper.updatePlayerScore(winningPlayerName); // 更新UI要切回主线程 withContext(Dispatchers.Main) { // 比如更新界面上的分数显示 int newScore = dbHelper.getPlayerScore(winningPlayerName); scoreTextView.setText("分数:" + newScore); Toast.makeText(MainActivity.this, winningPlayerName + "获胜!分数+1", Toast.LENGTH_SHORT).show(); } } }
如果你的项目还没用到Coroutines,也可以用AsyncTask(虽然官方不推荐,但简单场景下能用):
private class UpdateScoreTask extends AsyncTask<String, Void, Integer> { @Override protected Integer doInBackground(String... params) { String playerName = params[0]; dbHelper.updatePlayerScore(playerName); return dbHelper.getPlayerScore(playerName); } @Override protected void onPostExecute(Integer newScore) { super.onPostExecute(newScore); scoreTextView.setText("分数:" + newScore); Toast.makeText(MainActivity.this, "获胜!分数+1", Toast.LENGTH_SHORT).show(); } } // 调用方式: new UpdateScoreTask().execute(winningPlayerName);
一些注意事项
- 记得在Activity的
onDestroy方法里关闭数据库助手,避免资源泄漏:
@Override protected void onDestroy() { super.onDestroy(); if (dbHelper != null) { dbHelper.close(); } }
- 如果玩家姓名是动态输入的,要先调用
addPlayer确保玩家存在,否则updatePlayerScore会因为找不到记录而无效。 - 数据库操作一定要放在子线程,这是Android的规范,避免阻塞主线程导致界面卡顿或ANR。
这样整个流程就通了:玩家获胜→触发分数更新→数据库里的分数加1→界面同步显示新分数。
内容的提问来源于stack exchange,提问作者Lil
相关产品推荐
相关产品推荐

