用C++写一个贪吃蛇游戏(dos界面)

用C++写一个贪吃蛇游戏(dos界面)

效果大概是这样的:
在这里插入图片描述
游戏分为三个模块:(用三个类封装起来)

  • 1.墙
  • 2.食物
  • 3.蛇

关键的函数

  • 1
    #include<conio.h>
    中的_getch();可以不回显的输入w(上)s(下)a(左)d(有)
    它的返回值是输入的函数(c++中要加_,c中不需要)

  • 2
    <windows.h>
    中的Sleep(时间);

  • 3
    #include<conio.h>
    中的_kbhit();用于检查输入缓冲区中有没有内容,有内容返回true,无返回false(c++中要加_,c中不需要)

  • 4
    #include<system.h>
    中的:
    void gotoxy0(HANDLE hOut0, int x, int y) {
    COORD pos;
    pos.X = x;//横坐标
    pos.Y = y;//纵坐标
    SetConsoleCursorPosition(hOut0, pos);
    }
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定显示器的句柄变量

用于定义光标位置:
gotoxy(hOut,y,x);

代码如下:

--------------------------------------------------------
/*墙模块*/
//Wall.h
#pragma once
#include<iostream>
using namespace std;
class Wall {
public:
	enum{ROW=30,COL=30};
	//初始化
	void initWall() {
		for (int i = 0; i < ROW; ++i) {
			for (int j = 0; j < COL; ++j) {
				if (0==i||0==j||29==i||29==j) {
					wallArray[i][j] = '#';
				}
				else
					wallArray[i][j] = 32;
			}
		}
	}
	//画墙
	void print();
	char getWall(int a,int b);
	void setWall(int a,int b,char ch);
private:
	char wallArray[ROW][COL];
};
//Wall.cpp
#include"Wall.h"
//画墙
void Wall::print() {
	for (int i = 0; i < ROW; ++i) {
		for (int j = 0; j < COL; ++j) {
				cout<<wallArray[i][j]<<" ";
		}
		cout << endl;
	}
}
char Wall::getWall(int a, int b) {
	return wallArray[a][b];
}
void Wall::setWall(int a, int b, char ch) {
	wallArray[a][b] = ch;
}
-------------------------------------------------------
--------------------------------------------------------
/*食物模块*/
//Food.h
#pragma once
#include"Wall.h"
#include"Snake.h"


class Food {
public:
	Food(Wall& wall);
	//初始化(放置食物)
	void initFood();

private:
	int food_X;
	int food_Y;
	char ch = '+';
	
	Wall& m_wall;
};
--------------------------------------------------------
//Food.cpp
#include"Food.h"
#include<ctime>
#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);//定显示器的句柄变量

Food::Food(Wall& wall):m_wall(wall) {

}
//初始化(放置食物)
void Food::initFood() {
	//随机数种子
	srand((unsigned int)time(NULL));
	while(true){
		food_X = rand() % 28 + 1;
		food_Y = rand() % 28 + 1;
		if (32 == m_wall.getWall(food_X, food_Y)) {
			m_wall.setWall(food_X, food_Y, ch);
			gotoxy1(hOut1, food_Y * 2, food_X);
			cout << "+";

			break;//如果蛇填满屏幕就会死循环
		}
	}
}
--------------------------------------------------------
--------------------------------------------------------
/*蛇模块*/
//Snake.h
#pragma once
#include"Wall.h"
#include"Food.h"


class Snake {
public:
	Snake(Wall& wall);
	//初始化
	void initSanke();
	//清空结点
	void destroyPoint();
	//添加结点
	void addPoint(int a, int b);
	//删除尾结点
	void delPoint();
	//移动
	bool move(char FangXiang);
	//设定难度
	int getSleepTime();
	//获得蛇的长度	
	int countList();
	//分数记录
	int getScore();
private:
	struct Point {
		int x = 0;
		int y = 0;
		char ch=32;//空格

		Point* next;
	};
	//头指针
	Point* head;
	Wall* m_wall;
public:
	enum {
		up = 'w', down = 's', left = 'a', right = 'd'
	};
};
--------------------------------------------------------
//Snake.cpp
#include"Snake.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);//定显示器的句柄变量

Snake::Snake(Wall& wall):m_wall(&wall),head(NULL) {
	
}
//初始化
void Snake::initSanke() {
	destroyPoint();
	addPoint(5, 3);
	addPoint(5, 4);
	addPoint(5, 5);
	//放入
	if (NULL != head) {
		for (Point* p = head; p;) {
			m_wall->setWall(p->x, p->y, p->ch);
			p = p->next;
		}
	}
}
//清空结点
void Snake::destroyPoint() {
	if (NULL != head) {
		for (Point* p = head; p;) {
			Point* Np = p->next;
			delete p;
			p = Np;

		}
		head = NULL;
	}
}
//添加结点
void Snake::addPoint(int a,int b) {
	Point*Np = NULL;
	if (NULL == head) {
		head= new Point;
		head->x = a;
		head->y = b;
		head->ch = 'O';
		head->next = NULL;
		
		Np = head;
	}
	else {
		Point* NewNode=new Point;
		NewNode->x = a;
		NewNode->y = b;
		NewNode->ch = 'O';
		head->ch = '*';
		m_wall->setWall(head->x, head->y, head->ch);//放入
		gotoxy2(hOut2, head->y * 2, head->x);
		cout << head->ch;

		NewNode->next=head;
		head = NewNode;

		Np = NewNode;
	}
	//放入
	m_wall->setWall(Np->x, Np->y, Np->ch);
	gotoxy2(hOut2, Np->y * 2, Np->x);
	cout << Np->ch;
}
//删除尾结点
void Snake::delPoint() {
	if (NULL == head || NULL == head->next) {
		return;
	}
	Point* pa = head;
	Point* pb = head->next;
	while (pb->next != NULL) {
		pa = pb;
		pb = pb->next;
	}
	//放入
	m_wall->setWall(pb->x, pb->y, 32);
	gotoxy2(hOut2, pb->y * 2, pb->x);
	cout << " ";

	//释放结点空间
	delete pb;
	pb = NULL;
	pa->next = NULL;
}
//移动
bool Snake::move(char FangXiang) {
	int x = head->x;
	int y = head->y;
	
	switch(FangXiang){
	case up:
		--x;
		break;
	case down:
		++x;
		break;
	case left:
		y--;
		break;
	case right:
		y++;
		break;
	default:
		break;
	};
	char c = m_wall->getWall(x, y);
	
	Point* pa = head;//寻找尾结点
	while (pa->next != NULL) {
		pa = pa->next;
	}
	if((x==pa->x)&&(y==pa->y)){//判断是否为尾结点
		delPoint();
		addPoint(x, y);
	}
	else if ('#' == c || '*' == c || 'O' == c) {//是否
		cout << "GEME OVER" << endl;
		return false;
	}
	else if ('+' == c) {
		addPoint(x, y);
		Food food(*m_wall);
		food.initFood();
	}
	else {
		delPoint();
		addPoint(x, y);
		
	}
	return true;

}
//设定难度
int Snake::getSleepTime() {
	int size = countList();
	if (size < 5)
		return 300;
	else if (size < 10)
		return 200;
	else
		return 50;
}
//获得蛇的长度
int Snake::countList() {
	int size = 0;
	Point* p = head;
	while (p) {
		p = p->next;
		++size;
	}
	return size-3;
}
//分数记录
int Snake::getScore() {
	return countList()*100;
}

--------------------------------------------------------
--------------------------------------------------------
/*主函数*/
//game.cpp
//案例:贪吃蛇
#include<iostream>
#include<Windows.h>
#include<conio.h>

#include"Wall.h"
#include"Snake.h"
#include"Food.h"
using namespace std;

//定位光标
void gotoxy0(HANDLE hOut0, int x, int y) {
	COORD pos;
	pos.X = x;//横坐标
	pos.Y = y;//纵坐标
	SetConsoleCursorPosition(hOut0, pos);
}
HANDLE hOut0 = GetStdHandle(STD_OUTPUT_HANDLE);//定显示器的句柄变量

//寻找非法值
bool find(char x,char per_x) {//用于判断是否为有效输入
	if (x == Snake::up) {
		if (Snake::down == per_x)
			return false;
		else
			return true;
	}
	else if (x == Snake::down) {
		if (Snake::up == per_x)
			return false;
		else
			return true;
	}
	else if (x == Snake::right) {
		if (Snake::left == per_x)
			return false;
		else
			return true;
	}
	else if(x == Snake::left) {
		if (Snake::right == per_x)
			return false;
		else
			return true;
	}
	else
		return false;
}

int main() {
	//墙
	Wall A;
	A.initWall();
	Snake S(A);
	//初始化(蛇)
	S.initSanke();
	//食物
	Food F(A);
	F.initFood();//放置食物
	//死亡标识
	bool islive = true;
	gotoxy0(hOut0, 0, 0);
	A.print();//墙
	char x = NULL;
	char per_x = NULL;
	//A.print();//画
	while (true) {//等待有效输出
		x = _getch();
		if (x == Snake::up || x == Snake::down || x == Snake::right) {
			islive = S.move(x);
			per_x = x;
			break;
		}
	}
	while (islive) {
		gotoxy0(hOut0, 0, 30);
		cout << "得分:"<<S.getScore()<<endl;
		//system("cls");//没效果
		Sleep(S.getSleepTime());
	//	islive=move(x);

		
		//是否有输入
		if (_kbhit()) {
			//移动(蛇)
			x = _getch();
			//寻找非法值
			if (find(x,per_x)) {//判断是否为有效输入
				islive = S.move(x);
				per_x = x;
			}
			else {
				islive = S.move(per_x);
				x = per_x;
				continue;
			}
		}
		else {
			islive = S.move(x);
		}
		
	}

	cout << "完成!" << endl;
	getchar();
	getchar();
	return 0;
}
---------------------------------------------------------------
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值