VS2017
Snake.h
#pragma once
#include <iostream>
#include <windows.h>
#include <vector>
using namespace std;
class Snake
{
public:
Snake();
void gotoxy(int x, int y);
char get_cSnake_b(void); //获取蛇身图形
int m_iX; //蛇身横向坐标
int m_iY; //蛇身纵向坐标
static int c_iX; //公共坐标
static int c_iY; //公共坐标
private:
char m_cSnake_b; //蛇身图形
};
Snake_body.h
#pragma once
#include "Snake.h"
#include <conio.h>
class Snake_body :public Snake
{
public:
Snake_body();
void m_Int(void);
void set_vSnake_b(Snake t_x); //往向量里添加新的蛇身
void prt_vSnake_b(void); //打印蛇身
void erase_vSnake_b(void); //将老的蛇尾的坐标显示为空,并且删除老的蛇尾
void ctr_Direction(char c_key); //获取用户按键,控制方向移动
char ctr_Collide(void); //碰撞
void ctr_Level(void); //过关
bool ctr_Food(int x, int y); //吃食物
public:
static int m_iScore; //得分
static int m_iLevel; //关卡
static int key2;
private:
vector<Snake>m_vSnake_b; //蛇向量
};
Snake_food.h
#include "Snake.h"
#include <time.h>
class Snake_food : public Snake
{
public:
Snake_food();
void prtSnake_food(int *x, int *y); //打印食物
int m_ifX; //食物横坐标
int m_ifY; //食物纵坐标
private:
char *m_cSnake_food; //食物图形
};
Snake.cpp
#include "Snake.h"
int Snake::c_iX = 30;
int Snake::c_iY = 10;
Snake::Snake()
{
m_cSnake_b = '*';
}
void Snake::gotoxy(int x, int y)
{
COORD pos;
pos.X = x - 1;
pos.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
//获取蛇身图形
char Snake::get_cSnake_b(void)
{
return m_cSnake_b;
}
Snake_body.cpp
#include "Snake_body.h"
Snake_body::Snake_body()
{
}
int Snake_body::m_iScore = 0;
int Snake_body::m_iLevel = 1;
int Snake_body::key2 = 1;
void Snake_body::m_Int(void)
{
Snake tmp;
for (int i = 0; i < 35; i++)
{
cout << "o ";
}
cout << endl;
for (int i = 0; i < 25; i++)
{
cout << "o o" << endl;
}
for (int i = 0; i < 35; i++)
{
cout << "o ";
}
tmp.gotoxy(80, 2);
cout << "贪吃蛇";
tmp.gotoxy(72, 10);
cout << "游戏说明:";
tmp.gotoxy(72, 12);
cout << "使用W、A、S、D控制蛇的移动,";
tmp.gotoxy(72, 14);
cout << "每吃一个食物加一分。";
tmp.gotoxy(77, 25);
cout << "作者:完美教父";
}
//往向量里添加新的蛇身
void Snake_body::set_vSnake_b(Snake t_x)
{
m_vSnake_b.push_back(t_x);
}
//打印蛇
void Snake_body::prt_vSnake_b(void)
{
for (unsigned i = 0; i < m_vSnake_b.size(); i++)
{
this->gotoxy(m_vSnake_b[i].m_iX, m_vSnake_b[i].m_iY);
cout << m_vSnake_b[i].get_cSnake_b();
}
}
//删除第一个元素,并且将第一个元素坐标打印成空格,使实现移动
void Snake_body::erase_vSnake_b(void)
{
//将向量第一个元素的位置打印成空,方便形成蛇移动
gotoxy(m_vSnake_b[0].m_iX, m_vSnake_b[0].m_iY);
cout << " ";
//删除向量中第一个元素
m_vSnake_b.erase(m_vSnake_b.begin());
}
//碰撞
char Snake_body::ctr_Collide(void)
{
char Collide_key = '0';
if (!((m_vSnake_b.back().c_iX < 68 && m_vSnake_b.back().c_iX>2) && (m_vSnake_b.back().c_iY < 26 && m_vSnake_b.back().c_iY>2)))
{
this->gotoxy(25, 25);
cout << "撞墙啦,傻瓜!按任意键...";
_getch();
this->gotoxy(25, 25);
cout << "重新开始吗?回车确定!按ESC退出!";
Collide_key = _getch();
return Collide_key;
}
for (unsigned i = 0;i < m_vSnake_b.size() - 1;i++)
{
if (m_vSnake_b.back().c_iX == m_vSnake_b[i].m_iX&&m_vSnake_b.back().c_iY == m_vSnake_b[i].m_iY)
{
this->gotoxy(25, 25);
cout << "撞身体啦,呆子!按任意键...";
_getch();
this->gotoxy(25, 25);
cout << "重新开始吗?回车确定!按ESC退出!";
Collide_key = _getch();
return Collide_key;
}
}
return 0;
}
//吃食物
bool Snake_body::ctr_Food(int x, int y)
{
Snake *snake = NULL;
if (m_vSnake_b.back().m_iX == x && m_vSnake_b.back().m_iY == y)
{
//吃到食物加分
Snake_body::m_iScore++;
//如果吃到食物就加一个身体
snake = new Snake;
snake->m_iX = Snake::c_iX;
snake->m_iY = Snake::c_iY;
this->set_vSnake_b(*snake);
return true;
}
return false;
}
//控制方向
void Snake_body::ctr_Direction(char c_key)
{
char c_k = c_key;
int m_itDirection = 0; //方向标签,表示当时以什么方向移动 1.2.3.4代表上下左右,使用方向标签的作用主要是控制蛇不可以倒着移动,比如向上移动时d,按向下键s时无响应,依此类推
if (c_k == 'w') //上
{
m_itDirection = 1;
if (Snake_body::key2 == 1 || Snake_body::key2 == 3 || Snake_body::key2 == 4)
{
c_iY--;
Snake_body::key2 = m_itDirection;
}
else
{
c_iY++;
}
}
else if (c_k == 's') //下
{
m_itDirection = 2;
if (Snake_body::key2 == 2 || Snake_body::key2 == 3 || Snake_body::key2 == 4)
{
c_iY++;
Snake_body::key2 = m_itDirection;
}
else
{
c_iY--;
}
}
else if (c_k == 'a') //左
{
m_itDirection = 3;
if (Snake_body::key2 == 1 || Snake_body::key2 == 2 || Snake_body::key2 == 3)
{
c_iX--;
Snake_body::key2 = m_itDirection;
}
else
{
c_iX++;
}
}
else if (c_k == 'd') //右
{
m_itDirection = 4;
if (Snake_body::key2 == 1 || Snake_body::key2 == 2 || Snake_body::key2 == 4)
{
c_iX++;
Snake_body::key2 = m_itDirection;
}
else
{
c_iX--;
}
}
//在没有按任何键时,默认向右移
else
{
c_iX++;
m_itDirection = 4;
Snake_body::key2 = m_itDirection;
}
Snake *snake;
snake = new Snake;
snake->m_iX = c_iX;
snake->m_iY = c_iY;
snake->gotoxy(snake->m_iX, snake->m_iY);
cout << snake->get_cSnake_b(); //打印出添加的新蛇头
this->set_vSnake_b(*snake); //将新的蛇头加入向量中
this->erase_vSnake_b(); //将老的蛇尾的坐标显示为空,并且删除老的蛇尾
}
//控制通关
void Snake_body::ctr_Level(void)
{
switch (m_iLevel)
{
case 1:
if (m_iScore == 10)
{
m_iLevel++;
m_iScore = 0;
this->gotoxy(73, 5);
cout << " ";
}
break;
case 2:
if (m_iScore == 60)
{
m_iLevel++;
m_iScore = 0;
this->gotoxy(73, 5);
cout << " ";
}
break;
case 3:
if (m_iScore == 100)
{
this->gotoxy(25, 15);
cout << "恭喜你通关!你真棒!";
this->gotoxy(25, 17);
cout << "按任意键退出!";
_getch();
exit(1);
}
break;
}
}
Snake_food.cpp
#include "Snake_food.h"
Snake_food::Snake_food()
{
m_cSnake_food = new char;
*m_cSnake_food = '&';
m_ifX = 5;
m_ifY = 5;
}
//打印食物
void Snake_food::prtSnake_food(int *x, int *y)
{
srand((unsigned)time(NULL));
*x = rand() % 62 + 5;
*y = rand() % 24 + 2;
this->gotoxy(*x, *y);
cout << *m_cSnake_food;
}
Star.cpp
#include "Snake.h"
#include "Snake_body.h"
#include "Snake_food.h"
#include <stdlib.h>
#include <conio.h>
using namespace std;
#define SNAKE_COUNT 6 //初始化蛇身长度
#define SNAKE_SPEED 100 //游戏速度
int main(void)
{
rst:
Snake *snake = NULL; //单个蛇身
Snake_body snake_b; //蛇
Snake_food snake_f; //食物
snake_b.m_Int(); //初始化界面
char key = 0; //接收用户的按键
char key1 = 0; //使用暂停
//初始化蛇身
for (int i = 0; i < SNAKE_COUNT; i++)
{
snake = new Snake;
snake->m_iX = Snake::c_iX;
snake->m_iY = Snake::c_iY;
snake_b.set_vSnake_b(*snake);
Snake::c_iX++;
}
//打印初始化的蛇身
snake_b.prt_vSnake_b();
Snake::c_iX -= 1;
//打印初始化的食物
snake_f.prtSnake_food(&snake_f.m_ifX, &snake_f.m_ifY);
//循环游戏开始
while (1)
{
//监听键盘操作
if (_kbhit())
{
key = _getch();
}
//用户输入处理
if (key == 13)
{
snake_b.gotoxy(25, 25);
cout << "暂停游戏中。。。!";
_getch();
key = key1;
snake_b.gotoxy(25, 25);
cout << " ";
}
else if (key == 27)
{
snake_b.gotoxy(25, 25);
cout << "确定退出吗?回车键退出!其它任意键返回!";
char key2 = _getch();
if (key2 == 13)
{
exit(1);
}
key = key1;
snake_b.gotoxy(25, 25);
cout << " ";
}
else
{
//从暂停恢复游戏
key1 = key;
}
//控制蛇的移动方向
snake_b.ctr_Direction(key);
//检测碰撞及碰撞后的按键处理
char tmp_Collide = snake_b.ctr_Collide();
if (tmp_Collide == 13)
{
Snake_body::m_iScore = 0;
Snake::c_iX = 30;
Snake::c_iY = 10;
system("cls");
goto rst;
}
else if (tmp_Collide == 27)
{
exit(1);
}
else if (0 != tmp_Collide)
{
snake_b.gotoxy(25, 25);
cout << "输入错误!按任意键退出! ";
_getch();
exit(1);
}
//判断是否吃到食物
if (snake_b.ctr_Food(snake_f.m_ifX, snake_f.m_ifY))
{
//打印初始化的食物(再刷个食物出来)
snake_f.prtSnake_food(&snake_f.m_ifX, &snake_f.m_ifY);
}
snake_b.gotoxy(72, 5);
cout << "得分: " << Snake_body::m_iScore;
snake_b.gotoxy(72, 7);
cout << "关卡: " << Snake_body::m_iLevel;
snake_b.ctr_Level();
Sleep(SNAKE_SPEED);
}
system("pause");
return 0;
}