写一个贪吃蛇小游戏
源.cpp
#include<iostream>
#include"wall.h"
#include"Snake.h"
#include"Food.h"
#include<ctime>
#include<conio.h>
#include<Windows.h>
#include<time.h>
using namespace std;
void gotoxy3(HANDLE hOut3, int x, int y)
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut3, pos);
}//光标定位函数
HANDLE hOut3 = GetStdHandle(STD_OUTPUT_HANDLE);
int main() {
srand((unsigned int)time(NULL));
//判断是否死亡标志
bool isDead = false;
char preKey = NULL;
int preSleepTime = 0;
//char lastKey = NULL;
//测试
Wall walltmp;
walltmp.initWall();
walltmp.DrawWall();
//walltmp.SetWall(5, 4, "@");
//walltmp.SetWall(5, 5, "=");
//walltmp.SetWall(5, 6, "=");
Food food(walltmp);
food.setFood();
Snake snaketmp(walltmp,food);
snaketmp.initSnake();
//接收用户输入
while (!isDead) {
char KeyTmp = _getch();
//lastKey = KeyTmp;
if (snaketmp.LEFT== KeyTmp && preKey == NULL) {
continue;
}
do {
if (KeyTmp==snaketmp.UP || KeyTmp == snaketmp.DOWN || KeyTmp == snaketmp.LEFT || KeyTmp == snaketmp.RIGHT) {
//判断本次文件是否与上次冲突
if ((KeyTmp == snaketmp.UP && preKey == snaketmp.DOWN)
||(KeyTmp == snaketmp.DOWN && preKey == snaketmp.UP)
||(KeyTmp == snaketmp.LEFT && preKey == snaketmp.RIGHT)
||(KeyTmp == snaketmp.RIGHT && preKey == snaketmp.LEFT)) {
KeyTmp = preKey;
}
else {
preKey = KeyTmp;
}
if (snaketmp.move(KeyTmp) == true) {
//system("cls");
//walltmp.DrawWall();
gotoxy3(hOut3, 2 * walltmp.COL_Tmp, 11);
cout << "本局游戏得分:" << snaketmp.getScore() << "分!" << endl;
if (snaketmp.getSleepTime() < 160) {
Sleep(preSleepTime);
}
else {
Sleep(snaketmp.getSleepTime());
preSleepTime = snaketmp.getSleepTime();
}
gotoxy3(hOut3, 2 * walltmp.COL_Tmp, 12);
cout << "现在的速度等级为:" << snaketmp.getSpeech(preSleepTime);
if (snaketmp.getSpeech(preSleepTime) == 4) {
gotoxy3(hOut3, 2 * walltmp.COL_Tmp, 13);
cout << "——当前已经是最高速度!";
}
}
else {
isDead = true;
break;
}
}
else {
KeyTmp = preKey;
}
} while (!_kbhit());//当没有键盘输入的时候返回 0
}
//snaketmp.delPoint();
//snaketmp.move('w');
//snaketmp.move('w');
//snaketmp.move('w');
//snaketmp.move('d');
//cout << endl << walltmp.GetWall(5,4)<< endl;
system("pause");
return EXIT_SUCCESS;
}
wall.h
#pragma once
#ifndef _WALL_H
#define _WALL_H
#include<iostream>
using namespace std;
class Wall {
public:
enum {
ROW_Tmp = 26,
COL_Tmp = 26
};
//初始化墙壁
void initWall();
//画出墙壁
void DrawWall();
//根据索引设置二维数组内容
void SetWall(int x, int y, char c);
//根据索引获取当前位置的符号
char GetWall(int x, int y);
private:
char gameArray[ROW_Tmp][COL_Tmp];
};
#endif // !_WALL_H
wall.cpp
#include"wall.h"
void Wall::initWall() {
for (int i = 0; i < ROW_Tmp; i++) {
for (int j = 0; j < COL_Tmp; j++) {
//
if (i==0 || j==0 || i==ROW_Tmp-1 || j==COL_Tmp-1) {
gameArray[i][j] = '*';
}
else {
gameArray[i][j] = ' ' ;
}
}
}
}
void Wall::DrawWall()
{
for (int i = 0; i < ROW_Tmp;i++) {
for (int j = 0; j < COL_Tmp;j++) {
cout << gameArray[i][j] << " ";
}
if (i == 5) {
cout << "杨子江手打!";
}
if (i == 6) {
cout << "一定要切换成英文输入法!";
}
if (i == 7) {
cout << "按键 A :Left";
}
if (i == 8) {
cout << "按键 D :Right";
}
if (i == 9) {
cout << "按键 W :Up";
}
if (i == 10) {
cout << "按键 S :Down";
}
cout << endl;
}
}
void Wall::SetWall(int x, int y, char c)
{
gameArray[x][y] = c;
}
char Wall::GetWall(int x, int y)
{
return gameArray[x][y];
}
food.h
#pragma once
#include<iostream>
#include"wall.h"
using namespace std;
class Food {
public:
Food(Wall &wall);
//设置食物
void setFood();
Wall &wall;
int foodX;
int foodY;
};
food.cpp
#include "Food.h"
#include<Windows.h>
void gotoxy2(HANDLE hOut2, int x, int y)
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut2, pos);
}//光标定位函数
HANDLE hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);
Food::Food(Wall &wall): wall(wall)
{
}
void Food::setFood()
{
while (true) {
foodX = rand() % (Wall::ROW_Tmp - 2) + 1;
foodY = rand() % (Wall::COL_Tmp - 2) + 1;
//如果随机数是蛇头或者蛇身,就生成新的随机数
if (wall.GetWall(foodX, foodY) == ' ') {
wall.SetWall(foodX, foodY, '#');
gotoxy2(hOut2, 2 * foodY, foodX);
cout << "#";
break;
}
}
}
snake.h
#pragma once
#include<iostream>
#include"wall.h"
#include"Food.h"
using namespace std;
class Snake {
public:
Snake(Wall &pWall,Food &pFood);
~Snake();
enum {
UP = 'w',DOWN = 's',LEFT = 'a',RIGHT = 'd'
};
//节点
struct Point {
//数据域
int x;
int y;
//指针域
Point *Next;
};
Point *pHead;
//初始化
void initSnake();
//销毁节点
void destroySnake();
//添加节点
void addSnake(int x1,int y1);
//
void delPoint();
//
bool move(char Key);
Wall &wall;
Food &food;
bool isRool=false;//蛇本身的循环
//辅助玩法
//获取蛇长度和增加游戏速度
int getSize();
int getSleepTime();
//显示得分
int getScore();
//显示速度
int getSpeech(int a);
};
snake.cpp
#include"Snake.h"
#include<Windows.h>
void gotoxy1(HANDLE hOut1, int x, int y)
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut1, pos);
}//光标定位函数
HANDLE hOut1 = GetStdHandle(STD_OUTPUT_HANDLE);
Snake::Snake( Wall &pWall,Food &pFood) : wall(pWall) ,food(pFood)
{
pHead = NULL;
}
Snake::~Snake()
{
}
void Snake::initSnake()
{
destroySnake();
addSnake(5, 3);
addSnake(5, 4);
addSnake(5, 5);
}
void Snake::destroySnake()
{
Point *pCur = pHead;
if (pHead !=NULL) {
pCur = pHead->Next;
delete pHead;
pHead = pCur;
}
}
void Snake::addSnake(int x1, int y1)
{
Point *NewPoint = new Point;
NewPoint->x = x1;
NewPoint->y = y1;
NewPoint->Next = NULL;
//如果头不为空,则改为身子
if (pHead != NULL) {
wall.SetWall(pHead->x, pHead->y, '=');
gotoxy1(hOut1, 2 * pHead->y, pHead->x);
cout << "=";
}
NewPoint->Next = pHead;
pHead = NewPoint;
wall.SetWall(pHead->x, pHead->y,'@');
gotoxy1(hOut1, 2 * pHead->y, pHead->x);
cout << "@";
}
void Snake::delPoint()
{
//两个节点以上 才能删除操作
if (pHead==NULL || pHead->Next==NULL) {
return;
}
//找到尾节点
Point *pCur = pHead->Next;
Point *pPre = pHead;
while (pCur->Next!=NULL) {
pPre = pPre->Next;
pCur = pCur->Next;
}
//删除尾结点
wall.SetWall(pCur->x, pCur->y,' ');
gotoxy1(hOut1, 2 * pCur->y, pCur->x);
cout << " ";
delete pCur;
pCur = NULL;
pPre->Next = NULL;
}
bool Snake::move(char Key)
{
int x = pHead->x;
int y = pHead->y;
switch (Key)
{
case UP:
x--;
break;
case DOWN:
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
//如果下一步碰到的是尾巴 不应该死亡
Point *pCur = pHead->Next;
Point *pPre = pHead;
while (pCur->Next != NULL) {
pPre = pPre->Next;
pCur = pCur->Next;
}
if (pCur->x==x && pCur->y==y) {
isRool = true;
}
else {
//判断用户到达位置是否成功
if (wall.GetWall(x, y) == '*' ) {
addSnake(x, y);
delPoint();
//system("cls");
//wall.DrawWall();
gotoxy1(hOut1, 2 * wall.COL_Tmp, 11);
cout << "本局游戏得分:" << getScore() << "分!" << endl;
gotoxy1(hOut1, 0, wall.ROW_Tmp);
cout << "————你撞到墙了!————" << endl;
cout << "———— 游戏结束!————" << endl;
return false;
}
else if (wall.GetWall(x, y) == '='){
//wall.DrawWall();
gotoxy1(hOut1, 2 * wall.COL_Tmp, 11);
cout << "本局游戏得分:" << getScore() << "分!" << endl;
gotoxy1(hOut1, 0, wall.ROW_Tmp);
cout << "————你吃到了自己的身子!————" << endl;
cout << "———— 游戏结束! ————" << endl;
return false;
}
}
//移动成功
//1、吃到食物;2、未吃食物
if (wall.GetWall(x,y)=='#') {
this->addSnake(x,y);
//重新设置食物
food.setFood();
}
else {
this->addSnake(x, y);
this->delPoint();
if (isRool) {
wall.SetWall(x, y, '@');
gotoxy1(hOut1, 2 * y, x);
cout << "@";
}
}
return true;
}
int Snake::getSize()
{
int size = 0;
Point *CurPoint = pHead;
while (CurPoint!=NULL) {
size++;
CurPoint = CurPoint->Next;
}
return size;
}
int Snake::getSleepTime()
{
int size = getSize();
int SleepTime = 0;
if (size < 5) { SleepTime = 300; }
else if(size > 5 && size < 8) { SleepTime = 240; }
else if(size > 8 && size < 12) { SleepTime = 200; }
else if(size > 12){ SleepTime = 160; }
return SleepTime;
}
int Snake::getScore()
{
int getScore = 0;
int size = getSize();
getScore = (size - 3) * 100;
return getScore;
}
int Snake::getSpeech(int a)
{
int size = 0;
switch ( a )
{
case 300:
size = 1;
break;
case 240:
size = 2;
break;
case 200:
size = 3;
break;
case 160:
size = 4;
break;
default:
break;
}
return size;
}
我的运行结果如下: