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

生成游戏网格

  • 坐标系定义

    • 采用**左下角为原点(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 ,获取对应小游戏源码学习!

相关推荐
技术小甜甜1 天前
【Blender Texture】【游戏开发】高质感 Blender 4K 材质资源推荐合集 —— 提升场景真实感与美术表现力
blender·游戏开发·材质·texture
Thomas游戏开发1 天前
Unity3D TextMeshPro终极使用指南
前端·unity3d·游戏开发
Thomas游戏开发3 天前
Unity3D 逻辑代码性能优化策略
前端框架·unity3d·游戏开发
Thomas游戏开发4 天前
Unity3D HUD高性能优化方案
前端框架·unity3d·游戏开发
陈哥聊测试5 天前
游戏公司如何同时管好上百个游戏项目?
游戏·程序员·游戏开发
一名用户6 天前
unity随机生成未知符号教程
c#·unity3d·游戏开发
Be_Somebody10 天前
计算机图形学——Games101深度解析_第二章
游戏开发·计算机图形学·games101
GameTomato11 天前
【IOS】【OC】【应用内打印功能的实现】如何在APP内实现打印功能,连接本地打印机,把想要打印的界面打印成图片
macos·ios·objective-c·xcode·游戏开发·cocos2d
Be_Somebody11 天前
计算机图形学——Games101深度解析_第一章
游戏开发·计算机图形学·games101
飞起的猪22 天前
【虚幻引擎】UE5独立游戏开发全流程(商业级架构)
ue5·游戏引擎·游戏开发·虚幻·独立开发·游戏设计·引擎架构