开发贪吃蛇小游戏(附完整源码参考)

生成游戏网格

  • 坐标系定义

    • 采用**左下角为原点(0,0)**的二维坐标系
    • 网格尺寸例如:20行 × 10列
  • 网格状态定义

typescript 复制代码
enum GridStatus {
    notUse,
    snakeHead,
    snakeBody,
    food,
}
  • 生成游戏网格,默认所有网格的状态是未使用
typescript 复制代码
generateGrids(){
    ......

    for (let rowIndex=0; rowIndex<this.row; rowIndex++){
        this.gridList.push([])
        for (let columnIndex=0; columnIndex<this.column; columnIndex++){
            let gridData: GridDataInterface = {
                name: `Grid-${rowIndex}-${columnIndex}`,
                status: GridStatus.notUse,
                gridNode: null,
                row: rowIndex,
                column: columnIndex,
            }
            this.gridList[rowIndex].push(gridData)
            // 生成网格UI节点
            ......
        }
    }
}

蛇的初始化

  • 定义蛇的当前移动方向往左,蛇的下次移动也往左。
typescript 复制代码
enum Direction {
    UP,
    DOWN,
    LEFT,
    RIGHT
}

public currentDirection = Direction.LEFT
public nextDirection = Direction.LEFT
  • 定义蛇的初始位置:行数/2取整、列数/2取整,得到网格居中位置。

  • 修改居中位置网格数据,把网格状态改为蛇头,而当前移动方向的反方向设置一定数量的网格状态为蛇身。

typescript 复制代码
generateSnake(){
    // 起始位置
    const startRow = Math.floor(this.row / 2)
    const startColumn = Math.floor(this.column / 2)
    // 蛇头
    const headGridData = this.gridList[startRow][startColumn]
    headGridData.status = GridStatus.snakeHead
    this.snakeGridList.push(headGridData)
    // 蛇身
    for (
        let columnIndex=startColumn+1;
        columnIndex<=startColumn+this.startBodyNum;
        columnIndex++
    ){
        const nowGridData = this.gridList[startRow][columnIndex]
        nowGridData.status = GridStatus.snakeBody
        this.snakeGridList.push(nowGridData)
    }
    // 更新UI显示
    this.updateGridsUI()
}
  • 如此就把蛇数据定义在了网格数据里。

蛇朝一个方向移动

  • 点击开始游戏后,搞一个定时器,如每0.5秒调用一次,作为蛇的移动回调。

  • 下次移动方向为向左,那么就让蛇头的列数-1,如果方向往上则让蛇头的行数+1,可得到蛇头新的网格位置。

  • 有了新的蛇头网格位置后,就可以让蛇尾巴网格数据换到新蛇头网格位置,巧妙的实现蛇的移动。

typescript 复制代码
snakeMove(){
    if (this.gameStatus !== GameStatus.running) return

    const move = {row: 0, column: 0}
    if (this.nextDirection === Direction.LEFT){
        move.column = -1
    }
    else if (this.nextDirection === Direction.RIGHT){
        move.column = 1
    }
    else if (this.nextDirection === Direction.UP){
        move.row = 1
    }
    else if (this.nextDirection === Direction.DOWN){
        move.row = -1
    }
    const headGridData = this.snakeGridList[0]
    const newHeadGridData = this.gridList[headGridData.row+move.row][headGridData.column+move.column]
    // 移动
    headGridData.status = GridStatus.snakeBody
    newHeadGridData.status = GridStatus.snakeHead
    this.snakeGridList.unshift(newHeadGridData)
    const tailGridData = this.snakeGridList.pop()
    tailGridData.status = GridStatus.notUse
    // 更新UI显示
    this.updateGridsUI()
    // 下次移动
    this.snakeMoveSchedule()
}

蛇改变方向移动

  • 点击上、下、左、右按键时,记录蛇的下次移动方向。

  • 下次移动方向的限制:不能反方向移动。如蛇的当前移动方向是往左,那么下次移动方向就不能往右。

typescript 复制代码
onBtnClick(event: Event, key: string){
    if (key === 'begin' && this.gameStatus === GameStatus.ready){
        this.readDifficulty()
        this.setGameStauts(GameStatus.running)
        this.generateSnake()
        this.generateFood()
        this.snakeMoveSchedule()
    }
    ......
    // 移动方向更改
    else if (key === 'left' && this.gameStatus === GameStatus.running && this.currentDirection !== Direction.RIGHT){
        this.nextDirection = Direction.LEFT
    }
    else if (key === 'right' && this.gameStatus === GameStatus.running && this.currentDirection !== Direction.LEFT){
        this.nextDirection = Direction.RIGHT
    }
    else if (key === 'up' && this.gameStatus === GameStatus.running && this.currentDirection !== Direction.DOWN){
        this.nextDirection = Direction.UP
    }
    else if (key === 'down' && this.gameStatus === GameStatus.running && this.currentDirection !== Direction.UP){
        this.nextDirection = Direction.DOWN
    }
}
  • 当记录下次移动方向后,再次进入移动回调时蛇会改变方向移动,但移动后还需把当前移动方向记录为下次移动方向,让用户点击方向按钮时可以进行反方向判断。

生成食物

  • 点击开始游戏后,在生成蛇后再生成食物。

  • 食物的位置是一个随机位置,遍历网格数据提取出未使用的网格数据,随机一个网格数据,让网格状态改为食物即可。

蛇吃食物

  • 在蛇的移动回调中,得到蛇头新的网格位置后,判断网格状态是否是食物,如果是食物,则把食物网格设置为蛇头网格即可(不要再处理蛇尾网格数据),接着再生成新的食物。

游戏结束

  • 蛇头出网格边界:在蛇的移动回调中,判断蛇头新的网格位置,是否超出整体网格行数或列数以及小于0。
  • 蛇头撞到蛇身:在蛇的移动回调中,判断蛇头新的网格状态是否是蛇身。

游戏成功

  • 当蛇吃到食物,改完蛇头网格状态后,当所有网格的状态只有蛇头或蛇身时游戏成功。

加速功能

  • 当长按加速按钮时,使蛇的移动速度加快。

  • 只需在点击加速时更改蛇移动回调的间隔时间,缩短即可实现加速。

获取完整小游戏源码

  • 以上内容是讲述了贪吃蛇的核心逻辑如何实现,可以使用任何编程语言编写,但你如果是为了给别人玩、为了上架小游戏平台,那么就需要使用一个游戏引擎去开发小游戏。

  • Cocos商城 里,搜索 zezhou222 ,获取对应小游戏源码学习!

相关推荐
ryfdizuo2 天前
HDR渲染管线中的像素格式-v1
图形渲染·渲染·游戏开发·hdr·色彩·高动态
2401_841495643 天前
【游戏开发】登山赛车
数据结构·python·游戏·游戏开发·pygame·登山赛车游戏·游戏打包发布
喵个咪4 天前
Go单协程事件调度器:游戏后端的无锁有序与响应时间掌控
后端·游戏开发
yongche_shi4 天前
第九十九篇:Python在其他领域的应用:游戏开发、物联网、AIoT简介
开发语言·python·物联网·游戏开发·aiot
SmalBox5 天前
【节点】[NormalBlend节点]原理解析与实际应用
unity3d·游戏开发·图形学
龙智DevSecOps解决方案5 天前
Perforce《2025游戏技术现状报告》Part 5:创意工作者在用什么工具以及如何看待游戏引擎与生成式AI(附免费下载)
游戏引擎·游戏开发·软件开发·perforce·ai创作·龙智
_大学牲5 天前
Flutter 勇闯2D像素游戏之路(五):像元气骑士一样的设计随机地牢
flutter·游戏·游戏开发
SmalBox6 天前
【节点】[ColorMask节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox6 天前
【节点】[ChannelMask节点]原理解析与实际应用
unity3d·游戏开发·图形学
UWA7 天前
GPM 2.0全新功能发布|GPU精准监测 + 精细化运营,重构游戏性能管控新范式
人工智能·游戏·性能优化·重构·游戏开发·uwa