当前位置: 首页 > news >正文

C++ 贪吃蛇 Greedy Snake

代码整体功能概述

此代码构建了一个简易的控制台贪吃蛇游戏。游戏中,玩家借助 wsad 键来操控蛇的移动方向,目标是让蛇吃到随机出现在游戏区域内的水果,每吃到一个水果,蛇的身体会增长一节,同时玩家得分增加 10 分。若蛇撞到边界或者自身身体,游戏就会结束。


 

各部分代码详细解析

1. 全局变量和枚举类型定义
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
  • gameOver:用于标记游戏是否结束。
  • width 和 height:定义游戏区域的宽度和高度。
  • x 和 y:代表蛇头的坐标。
  • fruitX 和 fruitY:表示水果的坐标。
  • score:记录玩家的得分。
  • tailX 和 tailY:数组,用于存储蛇身体各节的坐标。
  • nTail:记录蛇身体的节数。
  • eDirection 枚举类型:定义蛇的移动方向,包含停止、左、右、上、下。
  • dir:存储当前蛇的移动方向。

2. Setup 函数

void Setup() {gameOver = false;dir = STOP;x = width / 2;y = height / 2;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;score = 0;
}
  • 该函数用于初始化游戏状态,把 gameOver 设为 false,蛇的初始移动方向设为停止,将蛇头置于游戏区域中央,随机生成水果的初始位置,并且把得分初始化为 0。
3. Draw 函数
void Draw() {system("cls");for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {if (j == 0)cout << "#";if (i == y && j == x)cout << "O";else if (i == fruitY && j == fruitX)cout << "F";else {bool print = false;for (int k = 0; k < nTail; k++) {if (tailX[k] == j && tailY[k] == i) {cout << "o";print = true;}}if (!print)cout << " ";}if (j == width - 1)cout << "#";}cout << endl;}for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;cout << "Score:" << score << endl;
}
  • 此函数用于绘制游戏界面,先清屏,接着绘制游戏区域的边界,然后在相应位置绘制蛇头、水果以及蛇的身体,最后输出当前得分。
4. Input 函数
void Input() {if (_kbhit()) {switch (_getch()) {case 'a':dir = LEFT;break;case 'd':dir = RIGHT;break;case 'w':dir = UP;break;case 's':dir = DOWN;break;case 'x':gameOver = true;break;}}
}
  • 该函数用于处理用户输入,当用户按下按键时,依据按键的不同改变蛇的移动方向,若按下 x 键,则结束游戏。
5. Logic 函数
void Logic() {int prevX = tailX[0];int prevY = tailY[0];int prev2X, prev2Y;tailX[0] = x;tailY[0] = y;for (int i = 1; i < nTail; i++) {prev2X = tailX[i];prev2Y = tailY[i];tailX[i] = prevX;tailY[i] = prevY;prevX = prev2X;prevY = prev2Y;}switch (dir) {case LEFT:x--;break;case RIGHT:x++;break;case UP:y--;break;case DOWN:y++;break;default:break;}// 撞到边界游戏结束if (x >= width || x < 0 || y >= height || y < 0)gameOver = true;// 撞到自己身体游戏结束for (int i = 0; i < nTail; i++)if (tailX[i] == x && tailY[i] == y)gameOver = true;if (x == fruitX && y == fruitY) {score += 10;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;nTail++;}
}

  • 该函数实现游戏的核心逻辑:
    • 先更新蛇身体各节的坐标。
    • 依据当前蛇的移动方向更新蛇头的坐标。
    • 检查蛇是否撞到边界或者自身身体,若撞到则游戏结束。
    • 检查蛇头是否与水果的位置重合,若重合则得分增加 10 分,随机生成新的水果位置,并且蛇的身体增长一节。
6. main 函数
int main() {Setup();while (!gameOver) {Draw();Input();Logic();Sleep(100);}return 0;
}
  • 这是程序的入口函数,先调用 Setup 函数初始化游戏,接着进入游戏主循环,在循环里不断调用 Draw 函数绘制界面、Input 函数处理用户输入、Logic 函数更新游戏逻辑,每次循环之间暂停 100 毫秒,直到游戏结束。

总结

这段代码借助控制台实现了一个简单的贪吃蛇游戏,包含游戏初始化、界面绘制、用户输入处理以及游戏逻辑更新等功能。不过,代码还存在一些可以优化的地方,例如可以添加音效、优化界面显示、增加游戏难度等。

作者好久没更新了,这次更新给个赞吧~

代码

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
using namespace std;bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailX[100], tailY[100];
int nTail;
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;void Setup() {gameOver = false;dir = STOP;x = width / 2;y = height / 2;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;score = 0;
}void Draw() {system("cls");for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {if (j == 0)cout << "#";if (i == y && j == x)cout << "O";else if (i == fruitY && j == fruitX)cout << "F";else {bool print = false;for (int k = 0; k < nTail; k++) {if (tailX[k] == j && tailY[k] == i) {cout << "o";print = true;}}if (!print)cout << " ";}if (j == width - 1)cout << "#";}cout << endl;}for (int i = 0; i < width + 2; i++)cout << "#";cout << endl;cout << "Score:" << score << endl;
}void Input() {if (_kbhit()) {switch (_getch()) {case 'a':dir = LEFT;break;case 'd':dir = RIGHT;break;case 'w':dir = UP;break;case 's':dir = DOWN;break;case 'x':gameOver = true;break;}}
}void Logic() {int prevX = tailX[0];int prevY = tailY[0];int prev2X, prev2Y;tailX[0] = x;tailY[0] = y;for (int i = 1; i < nTail; i++) {prev2X = tailX[i];prev2Y = tailY[i];tailX[i] = prevX;tailY[i] = prevY;prevX = prev2X;prevY = prev2Y;}switch (dir) {case LEFT:x--;break;case RIGHT:x++;break;case UP:y--;break;case DOWN:y++;break;default:break;}// 撞到边界游戏结束if (x >= width || x < 0 || y >= height || y < 0)gameOver = true;// 撞到自己身体游戏结束for (int i = 0; i < nTail; i++)if (tailX[i] == x && tailY[i] == y)gameOver = true;if (x == fruitX && y == fruitY) {score += 10;srand(time(NULL));fruitX = rand() % width;fruitY = rand() % height;nTail++;}
}int main() {Setup();while (!gameOver) {Draw();Input();Logic();Sleep(100);}return 0;
}    

相关文章:

  • 【React】通过 fetch 发起请求,设置 proxy 处理跨域
  • string函数的应用
  • 基于 BaseRecyclerViewAdapterHelper 4.x 的封装
  • PyTorch快速入门
  • ETL数据集成平台在交通运输行业的五大应用场景
  • 文件包含(详解)
  • 全志H5,NanopiKP1lus移植QT5.12记录
  • 常用的优化算法及横向对比
  • langchain tools源码解析以及扩展
  • 快速使用工具Cursor
  • 【天外之物】线元
  • MacOS怎么显示隐藏文件
  • python-图片分割
  • 慢速率拉伸热变形工艺试验机
  • 通俗理解MCP(Model Context Protocol)和A2A(Agent2Agent)
  • kaamel Privacy agent:AI赋能的隐私保护技术解决方案
  • [特殊字符] 当Docker遇上大模型:本地运行LLM的奇幻漂流 [特殊字符]
  • 68.评论日记
  • 使用dompurify修复XSS跨站脚本缺陷
  • ABAP OLE
  • 大连万达商业管理集团提前兑付“22大连万达MTN001” ,本息2.64亿元
  • 新华社经济随笔:机器人“摔倒、爬起”的背后
  • 第八届进博会将致力于打造“五个高”,为展商增值赋能
  • 同济研究生开发AI二维码走红拿下大奖,新一代00开发者掀起AI创业潮
  • 经济大省中川、豫、浙一季报已发:GDP增速均高于全国
  • 广西柳州23年的蝶变:从“酸雨之城”到“文明之城”