master
IoTcat 5 years ago
parent 8a0b97f547
commit 393665cd35
  1. BIN
      as2/1717608_Liu_Yimian_2.pdf
  2. BIN
      as2/1717608_Liu_Yimian_2.zip
  3. 42
      as3/code/GreedySnake/GreedySnake.cbp
  4. 10
      as3/code/GreedySnake/README.md
  5. 571
      as3/code/GreedySnake/controller.cpp
  6. 23
      as3/code/GreedySnake/controller.h
  7. 119
      as3/code/GreedySnake/food.cpp
  8. 25
      as3/code/GreedySnake/food.h
  9. 8
      as3/code/GreedySnake/main.cpp
  10. 11
      as3/code/GreedySnake/map.cpp
  11. 137
      as3/code/GreedySnake/map.h
  12. BIN
      as3/code/GreedySnake/obj/Debug/main.o
  13. 27
      as3/code/GreedySnake/point.cpp
  14. 19
      as3/code/GreedySnake/point.h
  15. BIN
      as3/code/GreedySnake/shot01.jpg
  16. BIN
      as3/code/GreedySnake/shot02.jpg
  17. BIN
      as3/code/GreedySnake/shot03.gif
  18. BIN
      as3/code/GreedySnake/shot04.gif
  19. 135
      as3/code/GreedySnake/snake.cpp
  20. 33
      as3/code/GreedySnake/snake.h
  21. 68
      as3/code/GreedySnake/startinterface.cpp
  22. 92
      as3/code/GreedySnake/startinterface.h
  23. 33
      as3/code/GreedySnake/tools.cpp
  24. 10
      as3/code/GreedySnake/tools.h

Binary file not shown.

Binary file not shown.

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="GreedySnake" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/GreedySnake" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/GreedySnake" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
</Compiler>
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

@ -0,0 +1,10 @@
# GreedySnake
c++经典项目贪吃蛇游戏控制台版,详细注释。
(点个star再走不急)
教程地址:http://blog.csdn.net/silence1772/article/details/55005008
## 游戏截图:
![](https://github.com/silence1772/GreedySnake/raw/master/shot01.jpg)
![](https://github.com/silence1772/GreedySnake/raw/master/shot02.jpg)
![](https://github.com/silence1772/GreedySnake/raw/master/shot03.gif)
![](https://github.com/silence1772/GreedySnake/raw/master/shot04.gif)

@ -0,0 +1,571 @@
#include <iostream>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include "controller.h"
#include "tools.h"
#include "startinterface.h"
#include "map.h"
#include "snake.h"
#include "food.h"
void Controller::Start()//开始界面
{
SetWindowSize(41, 32);//设置窗口大小
SetColor(2);//设置开始动画颜色
StartInterface *start = new StartInterface();//动态分配一个StartInterface类start
start->Action();//开始动画
delete start;//释放内存空间
/*设置关标位置,并输出提示语,等待任意键输入结束*/
SetCursorPosition(13, 26);
std::cout << "Press any key to start... " ;
SetCursorPosition(13, 27);
system("pause");
}
void Controller::Select()//选择界面
{
/*初始化界面选项*/
SetColor(3);
SetCursorPosition(13, 26);
std::cout << " " ;
SetCursorPosition(13, 27);
std::cout << " " ;
SetCursorPosition(6, 21);
std::cout << "请选择游戏难度:" ;
SetCursorPosition(6, 22);
std::cout << "(上下键选择,回车确认)" ;
SetCursorPosition(27, 22);
SetBackColor();//第一个选项设置背景色以表示当前选中
std::cout << "简单模式" ;
SetCursorPosition(27, 24);
SetColor(3);
std::cout << "普通模式" ;
SetCursorPosition(27, 26);
std::cout << "困难模式" ;
SetCursorPosition(27, 28);
std::cout << "炼狱模式" ;
SetCursorPosition(0, 31);
score = 0;
/*上下方向键选择模块*/
int ch;//记录键入值
key = 1;//记录选中项,初始选择第一个
bool flag = false;//记录是否键入Enter键标记,初始置为否
while ((ch = getch()))
{
switch (ch)//检测输入键
{
case 72://UP上方向键
if (key > 1)//当此时选中项为第一项时,UP上方向键无效
{
switch (key)
{
case 2:
SetCursorPosition(27, 22);//给待选中项设置背景色
SetBackColor();
std::cout << "简单模式" ;
SetCursorPosition(27, 24);//将已选中项取消我背景色
SetColor(3);
std::cout << "普通模式" ;
--key;
break;
case 3:
SetCursorPosition(27, 24);
SetBackColor();
std::cout << "普通模式" ;
SetCursorPosition(27, 26);
SetColor(3);
std::cout << "困难模式" ;
--key;
break;
case 4:
SetCursorPosition(27, 26);
SetBackColor();
std::cout << "困难模式" ;
SetCursorPosition(27, 28);
SetColor(3);
std::cout << "炼狱模式" ;
--key;
break;
}
}
break;
case 80://DOWN下方向键
if (key < 4)
{
switch (key)
{
case 1:
SetCursorPosition(27, 24);
SetBackColor();
std::cout << "普通模式" ;
SetCursorPosition(27, 22);
SetColor(3);
std::cout << "简单模式" ;
++key;
break;
case 2:
SetCursorPosition(27, 26);
SetBackColor();
std::cout << "困难模式" ;
SetCursorPosition(27, 24);
SetColor(3);
std::cout << "普通模式" ;
++key;
break;
case 3:
SetCursorPosition(27, 28);
SetBackColor();
std::cout << "炼狱模式" ;
SetCursorPosition(27, 26);
SetColor(3);
std::cout << "困难模式" ;
++key;
break;
}
}
break;
case 13://Enter回车键
flag = true;
break;
default://无效按键
break;
}
if (flag) break;//输入Enter回车键确认,退出检查输入循环
SetCursorPosition(0, 31);//将光标置于左下角,避免关标闪烁影响游戏体验
}
switch (key)//根据所选选项设置蛇的移动速度,speed值越小,速度越快
{
case 1:
speed = 135;
break;
case 2:
speed = 100;
break;
case 3:
speed = 60;
break;
case 4:
speed = 30;
break;
default:
break;
}
}
void Controller::DrawGame()//绘制游戏界面
{
system("cls");//清屏
/*绘制地图*/
SetColor(3);
Map *init_map = new Map();
init_map->PrintInitmap();
delete init_map;
/*绘制侧边栏*/
SetColor(3);
SetCursorPosition(33, 1);
std::cout << "Greedy Snake" ;
SetCursorPosition(34, 2);
std::cout << "贪吃蛇" ;
SetCursorPosition(31, 4);
std::cout << "难度:" ;
SetCursorPosition(36, 5);
switch (key)
{
case 1:
std::cout << "简单模式" ;
break;
case 2:
std::cout << "普通模式" ;
break;
case 3:
std::cout << "困难模式" ;
break;
case 4:
std::cout << "炼狱模式" ;
break;
default:
break;
}
SetCursorPosition(31, 7);
std::cout << "得分:" ;
SetCursorPosition(37, 8);
std::cout << " 0" ;
SetCursorPosition(33, 13);
std::cout << " 方向键移动" ;
SetCursorPosition(33, 15);
std::cout << " ESC键暂停" ;
}
int Controller::PlayGame()//游戏二级循环
{
/*初始化蛇和食物*/
Snake *csnake = new Snake();
Food *cfood = new Food();
SetColor(6);
csnake->InitSnake();
srand((unsigned)time(NULL));//设置随机数种子,如果没有 食物的出现位置将会固定
cfood->DrawFood(*csnake);
/*游戏循环*/
while (csnake->OverEdge() && csnake->HitItself()) //判断是否撞墙或撞到自身,即是否还有生命
{
/*调出选择菜单*/
if (!csnake->ChangeDirection()) //按Esc键时
{
int tmp = Menu();//绘制菜单,并得到返回值
switch (tmp)
{
case 1://继续游戏
break;
case 2://重新开始
delete csnake;
delete cfood;
return 1;//将1作为PlayGame函数的返回值返回到Game函数中,表示重新开始
case 3://退出游戏
delete csnake;
delete cfood;
return 2;//将2作为PlayGame函数的返回值返回到Game函数中,表示退出游戏
default:
break;
}
}
if (csnake->GetFood(*cfood)) //吃到食物
{
csnake->Move();//蛇增长
UpdateScore(1);//更新分数,1为分数权重
RewriteScore();//重新绘制分数
cfood->DrawFood(*csnake);//绘制新食物
}
else
{
csnake->NormalMove();//蛇正常移动
}
if (csnake->GetBigFood(*cfood)) //吃到限时食物
{
csnake->Move();
UpdateScore(cfood->GetProgressBar()/5);//分数根据限时食物进度条确定
RewriteScore();
}
if (cfood->GetBigFlag()) //如果此时有限时食物,闪烁它
{
cfood->FlashBigFood();
}
Sleep(speed);//制造蛇的移动效果
}
/*蛇死亡*/
delete csnake;//释放分配的内存空间
delete cfood;
int tmp = GameOver();//绘制游戏结束界面,并返回所选项
switch (tmp)
{
case 1:
return 1;//重新开始
case 2:
return 2;//退出游戏
default:
return 2;
}
}
void Controller::UpdateScore(const int& tmp)//更新分数
{
score += key * 10 * tmp;//所得分数根据游戏难度及传人的参数tmp确定
}
void Controller::RewriteScore()//重绘分数
{
/*为保持分数尾部对齐,将最大分数设置为6位,计算当前分数位数,将剩余位数用空格补全,再输出分数*/
SetCursorPosition(37, 8);
SetColor(11);
int bit = 0;
int tmp = score;
while (tmp != 0)
{
++bit;
tmp /= 10;
}
for (int i = 0; i < (6 - bit); ++i)
{
std::cout << " " ;
}
std::cout << score ;
}
int Controller::Menu()//选择菜单
{
/*绘制菜单*/
SetColor(11);
SetCursorPosition(32, 19);
std::cout << "菜单:" ;
Sleep(100);
SetCursorPosition(34, 21);
SetBackColor();
std::cout << "继续游戏" ;
Sleep(100);
SetCursorPosition(34, 23);
SetColor(11);
std::cout << "重新开始" ;
Sleep(100);
SetCursorPosition(34, 25);
std::cout << "退出游戏" ;
SetCursorPosition(0, 31);
/*选择部分*/
int ch;
int tmp_key = 1;
bool flag = false;
while ((ch = getch()))
{
switch (ch)
{
case 72://UP
if (tmp_key > 1)
{
switch (tmp_key)
{
case 2:
SetCursorPosition(34, 21);
SetBackColor();
std::cout << "继续游戏" ;
SetCursorPosition(34, 23);
SetColor(11);
std::cout << "重新开始" ;
--tmp_key;
break;
case 3:
SetCursorPosition(34, 23);
SetBackColor();
std::cout << "重新开始" ;
SetCursorPosition(34, 25);
SetColor(11);
std::cout << "退出游戏" ;
--tmp_key;
break;
}
}
break;
case 80://DOWN
if (tmp_key < 3)
{
switch (tmp_key)
{
case 1:
SetCursorPosition(34, 23);
SetBackColor();
std::cout << "重新开始" ;
SetCursorPosition(34, 21);
SetColor(11);
std::cout << "继续游戏" ;
++tmp_key;
break;
case 2:
SetCursorPosition(34, 25);
SetBackColor();
std::cout << "退出游戏" ;
SetCursorPosition(34, 23);
SetColor(11);
std::cout << "重新开始" ;
++tmp_key;
break;
}
}
break;
case 13://Enter
flag = true;
break;
default:
break;
}
if (flag)
{
break;
}
SetCursorPosition(0, 31);
}
if (tmp_key == 1) //选择继续游戏,则将菜单擦除
{
SetCursorPosition(32, 19);
std::cout << " " ;
SetCursorPosition(34, 21);
std::cout << " ";
SetCursorPosition(34, 23);
std::cout << " ";
SetCursorPosition(34, 25);
std::cout << " ";
}
return tmp_key;
}
void Controller::Game()//游戏一级循环
{
Start();//开始界面
while (true)//游戏可视为一个死循环,直到退出游戏时循环结束
{
Select();//选择界面
DrawGame();//绘制游戏界面
int tmp = PlayGame();//开启游戏循环,当重新开始或退出游戏时,结束循环并返回值给tmp
if (tmp == 1) //返回值为1时重新开始游戏
{
system("cls");
continue;
}
else if (tmp == 2) //返回值为2时退出游戏
{
break;
}
else
{
break;
}
}
}
int Controller::GameOver()//游戏结束界面
{
/*绘制游戏结束界面*/
Sleep(500);
SetColor(11);
SetCursorPosition(10, 8);
std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;
Sleep(30);
SetCursorPosition(9, 9);
std::cout << " ┃ Game Over !!! ┃" ;
Sleep(30);
SetCursorPosition(9, 10);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 11);
std::cout << " ┃ 很遗憾!你挂了 ┃" ;
Sleep(30);
SetCursorPosition(9, 12);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 13);
std::cout << " ┃ 你的分数为: ┃" ;
SetCursorPosition(24, 13);
std::cout << score ;
Sleep(30);
SetCursorPosition(9, 14);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 15);
std::cout << " ┃ 是否再来一局? ┃" ;
Sleep(30);
SetCursorPosition(9, 16);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 17);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 18);
std::cout << " ┃ 嗯,好的 不了,还是学习有意思 ┃" ;
Sleep(30);
SetCursorPosition(9, 19);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(9, 20);
std::cout << " ┃ ┃" ;
Sleep(30);
SetCursorPosition(10, 21);
std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;
Sleep(100);
SetCursorPosition(12, 18);
SetBackColor();
std::cout << "嗯,好的" ;
SetCursorPosition(0, 31);
/*选择部分*/
int ch;
int tmp_key = 1;
bool flag = false;
while ((ch = getch()))
{
switch (ch)
{
case 75://LEFT
if (tmp_key > 1)
{
SetCursorPosition(12, 18);
SetBackColor();
std::cout << "嗯,好的" ;
SetCursorPosition(20, 18);
SetColor(11);
std::cout << "不了,还是学习有意思" ;
--tmp_key;
}
break;
case 77://RIGHT
if (tmp_key < 2)
{
SetCursorPosition(20, 18);
SetBackColor();
std::cout << "不了,还是学习有意思" ;
SetCursorPosition(12, 18);
SetColor(11);
std::cout << "嗯,好的" ;
++tmp_key;
}
break;
case 13://Enter
flag = true;
break;
default:
break;
}
SetCursorPosition(0, 31);
if (flag) {
break;
}
}
SetColor(11);
switch (tmp_key)
{
case 1:
return 1;//重新开始
case 2:
return 2;//退出游戏
default:
return 1;
}
}

@ -0,0 +1,23 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
class Controller
{
public:
Controller() : speed(200), key(1), score(0) {}
void Start();
void Select();
void DrawGame();
int PlayGame();
void UpdateScore(const int&);
void RewriteScore();
int Menu();
void Game();
int GameOver();
private:
int speed;
int key;
int score;
};
#endif // CONTROLLER_H

@ -0,0 +1,119 @@
#include "food.h"
#include "tools.h"
#include <cstdlib>
#include <iostream>
void Food::DrawFood(Snake& csnake)//绘制食物
{
/*利用rand函数获得坐标,并将其范围限制在2-29内,即在地图内,如果获得的坐标与蛇身重叠,则重新获取。
5*/
while (true)
{
int tmp_x = rand() % 30;
int tmp_y = rand() % 30;
if(tmp_x < 2) tmp_x += 2;
if(tmp_y < 2) tmp_y += 2;
bool flag = false;
for (auto& point : csnake.snake)
{
if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == big_x && tmp_y == big_y)) {
flag = true;
break;
}
}
if (flag)
continue;
x = tmp_x;
y = tmp_y;
SetCursorPosition(x, y);
SetColor(13);
std::cout << "" ;
++cnt;
cnt %= 5;
if (cnt == 0)
{
DrawBigFood(csnake);
}
break;
}
}
void Food::DrawBigFood(Snake& csnake)//绘制限时食物
{
SetCursorPosition(5, 0);
SetColor(11);
std::cout << "------------------------------------------" ;//进度条
progress_bar = 42;
while (true)
{
int tmp_x = rand() % 30;
int tmp_y = rand() % 30;
if(tmp_x < 2) tmp_x += 2;
if(tmp_y < 2) tmp_y += 2;
bool flag = false;
for (auto& point : csnake.snake)
{
if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == x && tmp_y == y))
{
flag = true;
break;
}
}
if (flag)
continue;
big_x = tmp_x;
big_y = tmp_y;
SetCursorPosition(big_x, big_y);
SetColor(18);
std::cout << "" ;
big_flag = true;
flash_flag = true;
break;
}
}
int Food::GetCnt()
{
return cnt;
}
void Food::FlashBigFood()//闪烁限时食物
{
SetCursorPosition(big_x, big_y);
SetColor(18);
if (flash_flag)
{
std::cout << " " ;
flash_flag = false;
}
else
{
std::cout << "" ;
flash_flag = true;
}
SetCursorPosition(26, 0);
SetColor(11);
for (int i = 42; i >= progress_bar; --i)//进度条缩短
std::cout << "\b \b" ;
--progress_bar;
if (progress_bar == 0) {
SetCursorPosition(big_x, big_y);
std::cout << " " ;
big_flag = false;
big_x = 0;
big_y = 0;
}
}
bool Food::GetBigFlag()
{
return big_flag;
}
int Food::GetProgressBar()
{
return progress_bar;
}

@ -0,0 +1,25 @@
#ifndef FOOD_H
#define FOOD_H
#include "snake.h"
class Snake;
class Food
{
public:
Food() : cnt(0), flash_flag(false), big_flag(false), x(0), y(0), big_x(0), big_y(0), progress_bar(0) {}
void DrawFood(Snake&);
void DrawBigFood(Snake&);
int GetCnt();
void FlashBigFood();
bool GetBigFlag();
int GetProgressBar();
private:
int cnt;
bool flash_flag;//闪烁标记
bool big_flag;//是否有限时食物标记
int x, y;
int big_x, big_y;
int progress_bar;//限时食物进度条
friend class Snake;
};
#endif // FOOD_H

@ -0,0 +1,8 @@
#include "controller.h"
int main()//程序入口
{
Controller c;//声明一个Controller类
c.Game();//整个游戏循环
return 0;
}

@ -0,0 +1,11 @@
#include "map.h"
#include <windows.h>
void Map::PrintInitmap()//绘制初始地图
{
for (auto& point : initmap)
{
point.Print();
Sleep(10);//调用Sleep函数可营造动画效果
}
}

@ -0,0 +1,137 @@
#ifndef MAP_H
#define MAP_H
#include <vector>
#include "point.h"
class Map
{
public:
Map()//默认构造函数,将正方形各点压入initmap
{
initmap.emplace_back(Point(1, 1));
initmap.emplace_back(Point(2, 1));
initmap.emplace_back(Point(3, 1));
initmap.emplace_back(Point(4, 1));
initmap.emplace_back(Point(5, 1));
initmap.emplace_back(Point(6, 1));
initmap.emplace_back(Point(7, 1));
initmap.emplace_back(Point(8, 1));
initmap.emplace_back(Point(9, 1));
initmap.emplace_back(Point(10, 1));
initmap.emplace_back(Point(11, 1));
initmap.emplace_back(Point(12, 1));
initmap.emplace_back(Point(13, 1));
initmap.emplace_back(Point(14, 1));
initmap.emplace_back(Point(15, 1));
initmap.emplace_back(Point(16, 1));
initmap.emplace_back(Point(17, 1));
initmap.emplace_back(Point(18, 1));
initmap.emplace_back(Point(19, 1));
initmap.emplace_back(Point(20, 1));
initmap.emplace_back(Point(21, 1));
initmap.emplace_back(Point(22, 1));
initmap.emplace_back(Point(23, 1));
initmap.emplace_back(Point(24, 1));
initmap.emplace_back(Point(25, 1));
initmap.emplace_back(Point(26, 1));
initmap.emplace_back(Point(27, 1));
initmap.emplace_back(Point(28, 1));
initmap.emplace_back(Point(29, 1));
initmap.emplace_back(Point(30, 1));
initmap.emplace_back(Point(1, 2));
initmap.emplace_back(Point(30, 2));
initmap.emplace_back(Point(1, 3));
initmap.emplace_back(Point(30, 3));
initmap.emplace_back(Point(1, 4));
initmap.emplace_back(Point(30, 4));
initmap.emplace_back(Point(1, 5));
initmap.emplace_back(Point(30, 5));
initmap.emplace_back(Point(1, 6));
initmap.emplace_back(Point(30, 6));
initmap.emplace_back(Point(1, 7));
initmap.emplace_back(Point(30, 7));
initmap.emplace_back(Point(1, 8));
initmap.emplace_back(Point(30, 8));
initmap.emplace_back(Point(1, 9));
initmap.emplace_back(Point(30, 9));
initmap.emplace_back(Point(1, 10));
initmap.emplace_back(Point(30, 10));
initmap.emplace_back(Point(1, 11));
initmap.emplace_back(Point(30, 11));
initmap.emplace_back(Point(1, 12));
initmap.emplace_back(Point(30, 12));
initmap.emplace_back(Point(1, 13));
initmap.emplace_back(Point(30, 13));
initmap.emplace_back(Point(1, 14));
initmap.emplace_back(Point(30, 14));
initmap.emplace_back(Point(1, 15));
initmap.emplace_back(Point(30, 15));
initmap.emplace_back(Point(1, 16));
initmap.emplace_back(Point(30, 16));
initmap.emplace_back(Point(1, 17));
initmap.emplace_back(Point(30, 17));
initmap.emplace_back(Point(1, 18));
initmap.emplace_back(Point(30, 18));
initmap.emplace_back(Point(1, 19));
initmap.emplace_back(Point(30, 19));
initmap.emplace_back(Point(1, 20));
initmap.emplace_back(Point(30, 20));
initmap.emplace_back(Point(1, 21));
initmap.emplace_back(Point(30, 21));
initmap.emplace_back(Point(1, 22));
initmap.emplace_back(Point(30, 22));
initmap.emplace_back(Point(1, 23));
initmap.emplace_back(Point(30, 23));
initmap.emplace_back(Point(1, 24));
initmap.emplace_back(Point(30, 24));
initmap.emplace_back(Point(1, 25));
initmap.emplace_back(Point(30, 25));
initmap.emplace_back(Point(1, 26));
initmap.emplace_back(Point(30, 26));
initmap.emplace_back(Point(1, 27));
initmap.emplace_back(Point(30, 27));
initmap.emplace_back(Point(1, 28));
initmap.emplace_back(Point(30, 28));
initmap.emplace_back(Point(1, 29));
initmap.emplace_back(Point(30, 29));
initmap.emplace_back(Point(1, 30));
initmap.emplace_back(Point(2, 30));
initmap.emplace_back(Point(3, 30));
initmap.emplace_back(Point(4, 30));
initmap.emplace_back(Point(5, 30));
initmap.emplace_back(Point(6, 30));
initmap.emplace_back(Point(7, 30));
initmap.emplace_back(Point(8, 30));
initmap.emplace_back(Point(9, 30));
initmap.emplace_back(Point(10, 30));
initmap.emplace_back(Point(11, 30));
initmap.emplace_back(Point(12, 30));
initmap.emplace_back(Point(13, 30));
initmap.emplace_back(Point(14, 30));
initmap.emplace_back(Point(15, 30));
initmap.emplace_back(Point(16, 30));
initmap.emplace_back(Point(17, 30));
initmap.emplace_back(Point(18, 30));
initmap.emplace_back(Point(19, 30));
initmap.emplace_back(Point(20, 30));
initmap.emplace_back(Point(21, 30));
initmap.emplace_back(Point(22, 30));
initmap.emplace_back(Point(23, 30));
initmap.emplace_back(Point(24, 30));
initmap.emplace_back(Point(25, 30));
initmap.emplace_back(Point(26, 30));
initmap.emplace_back(Point(27, 30));
initmap.emplace_back(Point(28, 30));
initmap.emplace_back(Point(29, 30));
initmap.emplace_back(Point(30, 30));
}
void PrintInitmap();//绘制初始地图
private:
std::vector<Point> initmap;//保存初始地图
/*Map类可自定义多种地图,只需将表示地图的各个点保存在相应的map中,并在Snake类中增加相应判断撞墙函数即可
std::vector<Point> map1;
std::vector<Point> map2;
*/
};
#endif // MAP_H

@ -0,0 +1,27 @@
#include "point.h"
#include "tools.h"
#include <iostream>
void Point::Print()//输出方块
{
SetCursorPosition(x, y);
std::cout << "" ;
}
void Point::PrintCircular()//输出圆形
{
SetCursorPosition(x, y);
std::cout << "" ;
}
void Point::Clear()//清除输出
{
SetCursorPosition(x, y);
std::cout << " " ;
}
void Point::ChangePosition(const int x, const int y)//改变坐标
{
this->x = x;
this->y = y;
}

@ -0,0 +1,19 @@
#ifndef POINT_H
#define POINT_H
class Point
{
public:
Point(){}
Point(const int x, const int y) : x(x), y(y) {}
void Print();
void PrintCircular();
void Clear();
void ChangePosition(const int x, const int y);
bool operator== (const Point& point) { return (point.x == this->x) && (point.y == this->y); }
int GetX(){ return this->x; }
int GetY(){ return this->y; }
private:
int x, y;
};
#endif // POINT_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

@ -0,0 +1,135 @@
#include "snake.h"
#include <conio.h>
#include "tools.h"
#include <iostream>
void Snake::InitSnake()//初始化蛇
{
for (auto& point : snake)
{
point.PrintCircular();
}
}
void Snake::Move()//蛇增长
{
switch (direction)
{
case Direction::UP:
snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() - 1 ));
break;
case Direction::DOWN:
snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() + 1 ));
break;
case Direction::LEFT:
snake.emplace_back(Point(snake.back().GetX() - 1, snake.back().GetY() ));
break;
case Direction::RIGHT:
snake.emplace_back(Point(snake.back().GetX() + 1, snake.back().GetY() ));
break;
default:
break;
}
SetColor(14);
snake.back().PrintCircular();
}
void Snake::NormalMove()//蛇正常移动,头增长,尾缩短
{
Move();
snake.front().Clear();
snake.pop_front();
}
bool Snake::OverEdge()//超出边界
{
return snake.back().GetX() < 30 &&
snake.back().GetY() < 30 &&
snake.back().GetX() > 1 &&
snake.back().GetY() > 1;
}
bool Snake::HitItself()//撞到自身
{
std::deque<Point>::size_type cnt = 1;
Point *head = new Point(snake.back().GetX(), snake.back().GetY());//获得头部坐标
for (auto& point : snake) //如果整条蛇中与蛇头不相同的坐标不等于蛇长,则意味着蛇头碰撞到自身
{
if ( !(point == *head) )
++cnt;
else
break;
}
delete head;
if(cnt == snake.size())
return true;
else
return false;
}
bool Snake::ChangeDirection()//改变方向
{
char ch;
if (kbhit())//kbhit函数返回值为两个,需注意
{
ch = getch();
switch (ch)
{
case -32:
ch = getch();
switch (ch)
{
case 72:
if (direction != Direction::DOWN)//如果方向与当前运动方向相反,无效
direction = Direction::UP;
break;
case 80:
if (direction != Direction::UP)
direction = Direction::DOWN;
break;
case 75:
if (direction != Direction::RIGHT)
direction = Direction::LEFT;
break;
case 77:
if (direction != Direction::LEFT)
direction = Direction::RIGHT;
break;
default:
break;
}
return true;
case 27://ESC
return false;
default:
return true;
}
}
return true;
}
bool Snake::GetFood(const Food& cfood)
{
if (snake.back().GetX() == cfood.x && snake.back().GetY() == cfood.y)
return true;
else
return false;
}
bool Snake::GetBigFood(Food& cfood)
{
if (snake.back().GetX() == cfood.big_x && snake.back().GetY() == cfood.big_y)
{
cfood.big_flag = false;
cfood.big_x = 0;
cfood.big_y = 0;
SetCursorPosition(1, 0);
std::cout << " " ;
return true;
}
else
return false;
}

@ -0,0 +1,33 @@
#ifndef SNAKE_H
#define SNAKE_H
#include <deque>
#include "point.h"
#include "food.h"
class Food;
class Snake
{
public:
enum Direction {UP, DOWN, LEFT, RIGHT};
Snake() {
snake.emplace_back(14, 8);
snake.emplace_back(15, 8);
snake.emplace_back(16, 8);
direction = Direction::DOWN;
}
void InitSnake();
void Move();
void NormalMove();
bool OverEdge();
bool HitItself();
bool ChangeDirection();
bool GetFood(const Food&);
bool GetBigFood(Food&);
private:
std::deque<Point> snake;
Direction direction;
friend class Food;//将Food类置为友元,以便访问其私有元素
};
#endif // SNAKE_H

@ -0,0 +1,68 @@
#include "startinterface.h"
#include <windows.h>
void StartInterface::PrintFirst()//蛇从左边出现到完全出现的过程
{
for (auto& point : startsnake)
{
point.Print();
Sleep(speed);
}
}
void StartInterface::PrintSecond()//蛇从左向右移动的过程
{
for (int i = 10; i != 40; ++i) //蛇头需要从10移动到40
{
/*计算蛇头的下一个位置,并将其压入startsnake中,绘制出来,将蛇尾去掉*/
int j = ( ((i-2)%8) < 4 )?( 15 + (i-2)%8 ) : ( 21 - (i-2)%8 );
startsnake.emplace_back( Point(i, j) );
startsnake.back().Print();
startsnake.front().Clear();
startsnake.pop_front();
Sleep(speed);
}
}
void StartInterface::PrintThird()//蛇从接触右边到消失的过程
{
while ( !startsnake.empty() || textsnake.back().GetX() < 33 ) //当蛇还没消失或文字没移动到指定位置
{
if ( !startsnake.empty() ) //如果蛇还没消失,继续移动
{
startsnake.front().Clear();
startsnake.pop_front();
}
ClearText();//清除已有文字
PrintText();//绘制更新位置后的文字
Sleep(speed);
}
}
void StartInterface::PrintText()
{
for (auto& point : textsnake)
{
if (point.GetX() >= 0)
point.Print();
}
}
void StartInterface::ClearText()
{
for (auto& point : textsnake) //清除的同时将文字整体向右移动一格
{
if (point.GetX() >= 0)
point.Clear();
point.ChangePosition(point.GetX() + 1, point.GetY());
}
}
void StartInterface::Action()
{
PrintFirst();
PrintSecond();
PrintThird();
}

@ -0,0 +1,92 @@
#ifndef STRATINTERFACE_H
#define STARTINTERFACE_H
#include <deque>
#include <vector>
#include "point.h"
class StartInterface
{
public:
StartInterface() : speed(35) {
startsnake.emplace_back(Point(0,14));//Éß
startsnake.emplace_back(Point(1,14));
startsnake.emplace_back(Point(2,15));
startsnake.emplace_back(Point(3,16));
startsnake.emplace_back(Point(4,17));
startsnake.emplace_back(Point(5,18));
startsnake.emplace_back(Point(6,17));
startsnake.emplace_back(Point(7,16));
startsnake.emplace_back(Point(8,15));
startsnake.emplace_back(Point(9,14));
textsnake.emplace_back(Point(-26, 14));//S
textsnake.emplace_back(Point(-25, 14));
textsnake.emplace_back(Point(-27, 15));
textsnake.emplace_back(Point(-26, 16));
textsnake.emplace_back(Point(-25, 17));
textsnake.emplace_back(Point(-27, 18));
textsnake.emplace_back(Point(-26, 18));
textsnake.emplace_back(Point(-23, 14));//N
textsnake.emplace_back(Point(-23, 15));
textsnake.emplace_back(Point(-23, 16));
textsnake.emplace_back(Point(-23, 17));
textsnake.emplace_back(Point(-23, 18));
textsnake.emplace_back(Point(-22, 15));
textsnake.emplace_back(Point(-21, 16));
textsnake.emplace_back(Point(-20, 17));
textsnake.emplace_back(Point(-19, 14));
textsnake.emplace_back(Point(-19, 15));
textsnake.emplace_back(Point(-19, 16));
textsnake.emplace_back(Point(-19, 17));
textsnake.emplace_back(Point(-19, 18));
textsnake.emplace_back(Point(-17, 18));//A
textsnake.emplace_back(Point(-16, 17));
textsnake.emplace_back(Point(-15, 16));
textsnake.emplace_back(Point(-14, 15));
textsnake.emplace_back(Point(-14, 16));
textsnake.emplace_back(Point(-13, 14));
textsnake.emplace_back(Point(-13, 16));
textsnake.emplace_back(Point(-12, 15));
textsnake.emplace_back(Point(-12, 16));
textsnake.emplace_back(Point(-11, 16));
textsnake.emplace_back(Point(-10, 17));
textsnake.emplace_back(Point(-9, 18));
textsnake.emplace_back(Point(-7, 14));//K
textsnake.emplace_back(Point(-7, 15));
textsnake.emplace_back(Point(-7, 16));
textsnake.emplace_back(Point(-7, 17));
textsnake.emplace_back(Point(-7, 18));
textsnake.emplace_back(Point(-6, 16));
textsnake.emplace_back(Point(-5, 15));
textsnake.emplace_back(Point(-5, 17));
textsnake.emplace_back(Point(-4, 14));
textsnake.emplace_back(Point(-4, 18));
textsnake.emplace_back(Point(-2, 14));//E
textsnake.emplace_back(Point(-2, 15));
textsnake.emplace_back(Point(-2, 16));
textsnake.emplace_back(Point(-2, 17));
textsnake.emplace_back(Point(-2, 18));
textsnake.emplace_back(Point(-1, 14));
textsnake.emplace_back(Point(-1, 16));
textsnake.emplace_back(Point(-1, 18));
textsnake.emplace_back(Point(0, 14));
textsnake.emplace_back(Point(0, 16));
textsnake.emplace_back(Point(0, 18));
}
void PrintFirst();
void PrintSecond();
void PrintThird();
void PrintText();
void ClearText();
void Action();
private:
std::deque<Point> startsnake;//开始动画中的蛇
std::vector<Point> textsnake;//开始动画中的文字
int speed;//动画的速度
};
#endif // STRATINTERFACE_H

@ -0,0 +1,33 @@
#include "tools.h"
#include <windows.h>
#include <stdio.h>
void SetWindowSize(int cols, int lines)//设置窗口大小
{
system("title 贪吃蛇");//设置窗口标题
char cmd[30];
sprintf(cmd, "mode con cols=%d lines=%d", cols * 2, lines);//一个图形■占两个字符,故宽度乘以2
system(cmd);//system(mode con cols=88 lines=88)设置窗口宽度和高度
}
void SetCursorPosition(const int x, const int y)//设置光标位置
{
COORD position;
position.X = x * 2;
position.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}
void SetColor(int colorID)//设置文本颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colorID);
}
void SetBackColor()//设置文本背景色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
FOREGROUND_BLUE |
BACKGROUND_BLUE |
BACKGROUND_GREEN |
BACKGROUND_RED );
}

@ -0,0 +1,10 @@
#ifndef TOOLS_H
#define TOOLS_H
void SetWindowSize(int cols, int lines);
void SetCursorPosition(const int x, const int y);
void SetColor(int colorID);
void SetBackColor();
#endif // TOOLS_H
Loading…
Cancel
Save