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

生成游戏网格

  • 坐标系定义

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

相关推荐
Kapaseker1 天前
Bevt Event
rust·游戏开发
jason_yang2 天前
转眼间,已是十几年前的游戏代码了
cocos creator·游戏开发·cocos2d-x
Thomas游戏开发2 天前
Unity3D网格简化与LOD技术详解
前端框架·unity3d·游戏开发
Thomas游戏开发5 天前
Unity3D 图形渲染(Graphics & Rendering)详解
前端·unity3d·游戏开发
Thomas游戏开发5 天前
Unity3D 光栅化 vs 光线追踪:技术详解
前端框架·unity3d·游戏开发
Thomas游戏开发6 天前
Unity3D 多线程与协程优化详解
前端框架·unity3d·游戏开发
Thomas_YXQ10 天前
Unity3D Cinemachine 高级应用详解
数码相机·unity·面试·职场和发展·unity3d·游戏开发
Uzuki12 天前
Vulkan环境配置 | vscode+msvc 解决方案
vscode·游戏开发·图形学·c/c++
非衣居士12 天前
游戏编程模式(28种编程模式)
数据结构·游戏开发