Skip to content

典中之典cpp贪吃蛇,但想整点好活

Notifications You must be signed in to change notification settings

whyisverysmart/MySnakeGame

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MySnakeGame

编译与运行

需要linux环境下, 在游戏源文件根目录运行makemake MySnakeGame来编译并生成可执行文件MySnakeGame

实现的功能

界面:

  • 游戏要素的色彩
  • 艺术字logo
  • 更好的游戏菜单
  • 帮助界面和中途退出界面

模式:

  • 经典模式(Classic):

    • 循环往复的游戏地图
    • 食物(黄色#), 分数
    • 逐渐增加的游戏难度(速度)
    • 随分数增加添加爱心(红色+), 可增加生命值
  • 文字蛇模式(WordSnake):

    • 蛇初始为两个@字符组成
    • 地图上随机生成26个字母, 被吃掉后加入蛇尾
    • 从蛇尾开始向头部看, 如果产生完整单词, 这部分蛇身将与蛇分离, 并向相反方向运动
    • 由于地图循环往复, 这些掉落的单词也会一直运动下去, 游戏难度便随着拼出一个个单词而增加
    • 拼成单词时加分, 分数与单词长度相关
    • 使用CET4词库中长度不小于3的单词
  • 沙盒模式(SnakBox):

    • 根目录下的/data/maps/sand_box.map为沙盒模式使用的地图文件
    • 用文本编辑器修改该文件来达到自定义游戏地图的目的

沙盒模式地图文件语法

地图部分

第一行必须是m <int 1> <int 1>的格式, 其中两个非负整数分别代表地图的高度和宽度, 以下称作heightwidth 紧随其后的height行描述地图每一排的方块类型和渲染用字符

  • 数字代表方块类型, 紧随其后的字符表示渲染出来的样子
    • 0: 空方块
    • 1: 墙, 不可穿越, 蛇撞上即死亡
    • 2: 传送门, 蛇和实体(Entity)都可以穿过
    • 3: 障碍, 蛇消耗生命值可以穿过, 实体不能穿过

由于传送门的创建还需要指明传送位置, 因此必须在接下来的命令部分完成, 遇到2时程序会用空方块占位

地图样例:

mapfile_example

命令部分

紧接着地图部分的下一行以f开头即声明以下将为命令 命令的第一个字符代表其类型, 跟着的是参数

  • b: 创建方块的命令, 推荐用来创建传送门.
    • b <int 0> <int 1> <int 2> 第一个整数代表方块类型, 之后的两个代表方块坐标, 传送门需要额外两个整数来作为传送目标的坐标
  • i: 创建物品
    • i <int 0> <int 1> <int 2> <char> 第一个整数代表物品类型, 其中1代表食物, 2代表心, 3代表物品位的蛇身(SnakeBody), 后者需要多两个整数来说明下一节蛇身的位置, 如果提供两个负值则认为没有下一节; 之后的两个整数代表创建位置, 字符作渲染用
  • s: 声明蛇身
    • s <int 1> <int 2> <char> <int 3> <int 4> 前两个整数代表蛇身生成的位置, 字符作渲染用, 后面的两个整数代表下一节蛇身的位置, 提供两个负值则认为没有下一节
  • c: 声明蛇, 需要基于已经创建且连接好的蛇身
    • s <int 1> <int 2> <int 3> <int 4> 前两个整数代表蛇头的位置, 第三个代表初始生命值, 第四个代表初始方向(从向上开始, 逆时针依次为0 1 2 3)
  • e: 声明实体, 需要基于已经创建且连接好的蛇身
    • e <int 1> <int 2> <int 3> <int 4> 前两个整数是"蛇头"位置, 第三个代表初始方向, 第四个代表初始长度(当然需要与你准备好的蛇身链表长度相同)

虽然这些命令提供了足够的自由度, 以至于你可以将传送门的出口设置在 其自身上, 也可以将物品位的蛇身和普通蛇身串起来提供给蛇和实体等等, 但这些行为对游戏的稳定运行并不友好

命令样例:

command_example

源代码实现说明

游戏以block为单位来运算和渲染, block上可附着item和SnakeBody, item和SnakeBody也通过连接相应方块来标明位置, 渲染优先级SnakeBody > item > block. 由于SnakeBody实际上是BaseItem的一个子类, 所以蛇身也可以连接到block的item指针上, 但这并不推荐

两个强枚举类ItemTypeBlockType用来区分不同的block和不同的item

Map内含有一个block指针的二维向量, 一个指向蛇的指针, 一个储存着实体指针的向量, 以及其他常规参数

SnakeBody中有一个指向下一节蛇身的指针, 用于构建单链表; Snake内含有指向地图的指针, 指向蛇头部的指针, 和一些常规参数; moveForward()是蛇最核心的方法

Entity实际上是蛇的子类, 因此也采用SnakeBody作为单元构建链表. 与蛇不同的是实体的移动是平移

word_snake是蛇的子类, 用于文字蛇模式

命名空间PathRandom声明在map/map.h中, 分别使用了库和库. 前者提供了获取游戏运行目录绝对路径的函数和根据相对路径生成绝对路径的函数; 后者提供了初始化随机数引擎和根据引擎生成一定范围的均匀随机整数的方法

renders中的程序以标准实现为基础进行了一系列拓展, 包括添加新的函数, 新的窗口, 新的色彩对等, 游戏的主循环也在此

整个程序的主循环在main.cpp中

About

典中之典cpp贪吃蛇,但想整点好活

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 65.5%
  • Mathematica 33.1%
  • Makefile 1.1%
  • Shell 0.3%