参考其他人的代码用自己的习惯写了一版
墙
Wall.h
#pragma once
#ifndef _Util_Wall_Def
#define _Util_Wall_Def
#include
#include "mPoint.h"
#include "Food.h"
class Wall
{
public:
Wall();
int getHight();
int getWidth();
void setHight(int hight);
void setWidth(int width);
void drawWall();
bool checkTouchWall(class mPoint* np);
private:
int hight ;
int width;
};
#endif
Wall.cpp
#include "Wall.h"
Wall::Wall()
{
hight = 25;
width = hight * 2;
}
int Wall::getHight() {
return hight;
}
int Wall::getWidth() {
return width;
}
void Wall::setHight(int hight)
{
this->hight = hight;
}
void Wall::setWidth(int width)
{
this->width = width;
}
bool static checkSamePoint(mPoint p1, mPoint p2)
{
if (p1.x == p2.x && p1.y == p2.y) return true;
return false;
}
bool Wall::checkTouchWall(mPoint* cp)
{
if (cp->getX() < width-1 && cp->getY() < hight-1 && cp->getX()>0&& cp->getY()>0) {
return false;
}
else {
return true;
}
}
void Wall::drawWall()
{
for (int i = 0; i < width; i++)
{
for (int j = 0; j < hight; j++)
{
if (i == 0 || i == width - 1)//上下
{
Util::drawxy(i, j, "*",2);
continue;
}
if (j == 0 || j == hight - 1 )
{
Util::drawxy(i, j, "*",2);
continue;
}
}
}
stringstream ss;
ss << "Left:a Right:d,Up:w,Down:s ";
Util::drawxy(60, 8, ss.str(),3);
}
食物
Food.h
#pragma once
#ifndef _Food_Head_Def
#define _Food_Head_Def
#include "Snake.h"
#include "Wall.h"
using namespace std;
class Food
{
public:
Food(class Wall* wall,class Snake* snake);
int getX();
int getY();
bool getStatus();
void setStatus(bool status);
void clear();
private:
int x;
int y;
bool status;
};
#endif
Food.cpp
#include "Food.h"
Food::Food(class Wall* wall, class Snake* snake)
{
LOOP:
x = Util::getRandomNum(1, wall->getWidth() - 2);
y = Util::getRandomNum(1, wall->getHight() - 2);
//bool touch = snake.touchSnake(x, y);
mPoint tmp(x,y);
if (!snake->touchSnake(snake,tmp)) {
Util::drawxy(x, y, "$",1);
setStatus(true);
}
else {
goto LOOP;
}
}
int Food::getX()
{
return x;
}
int Food::getY()
{
return y;
}
bool Food::getStatus()
{
return status;
}
void Food::setStatus(bool status)
{
this->status = status;
}
void Food::clear()
{
Util::drawxy(x, y, " ", 1);
}
;
蛇
Snake.h
#pragma once
#ifndef _Snake_Head_Def
#define _Snake_Head_Def
#include
#include
#include
#include "mPoint.h"
#include "Wall.h"
using namespace std;
class Snake
{
public:
enum moveDirection { RIGHT=1, DOWN=-2, LEFT=-1, UP=2 };
Snake(class Wall* tmpwall);
bool move(class Food* food, class Wall* wall);
int size();
int getDirection();
//算成绩
void draw(int headColor);
class mPoint getHead();
void clear();
bool touchSnake(class Snake* snake, class mPoint m);
bool currentUpOrDown();
private:
list *head_body;
void addPoint(class mPoint np);
void removeEnd();
bool alive;
int currentDir;
};
#endif
Snake.cpp
#include "Snake.h"
void Snake::removeEnd()
{
mPoint m = head_body->back();
head_body->pop_back();
Util::drawxy(m," ",3);
}
void Snake::addPoint(mPoint np)
{
head_body->push_back(np);
}
Snake::Snake(Wall* tmpwall)
{
alive = true;
mPoint np(10,10);
mPoint np2(9,10);
mPoint np3(8,10);
head_body = new list;
head_body->push_front(np3);
head_body->push_front(np2);
head_body->push_front(np);
currentDir = moveDirection::RIGHT;
};
bool Snake::move(Food* food,Wall* wall)
{
mPoint np;
mPoint head = getHead();
int _x = head.getX();
int _y = head.getY();
switch (currentDir) {
case moveDirection::UP:
np.setX(_x);
np.setY(_y - 1);
break;
case moveDirection::DOWN:
np.setX(_x);
np.setY(_y + 1);
break;
case moveDirection::LEFT:
np.setX(_x - 1);
np.setY(_y);
break;
case moveDirection::RIGHT:
np.setX(_x + 1);
np.setY(_y);
break;
}
//是否碰到自己
mPoint m;
for (list::iterator ite = head_body->begin(); ite != head_body->end(); ite++) {
m = *ite;
if (m.getX() == np.getX() && m.getY() == np.getY()) {
Util::printInfo("Touch Snake Body!");
head_body->push_front(np);
draw(1);
return false;
}
}
//是否撞墙
if (wall->checkTouchWall(&np)) {
Util::printInfo("Touch Wall!");
head_body->push_front(np);
draw(1);
return false;
}
//是否吃到食物
if (np.getX() == food->getX() && np.getY() == food->getY()) {
Util::printInfo("Got Food!");
food->setStatus(false);
}
else {
if (head_body->size() > 2) {
removeEnd();
}
}
head_body->push_front(np);
return true;
}
int Snake::getDirection() {
char input= 'N';
while (_kbhit())
{
input = _getch();
}
int dir = currentDir;
switch (input)
{
case 'w':dir =2; break;
case 'W':dir = 2; break;
case 's':dir = -2; break;
case 'S':dir = -2; break;
case 'a':dir = -1; break;
case 'A':dir = -1; break;
case 'd':dir = 1; break;
case 'D':dir = 1; break;
}
if (dir == this->currentDir*-1) {
//dir = this->currentDir;
}else {
this->currentDir = dir;
}
return dir;
}
void Snake::draw(int headColor)
{
if (!head_body->empty())
{
int i = 0;
for (list::iterator it = head_body->begin(); it != head_body->end(); it++, i++)
{
mPoint cp = *it;
if (i != 0) {
Util::drawxy(cp, "#",2);
}
}
mPoint head = getHead();
Util::drawxy(head, "@", headColor);
}
}
mPoint Snake::getHead() {
return head_body->front();
}
void Snake::clear()
{
if (!head_body->empty())
{
for (list::iterator it = head_body->begin(); it != head_body->end(); it++)
{
mPoint cp = *it;
Util::drawxy(cp, " ", 2);
}
}
}
bool Snake::touchSnake(Snake* snake, mPoint m)
{
if (head_body != nullptr&&head_body->size()>0) {
for (list ::iterator ite = head_body->begin(); ite != head_body->end(); ite++)
{
if(ite->getX()==m.getX()&& ite->getY() == m.getY())
return true;
}
}
return false;
}
bool Snake::currentUpOrDown()
{
switch (currentDir) {
case moveDirection::UP:
return true;
case moveDirection::DOWN:
return true;
case moveDirection::LEFT:
return false;
case moveDirection::RIGHT:
return false;
}
return false;
}
int Snake::size()
{
return head_body->size();
}
点
mPoint.h
#pragma once
#ifndef _CPoint_Head_Def
#define _CPoint_Head_Def
#include
#include
#include "Util.h"
using namespace std;
class mPoint
{
public:
mPoint(int x, int y);
mPoint();
int getX();
int getY();
void draw(string str, int color);
void clear();
void setX(int x);
void setY(int y);
friend class Util;
friend static bool checkSamePoint(mPoint p1, mPoint p2);
private:
int x;
int y;
};
#endif
mPoint.cpp
#include "mPoint.h"
void mPoint::draw(string str,int color)
{
Util::drawxy(x, y, str, color);
}
void mPoint::clear() {
Util::drawxy(x, y, " ",1);
}
void mPoint::setX(int x)
{
this->x = x;
}
void mPoint::setY(int y)
{
this->y = y;
}
mPoint::mPoint(int x, int y)
{
this->x = x;
this->y = y;
}
mPoint::mPoint()
{
}
int mPoint::getX()
{
return x;
}
int mPoint::getY()
{
return y;
}
工具
Util.h
#pragma once
#ifndef _Util_Head_Def
#define _Util_Head_Def
#include
#include
#include
#include "Snake.h"
#include "Util.h"
using namespace std;
class Util
{
public:
enum COLOR{RED=1,GREEN=2,BLUE=3};
static void gotoxy(int x, int y);
static void drawxy(int x, int y, string str, int color);
static void drawxy(class mPoint mp, string str, int color);
static int getRandomNum(int limitDown, int limitUp);
static void printScore(class Snake* snake);
static void printInfo(string str);
static void printFinalInfo(string str);
};
#endif
Util.cpp
#include "Util.h"
void Util::gotoxy(int x, int y)
{
COORD coord = { (short)x,(short)y };
HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hHandle, coord);
}
void Util::drawxy(int x, int y, string str,int color)
{
gotoxy(x, y);
HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
switch (color)
{
case COLOR::GREEN:
SetConsoleTextAttribute(hHandle, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
case COLOR::RED:
SetConsoleTextAttribute(hHandle, FOREGROUND_RED | FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
case COLOR::BLUE:
SetConsoleTextAttribute(hHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
}
cout << str;
}
void Util::drawxy(mPoint mp, string str, int color)
{
drawxy(mp.getX(),mp.getY(),str,color);
}
int Util::getRandomNum(int limitDown, int limitUp)
{
srand(time(NULL));
return limitDown + rand() % limitUp;
}
void Util::printScore(Snake* snake)
{
int i= snake->size();
stringstream ss;
ss << "score:" << i-3;
drawxy(60, 10, ss.str(),2);
}
void Util::printInfo(string str)
{
drawxy(60,12,str,1) ;
}
void Util::printFinalInfo(string str)
{
drawxy(60, 14, str, 1);
}
主程序(main)
SnakeGame.cpp
#include
#include "Util.h"
#include "Wall.h"
#include "Snake.h"
#include "Food.h"
#include
int main()
{
Snake* snake = nullptr;
Food* food = nullptr;
LOOP:
if (food != nullptr) {
food->clear();
}
if (snake != nullptr) {
snake->clear();
}
Wall *wall=new Wall();
wall->drawWall();
snake = new Snake(wall);
food = new Food(wall, snake);
bool foodAvailable = true;
bool alive = true;
while (alive)
{
snake->draw(2);
snake->getDirection();
if (!food->getStatus()) {
food = new Food(wall, snake);
}
if (!snake->move(food,wall)) {
alive = false;
}
else {
snake->draw(2);
Util::printScore(snake);
if (snake->currentUpOrDown()) {
Sleep(400);
}
else {
Sleep(200);
}
}
}
Util::printFinalInfo("Game Over! Press Y to Restart!");
while (1)
{
while (_kbhit()) {
char c = _getch();
if (c == 'y' || c == 'Y')
{
goto LOOP;
}
}
}
}