Linux C++ 贪吃蛇游戏 -- 方向键控制蛇移动
2023-12-13 04:45:51
1. 代码
#include <iostream>
#include <ncurses.h>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <thread>
using namespace std;
// 定义方向
enum class Direction { UP, DOWN, LEFT, RIGHT };
class SnakeGame {
public:
SnakeGame(int width, int height) : width(width), height(height), score(0), gameover(false) {
srand(time(nullptr));
initscr(); // 初始化终端
keypad(stdscr, true); // 启用键盘输入
noecho(); // 关闭回显
nodelay(stdscr, true); // 非阻塞模式
curs_set(0); // 隐藏光标
getmaxyx(stdscr, max_y, max_x);
window = newwin(height, width, (max_y - height) / 2, (max_x - width) / 2);
box(window, 0, 0); // 绘制窗口边框
refresh();
wrefresh(window);
generateFood();
snake.push_back(make_pair(height / 2, width / 2)); // 初始化贪吃蛇位置
drawSnake();
}
~SnakeGame() {
delwin(window);
endwin();
}
void run() {
// 游戏循环
while (!gameover) {
int ch = getch();
handleInput(ch);
moveSnake();
checkCollision();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
showGameOver();
}
private:
int width, height;
int score;
bool gameover;
int max_x, max_y;
WINDOW *window;
vector<pair<int, int>> snake;
pair<int, int> food;
Direction direction = Direction::RIGHT;
void generateFood() {
do {
food.first = rand() % (height - 2) + 1;
food.second = rand() % (width - 2) + 1;
} while (isSnakeCell(food.first, food.second));
mvwaddch(window, food.first, food.second, '@');
refresh();
wrefresh(window);
}
void drawSnake() {
for (const auto& cell : snake) {
mvwaddch(window, cell.first, cell.second, '#');
}
refresh();
wrefresh(window);
}
void moveSnake() {
pair<int, int> head = snake.front();
pair<int, int> newHead = head;
switch (direction) {
case Direction::UP:
newHead.first--;
break;
case Direction::DOWN:
newHead.first++;
break;
case Direction::LEFT:
newHead.second--;
break;
case Direction::RIGHT:
newHead.second++;
break;
}
snake.insert(snake.begin(), newHead);
mvwaddch(window, newHead.first, newHead.second, '#');
refresh();
wrefresh(window);
if (newHead != food) {
mvwaddch(window, snake.back().first, snake.back().second, ' ');
snake.pop_back();
} else {
score++;
generateFood();
}
}
void handleInput(int ch) {
switch (ch) {
case KEY_UP:
if (direction != Direction::DOWN) {
direction = Direction::UP;
}
break;
case KEY_DOWN:
if (direction != Direction::UP) {
direction = Direction::DOWN;
}
break;
case KEY_LEFT:
if (direction != Direction::RIGHT) {
direction = Direction::LEFT;
}
break;
case KEY_RIGHT:
if (direction != Direction::LEFT) {
direction = Direction::RIGHT;
}
break;
}
}
void checkCollision() {
pair<int, int> head = snake.front();
// 检查是否撞墙
if (head.first == 0 || head.first == height - 1 || head.second == 0 || head.second == width - 1) {
gameover = true;
return;
}
// 检查是否撞到自己的身体
for (size_t i = 1; i < snake.size(); i++) {
if (snake[i] == head) {
gameover = true;
return;
}
}
}
void showGameOver() {
clear();
string gameOverText = "Game Over!";
mvprintw(max_y / 2, (max_x - gameOverText.length()) / 2, gameOverText.c_str());
string scoreText = "Score: " + to_string(score);
mvprintw(max_y / 2 + 1, (max_x - scoreText.length()) / 2, scoreText.c_str());
refresh();
getch();
}
bool isSnakeCell(int row, int col) {
for (const auto& cell : snake) {
if (cell.first == row && cell.second == col) {
return true;
}
}
return false;
}
};
int main() {
SnakeGame game(40, 20);
game.run();
return 0;
}
2. 编译命令
alfred@ubuntu:~/c_learning/d_cplusplus_learning$ g++ -std=c++11 snake.cpp -o snake -lncurses
3. 运行游戏,使用方向键 ↑ ↓ ← → 上下左右控制蛇移动
alfred@ubuntu:~/c_learning/d_cplusplus_learning$ ./snake
4. 调整蛇移动的速度
修改延时时间100,单位为ms,数字越小,移动越快,修改完后重新编译,运行
std::this_thread::sleep_for(std::chrono::milliseconds(100));
文章来源:https://blog.csdn.net/weixin_50212044/article/details/134816018
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!