MainActivity.kt代码如下:

package com.example.myapplication

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.pow
import kotlin.math.sqrt
import kotlin.random.Random

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TankBattleTheme {
                Box(modifier = Modifier.fillMaxSize()) {
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(
                                top = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() },
                                bottom = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
                            ),
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        TankBattleGame()
                    }
                }
            }
        }
    }
}

// ======================
// 数据模型
// ======================
data class Tank(
    val id: String = "tank_${Random.nextLong()}",
    var x: Int,
    var y: Int,
    var direction: Direction,
    val color: Color,
    val isPlayer: Boolean = false,
    var isAlive: Boolean = true
)

data class Bullet(
    var x: Int,
    var y: Int,
    val direction: Direction,
    val ownerId: String,
    val color: Color = Color.Yellow,
    val speed: Int // 添加子弹速度属性
)

data class Wall(val x: Int, val y: Int, val width: Int = GRID_SIZE, val height: Int = GRID_SIZE)

enum class Direction { UP, DOWN, LEFT, RIGHT }

data class PlayerStats(
    var score: Int = 0,
    var lives: Int = 1 // 基础生命值改为1
)

// 优化:扩展游戏设置,包含更多参数
data class GameSettings(
    val playerTankSpeed: Int,     // 玩家坦克速度
    val enemyTankSpeed: Int,      // 敌方坦克速度
    val playerBulletSpeed: Int,   // 玩家子弹速度
    val enemyBulletSpeed: Int,    // 敌方子弹速度
    val pointsPerExtraLife: Int   // 加命所需分数
)

// 修改:GameState 添加 RESTARTING 状态
enum class GameState { PLAYING, PAUSED, GAME_OVER, VICTORY, MENU, RESTARTING }

// ======================
// 常量 (适配小米手机)
// ======================
const val GRID_SIZE = 45
const val MAP_WIDTH_GRIDS = 20
const val MAP_HEIGHT_GRIDS = 20
const val DEFAULT_BULLET_SPEED = 5
const val GAME_LOOP_DELAY = 50L
const val BULLET_RADIUS = 6f

// ======================
// 主游戏入口 (优化后)
// ======================
@Composable
fun TankBattleGame() {
    val context = LocalContext.current
    // 优化:创建 ScoreRepository 实例
    val scoreRepository = remember { ScoreRepository(context) }
    var gameState by remember { mutableStateOf(GameState.MENU) }
    // 优化:初始化设置包含所有速度参数
    var gameSettings by remember {
        mutableStateOf(
            GameSettings(
                playerTankSpeed = 2,
                enemyTankSpeed = 2,
                playerBulletSpeed = DEFAULT_BULLET_SPEED,
                enemyBulletSpeed = DEFAULT_BULLET_SPEED,
                pointsPerExtraLife = 10
            )
        )
    }
    // 优化:用于存储游戏结束时的最终分数
    var finalScore by remember { mutableStateOf(0) }
    // 优化:用于存储游戏结束原因
    var gameEndReason by remember { mutableStateOf<GameEndReason?>(null) }

    // 优化:处理分数保存的副作用
    // *** 修改:这是唯一保存分数的地方 ***
    LaunchedEffect(finalScore, gameEndReason) {
        if (gameEndReason != null) {
            // 当 finalScore 或 gameEndReason 更新时,保存分数
            scoreRepository.addScore(finalScore)
            // 显示 Toast 提示
            val message = when (gameEndReason) {
                GameEndReason.VICTORY -> "恭喜胜利!最终得分: $finalScore"
                GameEndReason.DEFEAT -> "游戏结束!最终得分: $finalScore"
                GameEndReason.QUIT -> "游戏结束,得分: $finalScore"
                null -> ""
            }
            if (message.isNotEmpty()) {
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
            }
            // 重置原因,防止重复保存
            gameEndReason = null
        }
    }

    when (gameState) {
        GameState.MENU -> {
            // 优化:传递 ScoreRepository 到菜单界面
            GameMenuScreen(
                scoreRepository = scoreRepository,
                onStartGame = { settings ->
                    gameSettings = settings
                    gameState = GameState.PLAYING
                }
            )
        }
        GameState.PLAYING, GameState.PAUSED, GameState.GAME_OVER, GameState.VICTORY, GameState.RESTARTING -> {
            val density = LocalDensity.current
            val gameWidthDp: Dp = with(density) { (MAP_WIDTH_GRIDS * GRID_SIZE).toDp() }
            val gameHeightDp: Dp = with(density) { (MAP_HEIGHT_GRIDS * GRID_SIZE).toDp() }

            RunningGame(
                scoreRepository = scoreRepository, // 传递 scoreRepository
                gameSettings = gameSettings,
                gameState = gameState,
                gameWidthDp = gameWidthDp,
                gameHeightDp = gameHeightDp,
                onBackToMenu = { score, reason ->
                    // *** 修改:更新最终分数和原因,触发保存 ***
                    finalScore = score
                    gameEndReason = reason
                    gameState = GameState.MENU
                },
                onTogglePause = {
                    gameState = if (gameState == GameState.PLAYING) GameState.PAUSED else GameState.PLAYING
                },
                onGameEnd = { score, reason -> // 新增回调
                    // *** 修改:只负责更新主游戏状态和显示提示,不保存分数 ***
                    // 更新主游戏状态
                    gameState = when (reason) {
                        GameEndReason.VICTORY -> GameState.VICTORY
                        GameEndReason.DEFEAT -> GameState.GAME_OVER
                        else -> gameState // QUIT 不改变主状态机,由 onBackToMenu 处理
                    }
                    // 注意:Toast 移到了 LaunchedEffect 中统一处理
                },
                // 新增 onRestart 回调
                onRestart = {
                    gameState = GameState.RESTARTING
                }
            )
        }
    }
}

// ======================
// 菜单界面 (优化后)
// ======================
@Composable
fun GameMenuScreen(
    scoreRepository: ScoreRepository,
    onStartGame: (GameSettings) -> Unit
) {
    var initialSettings by remember {
        mutableStateOf(
            GameSettings(
                playerTankSpeed = 2,
                enemyTankSpeed = 2,
                playerBulletSpeed = DEFAULT_BULLET_SPEED,
                enemyBulletSpeed = DEFAULT_BULLET_SPEED,
                pointsPerExtraLife = 10
            )
        )
    }

    var playerSpeed by remember { mutableStateOf(initialSettings.playerTankSpeed.toString()) }
    var enemySpeed by remember { mutableStateOf(initialSettings.enemyTankSpeed.toString()) }
    var playerBulletSpeed by remember { mutableStateOf(initialSettings.playerBulletSpeed.toString()) }
    var enemyBulletSpeed by remember { mutableStateOf(initialSettings.enemyBulletSpeed.toString()) }
    var pointsForLife by remember { mutableStateOf(initialSettings.pointsPerExtraLife.toString()) }

    val playerSpeedInt = playerSpeed.toIntOrNull() ?: 2
    val enemySpeedInt = enemySpeed.toIntOrNull() ?: 2
    val playerBulletSpeedInt = playerBulletSpeed.toIntOrNull() ?: DEFAULT_BULLET_SPEED
    val enemyBulletSpeedInt = enemyBulletSpeed.toIntOrNull() ?: DEFAULT_BULLET_SPEED
    val pointsForLifeInt = pointsForLife.toIntOrNull() ?: 10

    val isPlayerSpeedValid = playerSpeedInt in 1..8
    val isEnemySpeedValid = enemySpeedInt in 1..8
    val isPlayerBulletSpeedValid = playerBulletSpeedInt in 1..15
    val isEnemyBulletSpeedValid = enemyBulletSpeedInt in 1..15
    val isPointsValid = pointsForLifeInt >= 5 && pointsForLifeInt % 5 == 0

    val allValid = isPlayerSpeedValid && isEnemySpeedValid && isPlayerBulletSpeedValid && isEnemyBulletSpeedValid && isPointsValid

    // 优化:获取历史成绩的 Flow 并收集状态
    val scores by scoreRepository.scoresFlow.collectAsState(initial = emptyList())
    val coroutineScope = rememberCoroutineScope()

    MaterialTheme {
        Surface(color = Color.Black, modifier = Modifier.fillMaxSize()) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(20.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Text("🎮 坦克大战", color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold)
                Spacer(Modifier.height(10.dp))

                // 优化:使用 LazyColumn 包裹设置项和历史记录
                LazyColumn(
                    modifier = Modifier
                        .fillMaxWidth()
                        .weight(1f),
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    // 设置项
                    item {
                        OutlinedTextField(
                            value = playerSpeed,
                            onValueChange = { playerSpeed = it },
                            label = { Text("玩家坦克速度 (1-8)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPlayerSpeedValid
                        )
                        if (!isPlayerSpeedValid) {
                            Text("⚠️ 玩家速度必须在 1-8 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = enemySpeed,
                            onValueChange = { enemySpeed = it },
                            label = { Text("敌方坦克速度 (1-8)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isEnemySpeedValid
                        )
                        if (!isEnemySpeedValid) {
                            Text("⚠️ 敌方速度必须在 1-8 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = playerBulletSpeed,
                            onValueChange = { playerBulletSpeed = it },
                            label = { Text("玩家子弹速度 (1-15)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPlayerBulletSpeedValid
                        )
                        if (!isPlayerBulletSpeedValid) {
                            Text("⚠️ 玩家子弹速度必须在 1-15 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = enemyBulletSpeed,
                            onValueChange = { enemyBulletSpeed = it },
                            label = { Text("敌方子弹速度 (1-15)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isEnemyBulletSpeedValid
                        )
                        if (!isEnemyBulletSpeedValid) {
                            Text("⚠️ 敌方子弹速度必须在 1-15 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = pointsForLife,
                            onValueChange = { pointsForLife = it },
                            label = { Text("多少分加一条命 (≥5 且 5 的倍数)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPointsValid
                        )
                        if (!isPointsValid) {
                            Text("⚠️ 分数必须 ≥5 且是 5 的倍数", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }

                    // 历史记录标题
                    item {
                        Spacer(Modifier.height(10.dp))
                        Text("📜 历史战绩", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.Medium)
                        Divider(color = Color.Gray, thickness = 1.dp)
                    }

                    // 历史记录列表
                    items(scores) { gameScore ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(vertical = 4.dp),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Text("得分: ${gameScore.score}", color = Color.Yellow)
                            Text(gameScore.timestamp, color = Color.LightGray, fontSize = 12.sp)
                        }
                    }

                    // 清除按钮 (放在列表末尾)
                    item {
                        Spacer(Modifier.height(10.dp))
                        Button(
                            onClick = {
                                coroutineScope.launch {
                                    scoreRepository.clearScores()
                                }
                            },
                            colors = ButtonDefaults.buttonColors(containerColor = Color.Red),
                            modifier = Modifier.align(Alignment.End)
                        ) {
                            Icon(Icons.Default.Delete, contentDescription = "清除", tint = Color.White)
                            Spacer(Modifier.width(4.dp))
                            Text("清除所有记录")
                        }
                    }
                }

                Spacer(Modifier.height(10.dp))

                Button(
                    onClick = {
                        if (allValid) {
                            onStartGame(
                                GameSettings(
                                    playerTankSpeed = playerSpeedInt,
                                    enemyTankSpeed = enemySpeedInt,
                                    playerBulletSpeed = playerBulletSpeedInt,
                                    enemyBulletSpeed = enemyBulletSpeedInt,
                                    pointsPerExtraLife = pointsForLifeInt
                                )
                            )
                        }
                    },
                    enabled = allValid,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text("开始游戏")
                }
            }
        }
    }
}


// ======================
// 主游戏逻辑 (修改后的版本)
// ======================
@Composable
fun RunningGame(
    scoreRepository: ScoreRepository, // 新增参数
    gameSettings: GameSettings,
    gameState: GameState,
    gameWidthDp: Dp,
    gameHeightDp: Dp,
    onBackToMenu: (score: Int, reason: GameEndReason) -> Unit, // 修改:此回调只负责通知,不负责保存
    onTogglePause: () -> Unit,
    onGameEnd: (score: Int, reason: GameEndReason) -> Unit, // 新增回调参数
    onRestart: () -> Unit // 新增回调参数
) {
    val context = LocalContext.current
    // 移除了内部的 scoreRepository 创建
    val edgeWalls = remember {
        val wallThickness = GRID_SIZE
        val mapWidthPixels = MAP_WIDTH_GRIDS * GRID_SIZE
        val mapHeightPixels = MAP_HEIGHT_GRIDS * GRID_SIZE
        buildList {
            for (x in 0 until MAP_WIDTH_GRIDS) {
                add(Wall(x * GRID_SIZE, 0))
            }
            for (x in 0 until MAP_WIDTH_GRIDS) {
                add(Wall(x * GRID_SIZE, mapHeightPixels - wallThickness))
            }
            for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                add(Wall(0, y * GRID_SIZE))
            }
            for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                add(Wall(mapWidthPixels - wallThickness, y * GRID_SIZE))
            }
        }
    }
    val innerWalls = remember {
        listOf(
            Wall(5 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(6 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(9 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(10 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 10 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 11 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 12 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 8 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 9 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 10 * GRID_SIZE),
            Wall(3 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(4 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(5 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(16 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(17 * GRID_SIZE, 15 * GRID_SIZE)
        )
    }
    val walls = remember { edgeWalls + innerWalls }
    var playerTank by remember {
        mutableStateOf(
            Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
        )
    }
    // 优化:使用 generateUniqueEnemyTanks 生成不重叠的坦克
    var enemyTanks by remember {
        mutableStateOf(
            generateUniqueEnemyTanks(walls, 10)
        )
    }
    val bullets = remember { mutableStateListOf<Bullet>() }
    var currentGameState by remember { mutableStateOf(gameState) }
    var playerMovingDirection by remember { mutableStateOf<Direction?>(null) }
    var stats by remember { mutableStateOf(PlayerStats()) }
    var lastExtraLifeScore by remember { mutableStateOf(0) }

    // 修复:将LaunchedEffect移到@Composable函数内部,并使用状态变量控制
    // 修改:这个 LaunchedEffect 监听 currentGameState 的变化来控制游戏循环
    LaunchedEffect(currentGameState) {
        while (currentGameState == GameState.PLAYING || currentGameState == GameState.PAUSED) {
            if (currentGameState == GameState.PLAYING) {
                // 玩家移动
                playerMovingDirection?.let { dir ->
                    val nextX = playerTank.x + when (dir) {
                        Direction.LEFT -> -gameSettings.playerTankSpeed
                        Direction.RIGHT -> gameSettings.playerTankSpeed
                        else -> 0
                    }
                    val nextY = playerTank.y + when (dir) {
                        Direction.UP -> -gameSettings.playerTankSpeed
                        Direction.DOWN -> gameSettings.playerTankSpeed
                        else -> 0
                    }
                    playerTank = playerTank.copy(direction = dir)
                    if (canMove(nextX, nextY, GRID_SIZE, GRID_SIZE, walls, listOf(playerTank) + enemyTanks, playerTank.id)) {
                        playerTank = playerTank.copy(x = nextX, y = nextY)
                    }
                }
                // 敌方坦克移动
                enemyTanks = enemyTanks.map { tank ->
                    if (!tank.isAlive) return@map tank
                    var newTank = tank
                    if (Random.nextInt(100) < 5) {
                        newTank = newTank.copy(direction = Direction.entries.random())
                    }
                    // 敌方坦克开火,子弹为蓝色,使用敌方子弹速度设置
                    if (Random.nextInt(100) < 2) {
                        val (bulletX, bulletY) = getBulletSpawnPosition(tank.x, tank.y, tank.direction)
                        bullets.add(Bullet(x = bulletX, y = bulletY, direction = tank.direction, ownerId = tank.id, color = Color.Blue, speed = gameSettings.enemyBulletSpeed))
                    }
                    val nextX = newTank.x + when (newTank.direction) {
                        Direction.LEFT -> -gameSettings.enemyTankSpeed
                        Direction.RIGHT -> gameSettings.enemyTankSpeed
                        else -> 0
                    }
                    val nextY = newTank.y + when (newTank.direction) {
                        Direction.UP -> -gameSettings.enemyTankSpeed
                        Direction.DOWN -> gameSettings.enemyTankSpeed
                        else -> 0
                    }
                    if (canMove(nextX, nextY, GRID_SIZE, GRID_SIZE, walls, listOf(playerTank) + enemyTanks, newTank.id)) {
                        newTank.copy(x = nextX, y = nextY)
                    } else {
                        val newDirection = when(newTank.direction) {
                            Direction.UP -> Direction.DOWN
                            Direction.DOWN -> Direction.UP
                            Direction.LEFT -> Direction.RIGHT
                            Direction.RIGHT -> Direction.LEFT
                        }
                        newTank.copy(direction = newDirection)
                    }
                }
                // 子弹移动
                val updatedBullets = bullets.map { bullet ->
                    val newX = bullet.x + when (bullet.direction) {
                        Direction.LEFT -> -bullet.speed
                        Direction.RIGHT -> bullet.speed
                        else -> 0
                    }
                    val newY = bullet.y + when (bullet.direction) {
                        Direction.UP -> -bullet.speed
                        Direction.DOWN -> bullet.speed
                        else -> 0
                    }
                    bullet.copy(x = newX, y = newY)
                }
                bullets.clear()
                bullets.addAll(updatedBullets)
                // 碰撞检测
                val bulletsToRemove = mutableStateListOf<Bullet>()
                val enemiesToKill = mutableStateListOf<Tank>()
                for (bullet in bullets) {
                    // 子弹与墙碰撞
                    if (walls.any { wall ->
                            bullet.x >= wall.x && bullet.x < wall.x + wall.width &&
                                    bullet.y >= wall.y && bullet.y < wall.y + wall.height
                        }) {
                        bulletsToRemove.add(bullet)
                        continue // 处理完墙碰撞后,跳过后续检查
                    }
                    // 子弹与坦克碰撞
                    // 玩家子弹击中敌方坦克
                    if (bullet.ownerId == playerTank.id) {
                        for (tank in enemyTanks) {
                            if (tank.isAlive && isColliding(bullet.x, bullet.y, tank.x, tank.y, 2, GRID_SIZE)) {
                                bulletsToRemove.add(bullet)
                                enemiesToKill.add(tank)
                                break // 一颗子弹只能击毁一个目标
                            }
                        }
                    }
                    // 敌方子弹击中玩家坦克
                    else if (playerTank.isAlive && isColliding(bullet.x, bullet.y, playerTank.x, playerTank.y, 2, GRID_SIZE)) {
                        bulletsToRemove.add(bullet)
                        playerTank.isAlive = false
                        // 不需要 break,因为敌方子弹不能击中其他敌方坦克
                    }
                    // 敌方子弹击中敌方坦克的情况被忽略(即敌方坦克不会自相残杀)
                }
                // 优化:只有玩家消灭敌方坦克才加分
                if (enemiesToKill.isNotEmpty()) {
                    enemiesToKill.forEach { it.isAlive = false }
                    stats.score += enemiesToKill.size // 加分
                    // 优化:检查是否达到加命分数
                    val fullSegments = stats.score / gameSettings.pointsPerExtraLife
                    val prevSegments = lastExtraLifeScore / gameSettings.pointsPerExtraLife
                    if (fullSegments > prevSegments) {
                        stats.lives += 1 // 生命值可以无限增加
                        lastExtraLifeScore = stats.score
                    }
                }
                bullets.removeAll(bulletsToRemove.toSet())

                // --- 修改开始 ---
                if (!playerTank.isAlive) {
                    stats.lives-- // 减命
                    if (stats.lives <= 0) {
                        // *** 修改:游戏结束时调用回调,但不保存分数 ***
                        onGameEnd(stats.score, GameEndReason.DEFEAT)
                    } else {
                        // 优化:不立即复活,而是等待重新开始
                        // playerTank = playerTank.copy(isAlive = true, x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE, y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE)
                    }
                } else if (enemyTanks.all { !it.isAlive }) {
                    // *** 修改:胜利时也调用回调,但不保存分数 ***
                    onGameEnd(stats.score, GameEndReason.VICTORY)
                }
                // --- 修改结束 ---
            }
            delay(GAME_LOOP_DELAY)
        }
    }

    // --- 优化:监听 gameState 变化来更新 currentGameState ---
    LaunchedEffect(gameState) {
        currentGameState = gameState
        // 新增:处理 RESTARTING 状态
        if (gameState == GameState.RESTARTING) {
            // 重置游戏状态和数据
            playerTank = Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
            enemyTanks = generateUniqueEnemyTanks(walls, 10)
            bullets.clear()
            // 优化:重置生命值为1
            stats = PlayerStats(lives = 1, score = 0) // 重置生命值和分数
            lastExtraLifeScore = 0
            currentGameState = GameState.PLAYING
        }
    }

    Box(modifier = Modifier.fillMaxSize()) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier.fillMaxSize()
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxWidth(),
                contentAlignment = Alignment.Center
            ) {

                // --- 优化:移除 Canvas 上的按钮绘制 ---
                // 绘制游戏画布
                GameCanvas(
                    playerTank = playerTank,
                    enemyTanks = enemyTanks,
                    bullets = bullets,
                    walls = walls,
                    gameWidthDp = gameWidthDp,
                    gameHeightDp = gameHeightDp
                )

                // --- 优化:移除在 Canvas 上绘制的按钮 ---

                // --- 新增:使用 GameOverOverlay ---
                // 游戏结束或胜利时显示覆盖层
                if (currentGameState == GameState.GAME_OVER || currentGameState == GameState.VICTORY) {
                    GameOverOverlay(
                        state = currentGameState,
                        score = stats.score,
                        onRestart = {
                            // 调用 onRestart 回调
                            onRestart()
                        },
                        onExit = {
                            // *** 修改:调用原始的返回菜单函数并传递分数和原因 ***
                            // 这会触发 TankBattleGame 中的 LaunchedEffect 来保存分数
                            onBackToMenu(stats.score, if(currentGameState == GameState.VICTORY) GameEndReason.VICTORY else GameEndReason.DEFEAT)
                        }
                    )
                }
                // --- 新增结束 ---
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(Color.DarkGray)
                    .padding(8.dp),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Text("分数: ${stats.score}", color = Color.Yellow, fontSize = 16.sp)
                Text("生命: ${stats.lives}", color = Color.Red, fontSize = 16.sp)
            }
            Column(modifier = Modifier.fillMaxWidth()) {
                GameControls(
                    onMove = { playerMovingDirection = it },
                    onStopMove = { playerMovingDirection = null },
                    onFire = {
                        if (currentGameState == GameState.PLAYING) {
                            val (bulletX, bulletY) = getBulletSpawnPosition(playerTank.x, playerTank.y, playerTank.direction)
                            // 玩家坦克开火,子弹为红色,使用玩家子弹速度设置
                            bullets.add(Bullet(x = bulletX, y = bulletY, direction = playerTank.direction, ownerId = playerTank.id, color = Color.Red, speed = gameSettings.playerBulletSpeed))
                        }
                    }
                )
                // --- 新增开始 ---
                // 按钮位于开火按钮下方
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(8.dp),
                    horizontalArrangement = Arrangement.SpaceEvenly
                ) {
                    Button(
                        onClick = onTogglePause,
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp)
                    ) {
                        Text(
                            if (currentGameState == GameState.PAUSED) "▶️ 继续游戏" else "⏸️ 暂停游戏",
                            fontSize = 14.sp
                        )
                    }
                    // 修改:添加确认弹窗
                    val openDialog = remember { mutableStateOf(false) }
                    Button(
                        onClick = { openDialog.value = true }, // 点击时打开弹窗
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp),
                        colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
                    ) {
                        Text("🏠 结束游戏", fontSize = 14.sp)
                    }
                    // 弹窗内容
                    if (openDialog.value) {
                        AlertDialog(
                            onDismissRequest = { openDialog.value = false },
                            title = { Text("确认退出") },
                            text = { Text("确定要结束游戏并返回菜单吗?") },
                            confirmButton = {
                                TextButton(
                                    onClick = {
                                        openDialog.value = false
                                        // *** 修改:确认后调用回调 ***
                                        // 这会触发 TankBattleGame 中的 LaunchedEffect 来保存分数
                                        onBackToMenu(stats.score, GameEndReason.QUIT)
                                    }
                                ) {
                                    Text("确定")
                                }
                            },
                            dismissButton = {
                                TextButton(
                                    onClick = { openDialog.value = false }
                                ) {
                                    Text("取消")
                                }
                            }
                        )
                    }
                }
                // --- 新增结束 ---
            }
        }
    }
}


@Composable
fun GameOverOverlay(
    state: GameState,
    score: Int,
    onRestart: () -> Unit,
    onExit: () -> Unit
) {
    Box(
        modifier = Modifier.fillMaxSize().background(Color.Black.copy(alpha = 0.8f)),
        contentAlignment = Alignment.Center
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text(
                text = when (state) {
                    GameState.GAME_OVER -> "💀 GAME OVER"
                    GameState.VICTORY -> "🎉 VICTORY!"
                    else -> ""
                },
                fontSize = 40.sp,
                fontWeight = FontWeight.Bold,
                color = if (state == GameState.GAME_OVER) Color.Red else Color.Green
            )
            Text("最终得分: $score", color = Color.White, fontSize = 20.sp)
            Spacer(Modifier.height(20.dp))
            Row {
                Button(onClick = onRestart, modifier = Modifier.padding(4.dp)) {
                    Text("🔄 重新开始")
                }
                Button(onClick = onExit, modifier = Modifier.padding(4.dp), colors = ButtonDefaults.buttonColors(containerColor = Color.Gray)) {
                    Text("🏠 返回菜单")
                }
            }
        }
    }
}

// ======================
// 游戏画布 (优化后的版本 - 移除了按钮)
// ======================
// 移除了 onBackToMenu, isPaused, onTogglePause 三个参数
@Composable
fun GameCanvas(
    playerTank: Tank,
    enemyTanks: List<Tank>,
    bullets: List<Bullet>,
    walls: List<Wall>,
    gameWidthDp: Dp,
    gameHeightDp: Dp
    // 移除了按钮相关的参数
) {
    Canvas(
        modifier = Modifier
            .size(gameWidthDp, gameHeightDp)
            .border(2.dp, Color.Gray)
    ) {
        walls.forEach { wall ->
            drawRect(
                color = Color.Gray,
                topLeft = Offset(wall.x.toFloat(), wall.y.toFloat()),
                size = androidx.compose.ui.geometry.Size(wall.width.toFloat(), wall.height.toFloat())
            )
        }

        if (playerTank.isAlive) {
            drawTank(playerTank)
        }

        enemyTanks.forEach { tank ->
            if (tank.isAlive) {
                drawTank(tank)
            }
        }

        bullets.forEach { bullet ->
            drawCircle(
                color = bullet.color,
                radius = BULLET_RADIUS,
                center = Offset(bullet.x.toFloat(), bullet.y.toFloat())
            )
        }
    }

    // 移除了按钮绘制逻辑
}

fun androidx.compose.ui.graphics.drawscope.DrawScope.drawTank(tank: Tank) {
    val centerX = tank.x + GRID_SIZE / 2f
    val centerY = tank.y + GRID_SIZE / 2f

    drawCircle(
        color = tank.color,
        radius = GRID_SIZE / 2.2f,
        center = Offset(centerX, centerY)
    )

    val barrelLength = GRID_SIZE / 1.8f
    val (dx, dy) = when (tank.direction) {
        Direction.UP -> Pair(0f, -barrelLength)
        Direction.DOWN -> Pair(0f, barrelLength)
        Direction.LEFT -> Pair(-barrelLength, 0f)
        Direction.RIGHT -> Pair(barrelLength, 0f)
    }

    drawLine(
        color = Color.Black,
        start = Offset(centerX, centerY),
        end = Offset(centerX + dx, centerY + dy),
        strokeWidth = 8f
    )
}

// ======================
// 控制按钮
// ======================
@Composable
fun GameControls(
    onMove: (Direction) -> Unit,
    onStopMove: () -> Unit,
    onFire: () -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        horizontalArrangement = Arrangement.SpaceAround,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Box(
            modifier = Modifier
                .size(150.dp)
                .background(Color.LightGray.copy(alpha = 0.5f), shape = CircleShape)
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = { },
                        onDragEnd = { onStopMove() },
                        onDragCancel = { onStopMove() },
                        onDrag = { change, _ ->
                            change.consume()
                            val position = change.position
                            val centerX = size.width / 2f
                            val centerY = size.height / 2f
                            val dx = position.x - centerX
                            val dy = position.y - centerY

                            val absDx = kotlin.math.abs(dx)
                            val absDy = kotlin.math.abs(dy)

                            if (absDx > 20 || absDy > 20) {
                                val direction = if (absDx > absDy) {
                                    if (dx > 0) Direction.RIGHT else Direction.LEFT
                                } else {
                                    if (dy > 0) Direction.DOWN else Direction.UP
                                }
                                onMove(direction)
                            }
                        }
                    )
                },
            contentAlignment = Alignment.Center
        ) {
            Box(
                modifier = Modifier
                    .size(50.dp)
                    .background(Color.DarkGray, shape = CircleShape)
            )
        }

        Button (
            onClick = onFire,
            modifier = Modifier
                .size(100.dp)
                .padding(start = 20.dp),
            shape = CircleShape,
            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3))
        ) {
            Text("开火", fontSize = 18.sp)
        }
    }
}

// ======================
// 辅助函数 (优化后)
// ======================
fun canMove(x: Int, y: Int, width: Int, height: Int, walls: List<Wall>, tanks: List<Tank>, selfId: String): Boolean {
    val objectRight = x + width
    val objectBottom = y + height

    if (x < 0 || y < 0 || objectRight > MAP_WIDTH_GRIDS * GRID_SIZE || objectBottom > MAP_HEIGHT_GRIDS * GRID_SIZE) return false

    for (wall in walls) {
        if (x < wall.x + wall.width &&
            objectRight > wall.x &&
            y < wall.y + wall.height &&
            objectBottom > wall.y) {
            return false
        }
    }

    for (tank in tanks) {
        if (tank.id != selfId && tank.isAlive) {
            if (x < tank.x + GRID_SIZE &&
                objectRight > tank.x &&
                y < tank.y + GRID_SIZE &&
                objectBottom > tank.y) {
                return false
            }
        }
    }

    return true
}

fun isColliding(x1: Int, y1: Int, x2: Int, y2: Int, size1: Int, size2: Int): Boolean {
    val centerX1 = x1 + size1 / 2
    val centerY1 = y1 + size1 / 2
    val radius1 = size1 / 2.2f

    val centerX2 = x2 + size2 / 2
    val centerY2 = y2 + size2 / 2
    val radius2 = size2 / 2.2f

    val distance = sqrt((centerX1 - centerX2).toDouble().pow(2) + (centerY1 - centerY2).toDouble().pow(2))
    return distance < (radius1 + radius2)
}

// 优化:新函数,生成指定数量且位置不重叠的敌方坦克
fun generateUniqueEnemyTanks(walls: List<Wall>, count: Int): List<Tank> {
    val enemyTanks = mutableSetOf<Tank>() // 使用 Set 避免自身重复
    val maxAttempts = count * 100 // 防止无限循环

    var attempts = 0
    while (enemyTanks.size < count && attempts < maxAttempts) {
        attempts++
        var x: Int
        var y: Int
        var isValidPosition = false
        var newTank: Tank? = null

        // 尝试生成一个有效位置的坦克
        repeat(100) { // 为单个坦克尝试100次找到不重叠的位置
            x = Random.nextInt(0, MAP_WIDTH_GRIDS) * GRID_SIZE
            y = Random.nextInt(0, MAP_HEIGHT_GRIDS) * GRID_SIZE

            // 检查是否与墙碰撞或在出生点区域
            val wallCollision = walls.any { wall ->
                x < wall.x + wall.width &&
                        x + GRID_SIZE > wall.x &&
                        y < wall.y + wall.height &&
                        y + GRID_SIZE > wall.y
            }
            val inSpawnArea = y >= (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE

            if (!wallCollision && !inSpawnArea) {
                // 检查是否与已生成的坦克重叠
                val tankCollision = enemyTanks.any { existingTank ->
                    x < existingTank.x + GRID_SIZE &&
                            x + GRID_SIZE > existingTank.x &&
                            y < existingTank.y + GRID_SIZE &&
                            y + GRID_SIZE > existingTank.y
                }

                if (!tankCollision) {
                    isValidPosition = true
                    newTank = Tank(
                        x = x,
                        y = y,
                        direction = Direction.entries.random(),
                        color = Color.Red
                    )
                    return@repeat // 找到有效位置,跳出循环
                }
            }
        }

        // 如果找到了有效位置且不与现有坦克重叠,则添加
        if (isValidPosition && newTank != null) {
            // 再次检查是否与集合中已有的坦克重叠(虽然上面检查了,但Set检查更安全)
            val finalCollision = enemyTanks.any { existingTank ->
                newTank.x < existingTank.x + GRID_SIZE &&
                        newTank.x + GRID_SIZE > existingTank.x &&
                        newTank.y < existingTank.y + GRID_SIZE &&
                        newTank.y + GRID_SIZE > existingTank.y
            }
            if(!finalCollision) {
                enemyTanks.add(newTank)
            }
        }
    }

    return enemyTanks.toList()
}


fun getBulletSpawnPosition(tankX: Int, tankY: Int, tankDirection: Direction): Pair<Int, Int> {
    val centerX = tankX + GRID_SIZE / 2
    val centerY = tankY + GRID_SIZE / 2
    val barrelLength = (GRID_SIZE / 1.8f).toInt()

    val (offsetX, offsetY) = when (tankDirection) {
        Direction.UP -> Pair(0, -barrelLength)
        Direction.DOWN -> Pair(0, barrelLength)
        Direction.LEFT -> Pair(-barrelLength, 0)
        Direction.RIGHT -> Pair(barrelLength, 0)
    }

    return Pair(centerX + offsetX, centerY + offsetY)
}

// 新增枚举类,用于标识游戏结束的原因
enum class GameEndReason {
    VICTORY,
    DEFEAT,
    QUIT
}

// ======================
// 预览
// ======================
@Preview(showBackground = true, backgroundColor = 0xFF000000, widthDp = 400, heightDp = 800)
@Composable
fun GameWithHUDPreview() {
    MaterialTheme {
        val previewPlayerTank = remember {
            Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
        }

        val previewWalls = remember {
            val wallThickness = GRID_SIZE
            val mapWidthPixels = MAP_WIDTH_GRIDS * GRID_SIZE
            val mapHeightPixels = MAP_HEIGHT_GRIDS * GRID_SIZE
            val edgeWalls = buildList {
                for (x in 0 until MAP_WIDTH_GRIDS) {
                    add(Wall(x * GRID_SIZE, 0))
                }
                for (x in 0 until MAP_WIDTH_GRIDS) {
                    add(Wall(x * GRID_SIZE, mapHeightPixels - wallThickness))
                }
                for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                    add(Wall(0, y * GRID_SIZE))
                }
                for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                    add(Wall(mapWidthPixels - wallThickness, y * GRID_SIZE))
                }
            }
            val innerWalls = listOf(
                Wall(5 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(6 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(9 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(10 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 10 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 11 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 12 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 8 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 9 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 10 * GRID_SIZE),
                Wall(3 * GRID_SIZE, 15 * GRID_SIZE),
                Wall(4 * GRID_SIZE, 15 * GRID_SIZE),
                Wall(5 * GRID_SIZE, 15 * GRID_SIZE)
            )
            edgeWalls + innerWalls
        }

        val previewEnemyTanks = remember { generateUniqueEnemyTanks(previewWalls, 10) }

        // 预览中的子弹也使用新的速度属性
        val previewBullets = remember {
            listOf(
                Bullet(x = 5 * GRID_SIZE, y = 10 * GRID_SIZE, direction = Direction.UP, ownerId = "player", color = Color.Red, speed = DEFAULT_BULLET_SPEED),
                Bullet(x = 8 * GRID_SIZE, y = 5 * GRID_SIZE, direction = Direction.RIGHT, ownerId = "enemy_1", color = Color.Blue, speed = DEFAULT_BULLET_SPEED)
            )
        }

        val previewStats = remember { PlayerStats(score = 15, lives = 2) }

        val density = LocalDensity.current
        val previewGameWidthDp: Dp = with(density) { (MAP_WIDTH_GRIDS * GRID_SIZE).toDp() }
        val previewGameHeightDp: Dp = with(density) { (MAP_HEIGHT_GRIDS * GRID_SIZE).toDp() }

        Box(modifier = Modifier.fillMaxSize()) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                modifier = Modifier.fillMaxSize()
            ) {
                Box(
                    modifier = Modifier
                        .weight(1f)
                        .fillMaxWidth(),
                    contentAlignment = Alignment.Center
                ) {
                    // 预览时只绘制 GameCanvas,不绘制按钮
                    GameCanvas(
                        playerTank = previewPlayerTank,
                        enemyTanks = previewEnemyTanks,
                        bullets = previewBullets,
                        walls = previewWalls,
                        gameWidthDp = previewGameWidthDp,
                        gameHeightDp = previewGameHeightDp
                    )
                }

                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(Color.DarkGray)
                        .padding(8.dp),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    Text("分数: ${previewStats.score}", color = Color.Yellow, fontSize = 16.sp)
                    Text("生命: ${previewStats.lives}", color = Color.Red, fontSize = 16.sp)
                }

                Column(modifier = Modifier.fillMaxWidth()) {
                    Row(
                        modifier = Modifier.padding(16.dp),
                        horizontalArrangement = Arrangement.SpaceAround,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Box(
                            modifier = Modifier
                                .size(150.dp)
                                .background(Color.LightGray.copy(alpha = 0.5f), shape = CircleShape),
                            contentAlignment = Alignment.Center
                        ) {
                            Box(
                                modifier = Modifier
                                    .size(50.dp)
                                    .background(Color.DarkGray, shape = CircleShape)
                            )
                        }
                        Button (
                            onClick = { },
                            modifier = Modifier
                                .size(100.dp)
                                .padding(start = 20.dp),
                            shape = CircleShape,
                            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3))
                        ) {
                            Text("开火", fontSize = 18.sp)
                        }
                    }

                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(8.dp),
                        horizontalArrangement = Arrangement.SpaceEvenly
                    ) {
                        Button(onClick = { }, modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp)) {
                            Text("⏸️ 暂停游戏", fontSize = 14.sp)
                        }
                        Button(
                            onClick = { },
                            modifier = Modifier
                                .weight(1f)
                                .padding(horizontal = 4.dp),
                            colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
                        ) {
                            Text("🏠 结束游戏", fontSize = 14.sp)
                        }
                    }
                }
            }

            Box(
                modifier = Modifier.fillMaxSize().background(Color.Black.copy(alpha = 0.3f)),
                contentAlignment = Alignment.TopStart
            ) {
                Text(
                    "🖼️ UI 预览模式",
                    color = Color.White,
                    fontSize = 16.sp,
                    modifier = Modifier.padding(8.dp)
                )
            }
        }
    }
}

@Preview(showBackground = true, widthDp = 400, heightDp = 800)
@Composable
fun MenuPreview() {
    // 预览更新后的菜单界面
    GameMenuScreen(
        scoreRepository = ScoreRepository(LocalContext.current), // 预览中创建实例
        onStartGame = {}
    )
}

// ======================
// 主题
// ======================
@Composable
fun TankBattleTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = lightColorScheme(
            primary = Color(0xFF006064),
            secondary = Color(0xFF00B8D4),
            // error = Color.Red // 可以自定义错误颜色
        ),
        typography = Typography(
            bodyLarge = androidx.compose.material3.Typography().bodyLarge.copy(fontSize = 16.sp)
        ),
        content = content
    )
}

ScoreRepository.kt代码如下:

package com.example.myapplication

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

// 使用扩展属性创建 DataStore
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "game_scores")

// 定义 Preferences Key
private val SCORES_KEY = stringPreferencesKey("scores_list")

/**
 * 表示单个游戏成绩
 */
data class GameScore(val score: Int, val timestamp: String)

/**
 * 成绩管理仓库
 */
class ScoreRepository(private val context: Context) {

    private val dataStore = context.dataStore

    /**
     * 流式返回所有历史成绩(按时间倒序)
     */
    val scoresFlow: Flow<List<GameScore>> = dataStore.data
        .map { preferences ->
            val scoresString = preferences[SCORES_KEY] ?: ""
            parseScores(scoresString)
        }

    /**
     * 解析存储的字符串为 GameScore 列表
     * 格式:score1@timestamp1|score2@timestamp2
     * 使用 '@' 分隔 score 和 timestamp,避免 ISO 时间中的 ':' 冲突
     */
    private fun parseScores(scoresString: String): List<GameScore> {
        if (scoresString.isEmpty()) return emptyList()

        return scoresString.split('|')
            .mapNotNull { entry ->
                val index = entry.indexOf('@')
                if (index == -1) return@mapNotNull null

                val scoreStr = entry.substring(0, index)
                val timestamp = entry.substring(index + 1)

                val score = scoreStr.toIntOrNull() ?: return@mapNotNull null

                GameScore(score, timestamp)
            }
            .sortedByDescending { it.timestamp } // 按时间倒序
    }

    /**
     * 添加新成绩
     */
    suspend fun addScore(score: Int) {
        val timestamp = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        val newEntry = "$score@$timestamp" // 使用 '@' 分隔,避免 ':' 冲突

        dataStore.edit { preferences ->
            val current = preferences[SCORES_KEY] ?: ""
            val updated = if (current.isEmpty()) {
                newEntry
            } else {
                "$newEntry|$current" // 最新在前
            }
            preferences[SCORES_KEY] = updated
        }
    }

    /**
     * 清空所有成绩
     */
    suspend fun clearScores() {
        dataStore.edit { preferences ->
            preferences.remove(SCORES_KEY)
        }
    }
}

MainActivity代码优化,防止击毁一辆坦克得2分或者以上,下面是优化代码:

package com.example.myapplication

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.pow
import kotlin.math.sqrt
import kotlin.random.Random

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TankBattleTheme {
                Box(modifier = Modifier.fillMaxSize()) {
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(
                                top = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() },
                                bottom = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
                            ),
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        TankBattleGame()
                    }
                }
            }
        }
    }
}

// ======================
// 数据模型
// ======================
data class Tank(
    val id: String = "tank_${Random.nextLong()}",
    var x: Int,
    var y: Int,
    var direction: Direction,
    val color: Color,
    val isPlayer: Boolean = false,
    var isAlive: Boolean = true
)

data class Bullet(
    var x: Int,
    var y: Int,
    val direction: Direction,
    val ownerId: String,
    val color: Color = Color.Yellow,
    val speed: Int // 添加子弹速度属性
)

data class Wall(val x: Int, val y: Int, val width: Int = GRID_SIZE, val height: Int = GRID_SIZE)

enum class Direction { UP, DOWN, LEFT, RIGHT }

data class PlayerStats(
    var score: Int = 0,
    var lives: Int = 1 // 基础生命值改为1
)

// 优化:扩展游戏设置,包含更多参数
data class GameSettings(
    val playerTankSpeed: Int,     // 玩家坦克速度
    val enemyTankSpeed: Int,      // 敌方坦克速度
    val playerBulletSpeed: Int,   // 玩家子弹速度
    val enemyBulletSpeed: Int,    // 敌方子弹速度
    val pointsPerExtraLife: Int   // 加命所需分数
)

// 修改:GameState 添加 RESTARTING 状态
enum class GameState { PLAYING, PAUSED, GAME_OVER, VICTORY, MENU, RESTARTING }

// ======================
// 常量 (适配小米手机)
// ======================
const val GRID_SIZE = 45
const val MAP_WIDTH_GRIDS = 20
const val MAP_HEIGHT_GRIDS = 20
const val DEFAULT_BULLET_SPEED = 5
const val GAME_LOOP_DELAY = 50L
const val BULLET_RADIUS = 6f

// ======================
// 主游戏入口 (优化后)
// ======================
@Composable
fun TankBattleGame() {
    val context = LocalContext.current
    // 优化:创建 ScoreRepository 实例
    val scoreRepository = remember { ScoreRepository(context) }
    var gameState by remember { mutableStateOf(GameState.MENU) }
    // 优化:初始化设置包含所有速度参数
    var gameSettings by remember {
        mutableStateOf(
            GameSettings(
                playerTankSpeed = 2,
                enemyTankSpeed = 2,
                playerBulletSpeed = DEFAULT_BULLET_SPEED,
                enemyBulletSpeed = DEFAULT_BULLET_SPEED,
                pointsPerExtraLife = 10
            )
        )
    }
    // 优化:用于存储游戏结束时的最终分数
    var finalScore by remember { mutableStateOf(0) }
    // 优化:用于存储游戏结束原因
    var gameEndReason by remember { mutableStateOf<GameEndReason?>(null) }

    // 优化:处理分数保存的副作用
    // *** 修改:这是唯一保存分数的地方 ***
    LaunchedEffect(finalScore, gameEndReason) {
        if (gameEndReason != null) {
            // 当 finalScore 或 gameEndReason 更新时,保存分数
            scoreRepository.addScore(finalScore)
            // 显示 Toast 提示
            val message = when (gameEndReason) {
                GameEndReason.VICTORY -> "恭喜胜利!最终得分: $finalScore"
                GameEndReason.DEFEAT -> "游戏结束!最终得分: $finalScore"
                GameEndReason.QUIT -> "游戏结束,得分: $finalScore"
                null -> ""
            }
            if (message.isNotEmpty()) {
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
            }
            // 重置原因,防止重复保存
            gameEndReason = null
        }
    }

    when (gameState) {
        GameState.MENU -> {
            // 优化:传递 ScoreRepository 到菜单界面
            GameMenuScreen(
                scoreRepository = scoreRepository,
                onStartGame = { settings ->
                    gameSettings = settings
                    gameState = GameState.PLAYING
                }
            )
        }
        GameState.PLAYING, GameState.PAUSED, GameState.GAME_OVER, GameState.VICTORY, GameState.RESTARTING -> {
            val density = LocalDensity.current
            val gameWidthDp: Dp = with(density) { (MAP_WIDTH_GRIDS * GRID_SIZE).toDp() }
            val gameHeightDp: Dp = with(density) { (MAP_HEIGHT_GRIDS * GRID_SIZE).toDp() }

            RunningGame(
                scoreRepository = scoreRepository, // 传递 scoreRepository
                gameSettings = gameSettings,
                gameState = gameState,
                gameWidthDp = gameWidthDp,
                gameHeightDp = gameHeightDp,
                onBackToMenu = { score, reason ->
                    // *** 修改:更新最终分数和原因,触发保存 ***
                    finalScore = score
                    gameEndReason = reason
                    gameState = GameState.MENU
                },
                onTogglePause = {
                    gameState = if (gameState == GameState.PLAYING) GameState.PAUSED else GameState.PLAYING
                },
                onGameEnd = { score, reason -> // 新增回调
                    // *** 修改:只负责更新主游戏状态和显示提示,不保存分数 ***
                    // 更新主游戏状态
                    gameState = when (reason) {
                        GameEndReason.VICTORY -> GameState.VICTORY
                        GameEndReason.DEFEAT -> GameState.GAME_OVER
                        else -> gameState // QUIT 不改变主状态机,由 onBackToMenu 处理
                    }
                    // 注意:Toast 移到了 LaunchedEffect 中统一处理
                },
                // 新增 onRestart 回调
                onRestart = {
                    gameState = GameState.RESTARTING
                }
            )
        }
    }
}

// ======================
// 菜单界面 (优化后)
// ======================
@Composable
fun GameMenuScreen(
    scoreRepository: ScoreRepository,
    onStartGame: (GameSettings) -> Unit
) {
    var initialSettings by remember {
        mutableStateOf(
            GameSettings(
                playerTankSpeed = 2,
                enemyTankSpeed = 2,
                playerBulletSpeed = DEFAULT_BULLET_SPEED,
                enemyBulletSpeed = DEFAULT_BULLET_SPEED,
                pointsPerExtraLife = 10
            )
        )
    }

    var playerSpeed by remember { mutableStateOf(initialSettings.playerTankSpeed.toString()) }
    var enemySpeed by remember { mutableStateOf(initialSettings.enemyTankSpeed.toString()) }
    var playerBulletSpeed by remember { mutableStateOf(initialSettings.playerBulletSpeed.toString()) }
    var enemyBulletSpeed by remember { mutableStateOf(initialSettings.enemyBulletSpeed.toString()) }
    var pointsForLife by remember { mutableStateOf(initialSettings.pointsPerExtraLife.toString()) }

    val playerSpeedInt = playerSpeed.toIntOrNull() ?: 2
    val enemySpeedInt = enemySpeed.toIntOrNull() ?: 2
    val playerBulletSpeedInt = playerBulletSpeed.toIntOrNull() ?: DEFAULT_BULLET_SPEED
    val enemyBulletSpeedInt = enemyBulletSpeed.toIntOrNull() ?: DEFAULT_BULLET_SPEED
    val pointsForLifeInt = pointsForLife.toIntOrNull() ?: 10

    val isPlayerSpeedValid = playerSpeedInt in 1..8
    val isEnemySpeedValid = enemySpeedInt in 1..8
    val isPlayerBulletSpeedValid = playerBulletSpeedInt in 1..15
    val isEnemyBulletSpeedValid = enemyBulletSpeedInt in 1..15
    val isPointsValid = pointsForLifeInt >= 5 && pointsForLifeInt % 5 == 0

    val allValid = isPlayerSpeedValid && isEnemySpeedValid && isPlayerBulletSpeedValid && isEnemyBulletSpeedValid && isPointsValid

    // 优化:获取历史成绩的 Flow 并收集状态
    val scores by scoreRepository.scoresFlow.collectAsState(initial = emptyList())
    val coroutineScope = rememberCoroutineScope()

    MaterialTheme {
        Surface(color = Color.Black, modifier = Modifier.fillMaxSize()) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(20.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Text("🎮 坦克大战", color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold)
                Spacer(Modifier.height(10.dp))

                // 优化:使用 LazyColumn 包裹设置项和历史记录
                LazyColumn(
                    modifier = Modifier
                        .fillMaxWidth()
                        .weight(1f),
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    // 设置项
                    item {
                        OutlinedTextField(
                            value = playerSpeed,
                            onValueChange = { playerSpeed = it },
                            label = { Text("玩家坦克速度 (1-8)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPlayerSpeedValid
                        )
                        if (!isPlayerSpeedValid) {
                            Text("⚠️ 玩家速度必须在 1-8 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = enemySpeed,
                            onValueChange = { enemySpeed = it },
                            label = { Text("敌方坦克速度 (1-8)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isEnemySpeedValid
                        )
                        if (!isEnemySpeedValid) {
                            Text("⚠️ 敌方速度必须在 1-8 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = playerBulletSpeed,
                            onValueChange = { playerBulletSpeed = it },
                            label = { Text("玩家子弹速度 (1-15)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPlayerBulletSpeedValid
                        )
                        if (!isPlayerBulletSpeedValid) {
                            Text("⚠️ 玩家子弹速度必须在 1-15 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = enemyBulletSpeed,
                            onValueChange = { enemyBulletSpeed = it },
                            label = { Text("敌方子弹速度 (1-15)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isEnemyBulletSpeedValid
                        )
                        if (!isEnemyBulletSpeedValid) {
                            Text("⚠️ 敌方子弹速度必须在 1-15 之间", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }
                    item {
                        OutlinedTextField(
                            value = pointsForLife,
                            onValueChange = { pointsForLife = it },
                            label = { Text("多少分加一条命 (≥5 且 5 的倍数)", color = Color.White) },
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = Color.White,
                                unfocusedTextColor = Color.White,
                                cursorColor = Color.White,
                                focusedLabelColor = Color.White,
                                unfocusedLabelColor = Color.Gray,
                                focusedBorderColor = Color.White,
                                unfocusedBorderColor = Color.Gray
                            ),
                            modifier = Modifier.fillMaxWidth(),
                            isError = !isPointsValid
                        )
                        if (!isPointsValid) {
                            Text("⚠️ 分数必须 ≥5 且是 5 的倍数", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
                        }
                    }

                    // 历史记录标题
                    item {
                        Spacer(Modifier.height(10.dp))
                        Text("📜 历史战绩", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.Medium)
                        Divider(color = Color.Gray, thickness = 1.dp)
                    }

                    // 历史记录列表
                    items(scores) { gameScore ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(vertical = 4.dp),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Text("得分: ${gameScore.score}", color = Color.Yellow)
                            Text(gameScore.timestamp, color = Color.LightGray, fontSize = 12.sp)
                        }
                    }

                    // 清除按钮 (放在列表末尾)
                    item {
                        Spacer(Modifier.height(10.dp))
                        Button(
                            onClick = {
                                coroutineScope.launch {
                                    scoreRepository.clearScores()
                                }
                            },
                            colors = ButtonDefaults.buttonColors(containerColor = Color.Red),
                            modifier = Modifier.align(Alignment.End)
                        ) {
                            Icon(Icons.Default.Delete, contentDescription = "清除", tint = Color.White)
                            Spacer(Modifier.width(4.dp))
                            Text("清除所有记录")
                        }
                    }
                }

                Spacer(Modifier.height(10.dp))

                Button(
                    onClick = {
                        if (allValid) {
                            onStartGame(
                                GameSettings(
                                    playerTankSpeed = playerSpeedInt,
                                    enemyTankSpeed = enemySpeedInt,
                                    playerBulletSpeed = playerBulletSpeedInt,
                                    enemyBulletSpeed = enemyBulletSpeedInt,
                                    pointsPerExtraLife = pointsForLifeInt
                                )
                            )
                        }
                    },
                    enabled = allValid,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text("开始游戏")
                }
            }
        }
    }
}


// ======================
// 主游戏逻辑 (修改后的版本)
// ======================
@Composable
fun RunningGame(
    scoreRepository: ScoreRepository, // 新增参数
    gameSettings: GameSettings,
    gameState: GameState,
    gameWidthDp: Dp,
    gameHeightDp: Dp,
    onBackToMenu: (score: Int, reason: GameEndReason) -> Unit, // 修改:此回调只负责通知,不负责保存
    onTogglePause: () -> Unit,
    onGameEnd: (score: Int, reason: GameEndReason) -> Unit, // 新增回调参数
    onRestart: () -> Unit // 新增回调参数
) {
    val context = LocalContext.current
    // 移除了内部的 scoreRepository 创建
    val edgeWalls = remember {
        val wallThickness = GRID_SIZE
        val mapWidthPixels = MAP_WIDTH_GRIDS * GRID_SIZE
        val mapHeightPixels = MAP_HEIGHT_GRIDS * GRID_SIZE
        buildList {
            for (x in 0 until MAP_WIDTH_GRIDS) {
                add(Wall(x * GRID_SIZE, 0))
            }
            for (x in 0 until MAP_WIDTH_GRIDS) {
                add(Wall(x * GRID_SIZE, mapHeightPixels - wallThickness))
            }
            for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                add(Wall(0, y * GRID_SIZE))
            }
            for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                add(Wall(mapWidthPixels - wallThickness, y * GRID_SIZE))
            }
        }
    }
    val innerWalls = remember {
        listOf(
            Wall(5 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(6 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(9 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(10 * GRID_SIZE, 5 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 10 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 11 * GRID_SIZE),
            Wall(7 * GRID_SIZE, 12 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 8 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 9 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 10 * GRID_SIZE),
            Wall(3 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(4 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(5 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(15 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(16 * GRID_SIZE, 15 * GRID_SIZE),
            Wall(17 * GRID_SIZE, 15 * GRID_SIZE)
        )
    }
    val walls = remember { edgeWalls + innerWalls }
    var playerTank by remember {
        mutableStateOf(
            Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
        )
    }
    // 优化:使用 generateUniqueEnemyTanks 生成不重叠的坦克
    var enemyTanks by remember {
        mutableStateOf(
            generateUniqueEnemyTanks(walls, 10)
        )
    }
    val bullets = remember { mutableStateListOf<Bullet>() }
    var currentGameState by remember { mutableStateOf(gameState) }
    var playerMovingDirection by remember { mutableStateOf<Direction?>(null) }
    var stats by remember { mutableStateOf(PlayerStats()) }
    var lastExtraLifeScore by remember { mutableStateOf(0) }

    // 修复:将LaunchedEffect移到@Composable函数内部,并使用状态变量控制
    // 修改:这个 LaunchedEffect 监听 currentGameState 的变化来控制游戏循环
    LaunchedEffect(currentGameState) {
        while (currentGameState == GameState.PLAYING || currentGameState == GameState.PAUSED) {
            if (currentGameState == GameState.PLAYING) {
                // 玩家移动
                playerMovingDirection?.let { dir ->
                    val nextX = playerTank.x + when (dir) {
                        Direction.LEFT -> -gameSettings.playerTankSpeed
                        Direction.RIGHT -> gameSettings.playerTankSpeed
                        else -> 0
                    }
                    val nextY = playerTank.y + when (dir) {
                        Direction.UP -> -gameSettings.playerTankSpeed
                        Direction.DOWN -> gameSettings.playerTankSpeed
                        else -> 0
                    }
                    playerTank = playerTank.copy(direction = dir)
                    if (canMove(nextX, nextY, GRID_SIZE, GRID_SIZE, walls, listOf(playerTank) + enemyTanks, playerTank.id)) {
                        playerTank = playerTank.copy(x = nextX, y = nextY)
                    }
                }
                // 敌方坦克移动
                enemyTanks = enemyTanks.map { tank ->
                    if (!tank.isAlive) return@map tank
                    var newTank = tank
                    if (Random.nextInt(100) < 5) {
                        newTank = newTank.copy(direction = Direction.entries.random())
                    }
                    // 敌方坦克开火,子弹为蓝色,使用敌方子弹速度设置
                    if (Random.nextInt(100) < 2) {
                        val (bulletX, bulletY) = getBulletSpawnPosition(tank.x, tank.y, tank.direction)
                        bullets.add(Bullet(x = bulletX, y = bulletY, direction = tank.direction, ownerId = tank.id, color = Color.Blue, speed = gameSettings.enemyBulletSpeed))
                    }
                    val nextX = newTank.x + when (newTank.direction) {
                        Direction.LEFT -> -gameSettings.enemyTankSpeed
                        Direction.RIGHT -> gameSettings.enemyTankSpeed
                        else -> 0
                    }
                    val nextY = newTank.y + when (newTank.direction) {
                        Direction.UP -> -gameSettings.enemyTankSpeed
                        Direction.DOWN -> gameSettings.enemyTankSpeed
                        else -> 0
                    }
                    if (canMove(nextX, nextY, GRID_SIZE, GRID_SIZE, walls, listOf(playerTank) + enemyTanks, newTank.id)) {
                        newTank.copy(x = nextX, y = nextY)
                    } else {
                        val newDirection = when(newTank.direction) {
                            Direction.UP -> Direction.DOWN
                            Direction.DOWN -> Direction.UP
                            Direction.LEFT -> Direction.RIGHT
                            Direction.RIGHT -> Direction.LEFT
                        }
                        newTank.copy(direction = newDirection)
                    }
                }
                // 子弹移动
                val updatedBullets = bullets.map { bullet ->
                    val newX = bullet.x + when (bullet.direction) {
                        Direction.LEFT -> -bullet.speed
                        Direction.RIGHT -> bullet.speed
                        else -> 0
                    }
                    val newY = bullet.y + when (bullet.direction) {
                        Direction.UP -> -bullet.speed
                        Direction.DOWN -> bullet.speed
                        else -> 0
                    }
                    bullet.copy(x = newX, y = newY)
                }
                bullets.clear()
                bullets.addAll(updatedBullets)
                // 碰撞检测
                val bulletsToRemove = mutableStateListOf<Bullet>()
                val enemiesToKill = mutableStateListOf<Tank>()

                // 修改:创建一个集合来跟踪本帧已被标记为击毁的坦克ID
                val killedTankIds = mutableSetOf<String>()

                for (bullet in bullets) {
                    // 子弹与墙碰撞
                    if (walls.any { wall ->
                            bullet.x >= wall.x && bullet.x < wall.x + wall.width &&
                                    bullet.y >= wall.y && bullet.y < wall.y + wall.height
                        }) {
                        bulletsToRemove.add(bullet)
                        continue // 处理完墙碰撞后,跳过后续检查
                    }
                    // 子弹与坦克碰撞
                    // 玩家子弹击中敌方坦克
                    if (bullet.ownerId == playerTank.id) {
                        for (tank in enemyTanks) {
                            // 修改:检查坦克是否还活着且本帧未被标记为击毁
                            if (tank.isAlive && !killedTankIds.contains(tank.id) &&
                                isColliding(bullet.x, bullet.y, tank.x, tank.y, 2, GRID_SIZE)) {
                                bulletsToRemove.add(bullet)
                                enemiesToKill.add(tank)
                                // 修改:将坦克ID添加到已击毁集合中
                                killedTankIds.add(tank.id)
                                break // 一颗子弹只能击毁一个目标
                            }
                        }
                    }
                    // 敌方子弹击中玩家坦克
                    else if (playerTank.isAlive && isColliding(bullet.x, bullet.y, playerTank.x, playerTank.y, 2, GRID_SIZE)) {
                        bulletsToRemove.add(bullet)
                        playerTank.isAlive = false
                        // 不需要 break,因为敌方子弹不能击中其他敌方坦克
                    }
                    // 敌方子弹击中敌方坦克的情况被忽略(即敌方坦克不会自相残杀)
                }
                // 优化:只有玩家消灭敌方坦克才加分
                if (enemiesToKill.isNotEmpty()) {
                    enemiesToKill.forEach { it.isAlive = false }
                    // 修改:确保每辆坦克只计1分,不管被多少子弹击中
                    stats.score += enemiesToKill.size // 加分
                    // 优化:检查是否达到加命分数
                    val fullSegments = stats.score / gameSettings.pointsPerExtraLife
                    val prevSegments = lastExtraLifeScore / gameSettings.pointsPerExtraLife
                    if (fullSegments > prevSegments) {
                        stats.lives += 1 // 生命值可以无限增加
                        lastExtraLifeScore = stats.score
                    }
                }
                bullets.removeAll(bulletsToRemove.toSet())

                // --- 修改开始 ---
                if (!playerTank.isAlive) {
                    stats.lives-- // 减命
                    if (stats.lives <= 0) {
                        // *** 修改:游戏结束时调用回调,但不保存分数 ***
                        onGameEnd(stats.score, GameEndReason.DEFEAT)
                    } else {
                        // 优化:不立即复活,而是等待重新开始
                        // playerTank = playerTank.copy(isAlive = true, x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE, y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE)
                    }
                } else if (enemyTanks.all { !it.isAlive }) {
                    // *** 修改:胜利时也调用回调,但不保存分数 ***
                    onGameEnd(stats.score, GameEndReason.VICTORY)
                }
                // --- 修改结束 ---
            }
            delay(GAME_LOOP_DELAY)
        }
    }

    // --- 优化:监听 gameState 变化来更新 currentGameState ---
    LaunchedEffect(gameState) {
        currentGameState = gameState
        // 新增:处理 RESTARTING 状态
        if (gameState == GameState.RESTARTING) {
            // 重置游戏状态和数据
            playerTank = Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
            enemyTanks = generateUniqueEnemyTanks(walls, 10)
            bullets.clear()
            // 优化:重置生命值为1
            stats = PlayerStats(lives = 1, score = 0) // 重置生命值和分数
            lastExtraLifeScore = 0
            currentGameState = GameState.PLAYING
        }
    }

    Box(modifier = Modifier.fillMaxSize()) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier.fillMaxSize()
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxWidth(),
                contentAlignment = Alignment.Center
            ) {

                // --- 优化:移除 Canvas 上的按钮绘制 ---
                // 绘制游戏画布
                GameCanvas(
                    playerTank = playerTank,
                    enemyTanks = enemyTanks,
                    bullets = bullets,
                    walls = walls,
                    gameWidthDp = gameWidthDp,
                    gameHeightDp = gameHeightDp
                )

                // --- 优化:移除在 Canvas 上绘制的按钮 ---

                // --- 新增:使用 GameOverOverlay ---
                // 游戏结束或胜利时显示覆盖层
                if (currentGameState == GameState.GAME_OVER || currentGameState == GameState.VICTORY) {
                    GameOverOverlay(
                        state = currentGameState,
                        score = stats.score,
                        onRestart = {
                            // 调用 onRestart 回调
                            onRestart()
                        },
                        onExit = {
                            // *** 修改:调用原始的返回菜单函数并传递分数和原因 ***
                            // 这会触发 TankBattleGame 中的 LaunchedEffect 来保存分数
                            onBackToMenu(stats.score, if(currentGameState == GameState.VICTORY) GameEndReason.VICTORY else GameEndReason.DEFEAT)
                        }
                    )
                }
                // --- 新增结束 ---
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(Color.DarkGray)
                    .padding(8.dp),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Text("分数: ${stats.score}", color = Color.Yellow, fontSize = 16.sp)
                Text("生命: ${stats.lives}", color = Color.Red, fontSize = 16.sp)
            }
            Column(modifier = Modifier.fillMaxWidth()) {
                GameControls(
                    onMove = { playerMovingDirection = it },
                    onStopMove = { playerMovingDirection = null },
                    onFire = {
                        if (currentGameState == GameState.PLAYING) {
                            val (bulletX, bulletY) = getBulletSpawnPosition(playerTank.x, playerTank.y, playerTank.direction)
                            // 玩家坦克开火,子弹为红色,使用玩家子弹速度设置
                            bullets.add(Bullet(x = bulletX, y = bulletY, direction = playerTank.direction, ownerId = playerTank.id, color = Color.Red, speed = gameSettings.playerBulletSpeed))
                        }
                    }
                )
                // --- 新增开始 ---
                // 按钮位于开火按钮下方
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(8.dp),
                    horizontalArrangement = Arrangement.SpaceEvenly
                ) {
                    Button(
                        onClick = onTogglePause,
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp)
                    ) {
                        Text(
                            if (currentGameState == GameState.PAUSED) "▶️ 继续游戏" else "⏸️ 暂停游戏",
                            fontSize = 14.sp
                        )
                    }
                    // 修改:添加确认弹窗
                    val openDialog = remember { mutableStateOf(false) }
                    Button(
                        onClick = { openDialog.value = true }, // 点击时打开弹窗
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp),
                        colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
                    ) {
                        Text("🏠 结束游戏", fontSize = 14.sp)
                    }
                    // 弹窗内容
                    if (openDialog.value) {
                        AlertDialog(
                            onDismissRequest = { openDialog.value = false },
                            title = { Text("确认退出") },
                            text = { Text("确定要结束游戏并返回菜单吗?") },
                            confirmButton = {
                                TextButton(
                                    onClick = {
                                        openDialog.value = false
                                        // *** 修改:确认后调用回调 ***
                                        // 这会触发 TankBattleGame 中的 LaunchedEffect 来保存分数
                                        onBackToMenu(stats.score, GameEndReason.QUIT)
                                    }
                                ) {
                                    Text("确定")
                                }
                            },
                            dismissButton = {
                                TextButton(
                                    onClick = { openDialog.value = false }
                                ) {
                                    Text("取消")
                                }
                            }
                        )
                    }
                }
                // --- 新增结束 ---
            }
        }
    }
}


@Composable
fun GameOverOverlay(
    state: GameState,
    score: Int,
    onRestart: () -> Unit,
    onExit: () -> Unit
) {
    Box(
        modifier = Modifier.fillMaxSize().background(Color.Black.copy(alpha = 0.8f)),
        contentAlignment = Alignment.Center
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text(
                text = when (state) {
                    GameState.GAME_OVER -> "💀 GAME OVER"
                    GameState.VICTORY -> "🎉 VICTORY!"
                    else -> ""
                },
                fontSize = 40.sp,
                fontWeight = FontWeight.Bold,
                color = if (state == GameState.GAME_OVER) Color.Red else Color.Green
            )
            Text("最终得分: $score", color = Color.White, fontSize = 20.sp)
            Spacer(Modifier.height(20.dp))
            Row {
                Button(onClick = onRestart, modifier = Modifier.padding(4.dp)) {
                    Text("🔄 重新开始")
                }
                Button(onClick = onExit, modifier = Modifier.padding(4.dp), colors = ButtonDefaults.buttonColors(containerColor = Color.Gray)) {
                    Text("🏠 返回菜单")
                }
            }
        }
    }
}

// ======================
// 游戏画布 (优化后的版本 - 移除了按钮)
// ======================
// 移除了 onBackToMenu, isPaused, onTogglePause 三个参数
@Composable
fun GameCanvas(
    playerTank: Tank,
    enemyTanks: List<Tank>,
    bullets: List<Bullet>,
    walls: List<Wall>,
    gameWidthDp: Dp,
    gameHeightDp: Dp
    // 移除了按钮相关的参数
) {
    Canvas(
        modifier = Modifier
            .size(gameWidthDp, gameHeightDp)
            .border(2.dp, Color.Gray)
    ) {
        walls.forEach { wall ->
            drawRect(
                color = Color.Gray,
                topLeft = Offset(wall.x.toFloat(), wall.y.toFloat()),
                size = androidx.compose.ui.geometry.Size(wall.width.toFloat(), wall.height.toFloat())
            )
        }

        if (playerTank.isAlive) {
            drawTank(playerTank)
        }

        enemyTanks.forEach { tank ->
            if (tank.isAlive) {
                drawTank(tank)
            }
        }

        bullets.forEach { bullet ->
            drawCircle(
                color = bullet.color,
                radius = BULLET_RADIUS,
                center = Offset(bullet.x.toFloat(), bullet.y.toFloat())
            )
        }
    }
}

fun androidx.compose.ui.graphics.drawscope.DrawScope.drawTank(tank: Tank) {
    val centerX = tank.x + GRID_SIZE / 2f
    val centerY = tank.y + GRID_SIZE / 2f

    drawCircle(
        color = tank.color,
        radius = GRID_SIZE / 2.2f,
        center = Offset(centerX, centerY)
    )

    val barrelLength = GRID_SIZE / 1.8f
    val (dx, dy) = when (tank.direction) {
        Direction.UP -> Pair(0f, -barrelLength)
        Direction.DOWN -> Pair(0f, barrelLength)
        Direction.LEFT -> Pair(-barrelLength, 0f)
        Direction.RIGHT -> Pair(barrelLength, 0f)
    }

    drawLine(
        color = Color.Black,
        start = Offset(centerX, centerY),
        end = Offset(centerX + dx, centerY + dy),
        strokeWidth = 8f
    )
}

// ======================
// 控制按钮
// ======================
@Composable
fun GameControls(
    onMove: (Direction) -> Unit,
    onStopMove: () -> Unit,
    onFire: () -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        horizontalArrangement = Arrangement.SpaceAround,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Box(
            modifier = Modifier
                .size(150.dp)
                .background(Color.LightGray.copy(alpha = 0.5f), shape = CircleShape)
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = { },
                        onDragEnd = { onStopMove() },
                        onDragCancel = { onStopMove() },
                        onDrag = { change, _ ->
                            change.consume()
                            val position = change.position
                            val centerX = size.width / 2f
                            val centerY = size.height / 2f
                            val dx = position.x - centerX
                            val dy = position.y - centerY

                            val absDx = kotlin.math.abs(dx)
                            val absDy = kotlin.math.abs(dy)

                            if (absDx > 20 || absDy > 20) {
                                val direction = if (absDx > absDy) {
                                    if (dx > 0) Direction.RIGHT else Direction.LEFT
                                } else {
                                    if (dy > 0) Direction.DOWN else Direction.UP
                                }
                                onMove(direction)
                            }
                        }
                    )
                },
            contentAlignment = Alignment.Center
        ) {
            Box(
                modifier = Modifier
                    .size(50.dp)
                    .background(Color.DarkGray, shape = CircleShape)
            )
        }

        Button (
            onClick = onFire,
            modifier = Modifier
                .size(100.dp)
                .padding(start = 20.dp),
            shape = CircleShape,
            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3))
        ) {
            Text("开火", fontSize = 18.sp)
        }
    }
}

// ======================
// 辅助函数 (优化后)
// ======================
fun canMove(x: Int, y: Int, width: Int, height: Int, walls: List<Wall>, tanks: List<Tank>, selfId: String): Boolean {
    val objectRight = x + width
    val objectBottom = y + height

    if (x < 0 || y < 0 || objectRight > MAP_WIDTH_GRIDS * GRID_SIZE || objectBottom > MAP_HEIGHT_GRIDS * GRID_SIZE) return false

    for (wall in walls) {
        if (x < wall.x + wall.width &&
            objectRight > wall.x &&
            y < wall.y + wall.height &&
            objectBottom > wall.y) {
            return false
        }
    }

    for (tank in tanks) {
        if (tank.id != selfId && tank.isAlive) {
            if (x < tank.x + GRID_SIZE &&
                objectRight > tank.x &&
                y < tank.y + GRID_SIZE &&
                objectBottom > tank.y) {
                return false
            }
        }
    }

    return true
}

fun isColliding(x1: Int, y1: Int, x2: Int, y2: Int, size1: Int, size2: Int): Boolean {
    val centerX1 = x1 + size1 / 2
    val centerY1 = y1 + size1 / 2
    val radius1 = size1 / 2.2f

    val centerX2 = x2 + size2 / 2
    val centerY2 = y2 + size2 / 2
    val radius2 = size2 / 2.2f

    val distance = sqrt((centerX1 - centerX2).toDouble().pow(2) + (centerY1 - centerY2).toDouble().pow(2))
    return distance < (radius1 + radius2)
}

// 优化:新函数,生成指定数量且位置不重叠的敌方坦克
fun generateUniqueEnemyTanks(walls: List<Wall>, count: Int): List<Tank> {
    val enemyTanks = mutableSetOf<Tank>() // 使用 Set 避免自身重复
    val maxAttempts = count * 100 // 防止无限循环

    var attempts = 0
    while (enemyTanks.size < count && attempts < maxAttempts) {
        attempts++
        var x: Int
        var y: Int
        var isValidPosition = false
        var newTank: Tank? = null

        // 尝试生成一个有效位置的坦克
        repeat(100) { // 为单个坦克尝试100次找到不重叠的位置
            x = Random.nextInt(0, MAP_WIDTH_GRIDS) * GRID_SIZE
            y = Random.nextInt(0, MAP_HEIGHT_GRIDS) * GRID_SIZE

            // 检查是否与墙碰撞或在出生点区域
            val wallCollision = walls.any { wall ->
                x < wall.x + wall.width &&
                        x + GRID_SIZE > wall.x &&
                        y < wall.y + wall.height &&
                        y + GRID_SIZE > wall.y
            }
            val inSpawnArea = y >= (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE

            if (!wallCollision && !inSpawnArea) {
                // 检查是否与已生成的坦克重叠
                val tankCollision = enemyTanks.any { existingTank ->
                    x < existingTank.x + GRID_SIZE &&
                            x + GRID_SIZE > existingTank.x &&
                            y < existingTank.y + GRID_SIZE &&
                            y + GRID_SIZE > existingTank.y
                }

                if (!tankCollision) {
                    isValidPosition = true
                    newTank = Tank(
                        x = x,
                        y = y,
                        direction = Direction.entries.random(),
                        color = Color.Red
                    )
                    return@repeat // 找到有效位置,跳出循环
                }
            }
        }

        // 如果找到了有效位置且不与现有坦克重叠,则添加
        if (isValidPosition && newTank != null) {
            // 再次检查是否与集合中已有的坦克重叠(虽然上面检查了,但Set检查更安全)
            val finalCollision = enemyTanks.any { existingTank ->
                newTank.x < existingTank.x + GRID_SIZE &&
                        newTank.x + GRID_SIZE > existingTank.x &&
                        newTank.y < existingTank.y + GRID_SIZE &&
                        newTank.y + GRID_SIZE > existingTank.y
            }
            if(!finalCollision) {
                enemyTanks.add(newTank)
            }
        }
    }

    return enemyTanks.toList()
}


fun getBulletSpawnPosition(tankX: Int, tankY: Int, tankDirection: Direction): Pair<Int, Int> {
    val centerX = tankX + GRID_SIZE / 2
    val centerY = tankY + GRID_SIZE / 2
    val barrelLength = (GRID_SIZE / 1.8f).toInt()

    val (offsetX, offsetY) = when (tankDirection) {
        Direction.UP -> Pair(0, -barrelLength)
        Direction.DOWN -> Pair(0, barrelLength)
        Direction.LEFT -> Pair(-barrelLength, 0)
        Direction.RIGHT -> Pair(barrelLength, 0)
    }

    return Pair(centerX + offsetX, centerY + offsetY)
}

// 新增枚举类,用于标识游戏结束的原因
enum class GameEndReason {
    VICTORY,
    DEFEAT,
    QUIT
}

// ======================
// 预览
// ======================
@Preview(showBackground = true, backgroundColor = 0xFF000000, widthDp = 400, heightDp = 800)
@Composable
fun GameWithHUDPreview() {
    MaterialTheme {
        val previewPlayerTank = remember {
            Tank(
                x = MAP_WIDTH_GRIDS / 2 * GRID_SIZE,
                y = (MAP_HEIGHT_GRIDS - 3) * GRID_SIZE,
                direction = Direction.UP,
                color = Color.Green,
                isPlayer = true,
                isAlive = true
            )
        }

        val previewWalls = remember {
            val wallThickness = GRID_SIZE
            val mapWidthPixels = MAP_WIDTH_GRIDS * GRID_SIZE
            val mapHeightPixels = MAP_HEIGHT_GRIDS * GRID_SIZE
            val edgeWalls = buildList {
                for (x in 0 until MAP_WIDTH_GRIDS) {
                    add(Wall(x * GRID_SIZE, 0))
                }
                for (x in 0 until MAP_WIDTH_GRIDS) {
                    add(Wall(x * GRID_SIZE, mapHeightPixels - wallThickness))
                }
                for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                    add(Wall(0, y * GRID_SIZE))
                }
                for (y in 1 until MAP_HEIGHT_GRIDS - 1) {
                    add(Wall(mapWidthPixels - wallThickness, y * GRID_SIZE))
                }
            }
            val innerWalls = listOf(
                Wall(5 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(6 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(9 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(10 * GRID_SIZE, 5 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 10 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 11 * GRID_SIZE),
                Wall(7 * GRID_SIZE, 12 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 8 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 9 * GRID_SIZE),
                Wall(15 * GRID_SIZE, 10 * GRID_SIZE),
                Wall(3 * GRID_SIZE, 15 * GRID_SIZE),
                Wall(4 * GRID_SIZE, 15 * GRID_SIZE),
                Wall(5 * GRID_SIZE, 15 * GRID_SIZE)
            )
            edgeWalls + innerWalls
        }

        val previewEnemyTanks = remember { generateUniqueEnemyTanks(previewWalls, 10) }

        // 预览中的子弹也使用新的速度属性
        val previewBullets = remember {
            listOf(
                Bullet(x = 5 * GRID_SIZE, y = 10 * GRID_SIZE, direction = Direction.UP, ownerId = "player", color = Color.Red, speed = DEFAULT_BULLET_SPEED),
                Bullet(x = 8 * GRID_SIZE, y = 5 * GRID_SIZE, direction = Direction.RIGHT, ownerId = "enemy_1", color = Color.Blue, speed = DEFAULT_BULLET_SPEED)
            )
        }

        val previewStats = remember { PlayerStats(score = 15, lives = 2) }

        val density = LocalDensity.current
        val previewGameWidthDp: Dp = with(density) { (MAP_WIDTH_GRIDS * GRID_SIZE).toDp() }
        val previewGameHeightDp: Dp = with(density) { (MAP_HEIGHT_GRIDS * GRID_SIZE).toDp() }

        Box(modifier = Modifier.fillMaxSize()) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                modifier = Modifier.fillMaxSize()
            ) {
                Box(
                    modifier = Modifier
                        .weight(1f)
                        .fillMaxWidth(),
                    contentAlignment = Alignment.Center
                ) {
                    // 预览时只绘制 GameCanvas,不绘制按钮
                    GameCanvas(
                        playerTank = previewPlayerTank,
                        enemyTanks = previewEnemyTanks,
                        bullets = previewBullets,
                        walls = previewWalls,
                        gameWidthDp = previewGameWidthDp,
                        gameHeightDp = previewGameHeightDp
                    )
                }

                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(Color.DarkGray)
                        .padding(8.dp),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    Text("分数: ${previewStats.score}", color = Color.Yellow, fontSize = 16.sp)
                    Text("生命: ${previewStats.lives}", color = Color.Red, fontSize = 16.sp)
                }

                Column(modifier = Modifier.fillMaxWidth()) {
                    Row(
                        modifier = Modifier.padding(16.dp),
                        horizontalArrangement = Arrangement.SpaceAround,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Box(
                            modifier = Modifier
                                .size(150.dp)
                                .background(Color.LightGray.copy(alpha = 0.5f), shape = CircleShape),
                            contentAlignment = Alignment.Center
                        ) {
                            Box(
                                modifier = Modifier
                                    .size(50.dp)
                                    .background(Color.DarkGray, shape = CircleShape)
                            )
                        }
                        Button (
                            onClick = { },
                            modifier = Modifier
                                .size(100.dp)
                                .padding(start = 20.dp),
                            shape = CircleShape,
                            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3))
                        ) {
                            Text("开火", fontSize = 18.sp)
                        }
                    }

                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(8.dp),
                        horizontalArrangement = Arrangement.SpaceEvenly
                    ) {
                        Button(onClick = { }, modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 4.dp)) {
                            Text("⏸️ 暂停游戏", fontSize = 14.sp)
                        }
                        Button(
                            onClick = { },
                            modifier = Modifier
                                .weight(1f)
                                .padding(horizontal = 4.dp),
                            colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
                        ) {
                            Text("🏠 结束游戏", fontSize = 14.sp)
                        }
                    }
                }
            }

            Box(
                modifier = Modifier.fillMaxSize().background(Color.Black.copy(alpha = 0.3f)),
                contentAlignment = Alignment.TopStart
            ) {
                Text(
                    "🖼️ UI 预览模式",
                    color = Color.White,
                    fontSize = 16.sp,
                    modifier = Modifier.padding(8.dp)
                )
            }
        }
    }
}

@Preview(showBackground = true, widthDp = 400, heightDp = 800)
@Composable
fun MenuPreview() {
    // 预览更新后的菜单界面
    GameMenuScreen(
        scoreRepository = ScoreRepository(LocalContext.current), // 预览中创建实例
        onStartGame = {}
    )
}

// ======================
// 主题
// ======================
@Composable
fun TankBattleTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = lightColorScheme(
            primary = Color(0xFF006064),
            secondary = Color(0xFF00B8D4),
            // error = Color.Red // 可以自定义错误颜色
        ),
        typography = Typography(
            bodyLarge = androidx.compose.material3.Typography().bodyLarge.copy(fontSize = 16.sp)
        ),
        content = content
    )
}

这里应用桌面图标自己随便设置,在这里android:icon="@drawable/tanke"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@drawable/tanke"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyApplication">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

在这里插入图片描述
在这里插入图片描述

请添加图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐