用AI写游戏3——deepseek实现kotlin android studio greedy snake game 贪吃蛇游戏

news/2025/2/24 8:14:06

项目下载

https://download.csdn.net/download/AnalogElectronic/90421306
在这里插入图片描述

项目结构

在这里插入图片描述
就是通过android studio 建空项目,改下MainActivity.kt的内容就完事了

ctrl+shift+alt+s 看项目结构如下
在这里插入图片描述

核心代码

MainActivity.kt

kotlin">package com.example.snakegame1

// MainActivity.kt
import android.content.ContentValues.TAG
import android.view.KeyEvent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.*
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import java.util.*
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput
import kotlin.math.abs
import kotlin.math.roundToInt

// 游戏配置常量
const val CELL_SIZE = 30f      // 每个网格单元大小
const val GRID_SIZE = 20       // 网格行列数
const val GAME_SPEED = 150L    // 游戏刷新速度(毫秒)

// 方向枚举类
enum class Direction { UP, DOWN, LEFT, RIGHT }

// 坐标数据类
data class Point(val x: Int, val y: Int)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SnakeGame()
        }
    }
}

@Composable
fun SnakeGame() {
    // 游戏状态控制
    var isPlaying by remember { mutableStateOf(true) }
    var score by remember { mutableStateOf(0) }
    Log.d(TAG, "游戏是否启动: $isPlaying")

    // 蛇的初始状态
    val snake = remember {
        mutableStateOf(
            Snake(
                body = listOf(Point(GRID_SIZE/2, GRID_SIZE/2)),
                direction = Direction.RIGHT
            )
        )
    }

    // 食物位置
    var food by remember { mutableStateOf(generateFood(snake.value.body)) }

    // 游戏循环控制
    LaunchedEffect(key1 = isPlaying) {
        while (isPlaying) {
            delay(GAME_SPEED)
            snake.value = snake.value.move()

            // 检测是否吃到食物
            if (snake.value.body.first() == food) {
                score += 10
                food = generateFood(snake.value.body)
                snake.value = snake.value.grow()
            }

            // 检测碰撞
            if (checkCollision(snake.value.body)) {
                isPlaying = false
            }
        }
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFF2B2B2B))
            .pointerInput(Unit) {
                // 处理触摸或鼠标事件
                detectDragGestures { _, dragAmount ->
                    // 根据拖动方向改变蛇的方向
                    if (abs(dragAmount.x) > abs(dragAmount.y)) {
                        if (dragAmount.x > 0) {
                            snake.value = snake.value.turn(Direction.RIGHT)
                        } else {
                            snake.value = snake.value.turn(Direction.LEFT)
                        }
                    } else {
                        if (dragAmount.y > 0) {
                            snake.value = snake.value.turn(Direction.DOWN)
                        } else {
                            snake.value = snake.value.turn(Direction.UP)
                        }
                    }
                }
            }
            .focusable(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // 游戏画布
        Canvas(
            modifier = Modifier
                .size((CELL_SIZE * GRID_SIZE).dp)
                .background(Color.Black)
        ) {
            // 绘制网格线
            for (i in 0..GRID_SIZE) {
                drawLine(
                    color = Color.Gray.copy(alpha = 0.3f),
                    start = Offset(i * CELL_SIZE, 0f),
                    end = Offset(i * CELL_SIZE, size.height),
                    strokeWidth = 1f
                )
                drawLine(
                    color = Color.Gray.copy(alpha = 0.3f),
                    start = Offset(0f, i * CELL_SIZE),
                    end = Offset(size.width, i * CELL_SIZE),
                    strokeWidth = 1f
                )
            }

            // 绘制食物
            drawCircle(
                color = Color.Red,
                center = Offset(
                    food.x * CELL_SIZE + CELL_SIZE / 2,
                    food.y * CELL_SIZE + CELL_SIZE / 2
                ),
                radius = CELL_SIZE / 3
            )

            // 绘制蛇身
            snake.value.body.forEachIndexed { index, point ->
                val color = if (index == 0) Color.Green else Color(0xFF4CAF50)
                drawCircle(
                    color = color,
                    center = Offset(
                        point.x * CELL_SIZE + CELL_SIZE / 2,
                        point.y * CELL_SIZE + CELL_SIZE / 2
                    ),
                    radius = CELL_SIZE / 2.5f,
                    style = Stroke(width = 3f)
                )
            }
        }

        // 重新开始按钮
        if (!isPlaying) {
            Button(
                onClick = {
                    // 重置游戏状态
                    isPlaying = true
                    score = 0
                    snake.value = Snake(
                        body = listOf(Point(GRID_SIZE/2, GRID_SIZE/2)),
                        direction = Direction.RIGHT
                    )
                    food = generateFood(snake.value.body)
                },
                modifier = Modifier.padding(8.dp)
            ) {
                Text("重新开始")
            }
        }
    }
}

// 蛇类定义
class Snake(
    val body: List<Point>,
    val direction: Direction
) {
    // 移动方法
    fun move(): Snake {
        val head = body.first()
        val newHead = when (direction) {
            Direction.UP -> head.copy(y = head.y - 1)
            Direction.DOWN -> head.copy(y = head.y + 1)
            Direction.LEFT -> head.copy(x = head.x - 1)
            Direction.RIGHT -> head.copy(x = head.x + 1)
        }
        return copy(body = listOf(newHead) + body.dropLast(1))
    }

    // 转向方法
    fun turn(newDirection: Direction): Snake {
        // 禁止反向移动
        if ((direction == Direction.UP && newDirection == Direction.DOWN) ||
            (direction == Direction.DOWN && newDirection == Direction.UP) ||
            (direction == Direction.LEFT && newDirection == Direction.RIGHT) ||
            (direction == Direction.RIGHT && newDirection == Direction.LEFT)
        ) {
            return this
        }
        return copy(direction = newDirection)
    }

    // 增长方法
    fun grow(): Snake {
        val tail = body.last()
        val newTail = when (direction) {
            Direction.UP -> tail.copy(y = tail.y + 1)
            Direction.DOWN -> tail.copy(y = tail.y - 1)
            Direction.LEFT -> tail.copy(x = tail.x + 1)
            Direction.RIGHT -> tail.copy(x = tail.x - 1)
        }
        return copy(body = body + newTail)
    }

    private fun copy(
        body: List<Point> = this.body,
        direction: Direction = this.direction
    ) = Snake(body, direction)
}

// 生成食物位置
fun generateFood(snakeBody: List<Point>): Point {
    val random = Random()
    while (true) {
        val newFood = Point(
            random.nextInt(GRID_SIZE),
            random.nextInt(GRID_SIZE)
        )
        if (newFood !in snakeBody) return newFood
    }
}

// 碰撞检测
fun checkCollision(body: List<Point>): Boolean {
    val head = body.first()
    return head.x < 0 || head.x >= GRID_SIZE ||
            head.y < 0 || head.y >= GRID_SIZE ||
            head in body.drop(1)
}

实现效果
在这里插入图片描述


http://www.niftyadmin.cn/n/5864106.html

相关文章

Logback:强大的Java日志框架

文章目录 引言什么是Logback&#xff1f;Logback的主要特点Logback的配置在项目中使用Logback总结 引言 在软件开发中&#xff0c;日志记录是一个不可或缺的部分。它不仅帮助开发者在调试时追踪问题&#xff0c;还能在生产环境中监控应用程序的运行状态。Java生态中有多种日志…

sentinel小记

sentinel小记 1、被处理的接口 /*** 分页获取题目列表&#xff08;封装类&#xff09;** param questionQueryRequest* param request* return*/PostMapping("/list/page/vo")public BaseResponse<Page<QuestionVO>> listQuestionVOByPage(RequestBody …

Docker启动ES容器打包本地镜像

文章目录 1、安装 Docker2、下载镜像3、查看已下载的镜像4、 保存和加载镜像5、.tar 文件与 Docker 镜像的关系6、如何从 .tar 文件加载 Docker 镜像7、为什么需要 .tar 文件&#xff1f;8、ES 8.x版本无法启动8.1 问题原因8.2 解决方案8.3 提交容器为新镜像 1、安装 Docker 如…

Vue2 和 Vue3 的响应式原理对比

Object.defineProperty 与 Proxy 对比 前言一、Vue2 的响应式原理二、Vue3 的响应式原理三、性能优化总结 前言 响应式系统是 Vue 框架的核心机制之一&#xff0c;通俗易懂的来说 vue2需要手动登记&#xff0c;只有被用到的才会被记录&#xff0c;vue3全自动监控。 一、Vue2 …

一周学会Flask3 Python Web开发-Jinja2模板基本使用

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们平台开发web系统&#xff0c;必须用到网页&#xff0c;单纯的静态网页无法满足我们的需求。我们可以使用模版引擎技术&am…

智能优化算法:莲花算法(Lotus flower algorithm,LFA)介绍,提供MATLAB代码

一、 莲花算法 1.1 算法原理 莲花算法&#xff08;Lotus flower algorithm&#xff0c;LFA&#xff09;是一种受自然启发的优化算法&#xff0c;其灵感来源于莲花的自清洁特性和授粉过程。莲花的自清洁特性&#xff0c;即所谓的“莲花效应”&#xff0c;是由其叶片表面的微纳…

《GNU/Linux Shell命令全解析》

前言: Shell&#xff08;如Bash、Zsh&#xff09;是一个用户应用程序&#xff0c;通过系统调用接口与内核空间进行交互,运行在所示位置在用户空间中。 GNU/Linux内核架构简易图: 1.基础命令行操作 1.1 Shell功能定义 命令行解释器&#xff1a;Shell解释用户输入的命令&#x…

【环境配置】maven,mysql,node.js,vue的快速配置与上手

【环境配置】maven,mysql,node.js,vue的快速配置与上手 我们在利用springbootvue来进行全栈项目开发时&#xff0c;需要做很多的准备工作&#xff0c;其中maven,mysql,node,js和vue的配置是必不可少的。 本期我们尽可能精简地介绍它们的配置以及快速上手。 1.maven 1.1.下载…