版权声明:Author: 徐筵彭 https://blog.csdn.net/qq_28304097/article/details/86665407
学习编程的过程中,C++似乎是一个难以跨过的坎,好不容易能写点基础算法,遇到数据结构又是无从下手,笔者作为一个业余选手,由于工作需要顺便写点代码的人,站在另一个视角给初学者还不能独立撸代码的人提供一个案例,从实战中跨过这道障碍。
学习编程前期所有语言都是想通的,只是语法规则不同,循序结构、循环结构、选择结构,之后C++又多了指针,函数,面向对象,因此,在理解和初步掌握基础语法规则的基础之上,独立完成一个贪吃蛇小游戏确实让人有一种酣畅淋漓之感,麻雀虽小,五脏俱全,就从最开始做出贪吃蛇的外部围墙,再考虑设计随机出现的实物,再考虑蛇如何吃食物可以加长,不要参考别人的代码,不懂的语法就去翻书,比如随机数那块我就是百度的,然后嵌入到自己的代码中,完全凭借自己的逻辑和不断地调试去指导我们的编程。相信我,完成这个小任务之后立马可以提高你的功力,彻底将编程作为你的工具,之后要做的就是如何利用好这个工具。
Snake.h
#pragma once
#include <iostream>
#include <Windows.h>
#include <time.h>
#include <list>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
using namespace std;
class Snake_Position
{
public:
int x_snake;
int y_snake;
};
//系统函数
void setColor(int color);
void GOTO(int x, int y);
void HiddenCursor();
//自定义函数
void Init_Map();
void Show_Snake();
void Init();
void isDead();
void Show_Score();
Snake.cpp
#include "Snake.h"
using namespace std;
void GOTO(int x, int y)
{
COORD wall{ 2 * x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), wall);
}
void setColor(int color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void HiddenCursor()
{
CONSOLE_CURSOR_INFO info;
info.dwSize = 1;
info.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}
Main.cpp
#include "Snake.h"
int iScore = 0;
int iGrade = 1;
//蛇头蛇尾初始位置
int x_head = 1, y_head = 3;
int x_tail = 1, y_tail = 1;
//地图坐标
int i_Map = 1, j_Map = 1;
//第二节初始位置
int x_second = 1, y_second = 2;
//初始化移动方向
int towards1 = 2; //原来方向
int towards2; //按键按下后的方向
const int SIDE = 20;
int Snake_Map[SIDE][SIDE] = { 0 };
int Speed = 300;
list<Snake_Position> LIST;
Snake_Position snake;
int main()
{
Init();
srand((unsigned)time(NULL));
char getKeyboard = 'd'; //从键盘读取的键值
char getKeyboard_Vice = 'd'; //副本: 如果读取其他值,则保持原来键值
while (1)
{
int isSendFood = 1; //1--不发送食物 0--发送食物
int iFood;
int x = rand() % 18 + 1;
int y = rand() % 18 + 1;
setColor(6);
HiddenCursor();
GOTO(y, x);
cout << "★";
if (Snake_Map[x][y] != 2)
Snake_Map[x][y] = 3;
else
continue;
while (isSendFood)
{
if (_kbhit())
getKeyboard = _getch();
if (getKeyboard != 's' && getKeyboard != 'S' && getKeyboard != 'a' && getKeyboard != 'A' && getKeyboard != 'w' && getKeyboard != 'W' && getKeyboard != 'd' && getKeyboard != 'D')
getKeyboard = getKeyboard_Vice;
switch (getKeyboard)
{
case 'W':
case 'w':
towards2 = 4;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2; //如果现在方向合理,则保存方向到towards1
x_head -= 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'w';
break;
case 'S':
case 's':
towards2 = 1;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
x_head += 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 's';
break;
case 'A':
case 'a':
towards2 = 3;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
y_head -= 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'a';
break;
case 'D':
case 'd':
towards2 = 2;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
y_head += 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'd';
break;
default:
break;
}
}
}
system("pause");
return 0;
}
void Init_Map()
{
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
if (i == 0 || i == SIDE - 1 || j == 0 || j == SIDE - 1)
{
GOTO(i, j);
cout << "■";
}
}
}
}
void Show_Snake()
{
for (int i = 1; i < SIDE - 1; i++)
{
for (int j = 1; j < SIDE - 1; j++)
{
if (Snake_Map[i][j] == 3)
{
GOTO(j, i);
cout << "★";
}
if (Snake_Map[i][j] == 2)
{
GOTO(j, i);
cout << "○";
}
if (Snake_Map[i][j] == 0)
{
GOTO(j, i);
cout << " ";
}
}
}
}
void Init()
{
Init_Map(); //初始化显示地图
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
if (i == 0 || i == SIDE - 1 || j == 0 || j == SIDE - 1)
Snake_Map[i][j] = 9;
}
}
//将蛇的初始三节坐标依次保存到LIST中
Snake_Map[1][1] = 2;
snake.x_snake = 1;
snake.y_snake = 1;
LIST.push_front(snake);
Snake_Map[1][2] = 2;
snake.x_snake = 1;
snake.y_snake = 2;
LIST.push_front(snake);
Snake_Map[1][3] = 2;
snake.x_snake = 1;
snake.y_snake = 3;
LIST.push_front(snake);
Show_Snake();
}
void isDead()
{
if (Snake_Map[x_head][y_head] == 9 || Snake_Map[x_head][y_head] == 2) //死亡条件
{
system("cls");
cout << "你已经挂了, 游戏结束!" << endl;
Sleep(2000);
exit(-1);
}
}
void Show_Score()
{
if (iScore == 5)
{
iGrade = 2;
Speed = 250;
//Sleep(2000);
}
if (iScore == 10)
{
iGrade = 3;
Speed = 200;
//Sleep(2000);
}
if (iScore == 15)
{
setColor(4);
HiddenCursor();
GOTO(5, 5);
cout << "您已达到王者级别";
Sleep(5000);
exit(0);
}
setColor(4);
HiddenCursor();
GOTO(30, 8);
cout << "级别: " << iGrade;
GOTO(30, 12);
cout << "得分: " << iScore;
}