c++入门程序,带你实现一个贪吃蛇

软件环境:EasyX 20210115, visual studio2019

参考代码:https://codebus.cn/aknoi/snake

效果展示:

在这里插入图片描述在这里插入图片描述

当按下’s’键的时候会出现自己目前的得分。
展望:
由于只是一个简单的版本,所以还存在一些不足,下一步考虑使用链表而不是数组来作为存储结构;使用线程而不是延迟;使用mysql构建一个用户登录界面。

重点解释

存储位置的时候只是存储坐标点,但是当画的时候,显示的一个个矩形来表示蛇的一节节的身体。

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码结构:
主要由snake,food类构成,还有一个控制的main文件进行逻辑控制
代码:
snake.h

#ifndef SNAKE_H_
#define SNAKE_H_
#include<vector>
#include<graphics.h>
#include<conio.h>
#include"food.h"

using std::vector;

class snake
{
private:
	struct Point
	{
		int x;
		int y;
	};
	vector<Point> xy;	
	Point next;		
	vector<COLORREF> color;	
	int num;		
	int direction;	
	int grade;
	bool live;

public:
	static enum DIRECTION{UP, DOWN, LEFT, RIGHT};	
	snake();
	void draw();
	void move();
	void eat(food &f);
	void setDirection(DIRECTION dir) { direction = dir; }
	int getPosX() { return xy[0].x; }
	int getPosY() { return xy[0].y; }
	int getDirection() { return direction; }
	int getScore() { return grade; }
	~snake() {};
};

#endif

snake.cpp

#include"snake.h"

snake::snake()
{
	snake::Point pos;
	pos.x = 20;
	pos.y = 0;
	xy.push_back(pos);
	color.push_back(RGB(rand()%256, rand()%256, rand()%256));
	pos.x = 10;
	pos.y = 0;
	xy.push_back(pos);
	color.push_back(RGB(rand()%256, rand()%256, rand()%256));
	pos.x = 0;
	pos.y = 0;
	xy.push_back(pos);
	color.push_back(RGB(rand()%256, rand()%256, rand()%256));
	num = 3;
	direction = RIGHT;
	grade = 0;
	live = true;
}

void snake::draw()
{
	for(int i=0; i<num; i++)
	{
		setfillcolor(color[i]);
		fillrectangle(xy[i].x, xy[i].y, xy[i].x+10, xy[i].y+10);
	}
}
void snake::move()
{
	next = xy[num-1];
	for(int i=num-1; i>=1; i--)
	{
		xy[i] = xy[i-1];
	}
	switch(direction)
	{
		case RIGHT:
			xy[0].x += 10;
			break;
		case LEFT:
			xy[0].x -= 10;
			break;
		case UP:
			xy[0].y -= 10;
			break;
		case DOWN:
			xy[0].y += 10;
			break;
	}
}

void snake::eat(food &f)
{
	Point point;
	point.x = f.getPosX();
	point.y = f.getPosY();

	if (xy[0].x == point.x && xy[0].y == point.y)
	{
		vector<Point>::iterator Phead = xy.begin();
		vector<COLORREF>::iterator Chead = color.begin();
		xy.insert(Phead, point);
		color.insert(Chead, f.getColor());

		grade += f.getGrade();
		num++;
		f.refresh();
	}
}

food.h

#ifndef FOOD_H
#define FOOD_H
#include<graphics.h>
#include<cstdlib>

class food
{
private:
	struct Point
	{
		int x;
		int y;
	};
	Point pos;		
	int grade;		
	COLORREF color;
	static const int grades[3];
	static const COLORREF colors[3];

public:
	food();
	~food() {};

	void draw();
	int getPosX() { return pos.x; }
	int getPosY() { return pos.y; }
	COLORREF getColor() { return color; }
	int getGrade() { return grade; }
	void refresh();

};

#endif // !FOOD_H

food.cpp

#include"food.h"

//随机生成事物的时候需要使用的
const int food::grades[3] = { 100, 50, 10 };
const COLORREF food::colors[3] = { RED, GREEN, BLUE };

food::food()
{
	int colorNum = rand() % 3;
	color = colors[colorNum];
	grade = grades[colorNum];
	pos.x = rand() % 80 * 10;
	pos.y = rand() % 60 * 10;
}
void food::draw()
{
	setfillcolor(color);
	fillrectangle(pos.x, pos.y, pos.x + 10, pos.y + 10);
}

void food::refresh()
{
	int colorNum = rand() % 3;
	color = colors[colorNum];
	grade = grades[colorNum];
	pos.x = rand() % 80 * 10;
	pos.y = rand() % 60 * 10;
}

main.cpp

#include<graphics.h>
#include<ctime>
#include<conio.h>
#include<locale>
#include"snake.h"

bool checkLive(snake & s)
{
	if (s.getPosX() >= 800 || s.getPosX()<0 || s.getPosY() >= 600 || s.getPosY() < 0)
	{
		return false;
	}
	return true;
}

void showScore(snake &s)
{
	TCHAR text[100];
	wsprintf(text, _T("分数: %d"), s.getScore());
	settextcolor(BLACK);
	RECT rect = { 600, 0, 800, 100 };
	drawtext(text, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
}

bool keyDown(snake &s)
{
	char userKey = _getch();
	if(userKey == -32)
	{
		userKey = -_getch();
	}
	if (userKey == 's')
	{
		showScore(s);
		return false;
	}
	switch(userKey)
	{
		case 'w':
		case 'W':
		case -72:
			if (s.getDirection() != snake::DOWN)
				s.setDirection(snake::UP);
			else
				return false;
			break;
		case 's':
		case 'S':
		case -80:
			if (s.getDirection() != snake::UP)
				s.setDirection(snake::DOWN);
			else
				return false;
			break;
		case 'a':
		case 'A':
		case -75:
			if (s.getDirection() != snake::RIGHT)
				s.setDirection(snake::LEFT);
			else
				return false;
			break;
		case 'd':
		case 'D':
		case -77:
			if (s.getDirection() != snake::LEFT)
				s.setDirection(snake::RIGHT);
			else
				return false;
			break;
	}
	return true;
}






int main(void)
{
	setlocale(LC_ALL, ".936");
	initgraph(800, 600);
	setbkcolor(RGB(95, 183, 72));
	srand((unsigned)time(NULL));
	
	snake s;
	s.draw();
	food f;
	f.draw();

	while(true)
	{
		if(_kbhit())
		{
			if (keyDown(s))
			{
				s.move();
			}
		}
		s.draw();
		f.draw();
		Sleep(100);
		s.eat(f);
		s.move();
		if (!checkLive(s))
		{
			break;
		}
		clearrectangle(0, 0, 800, 600);
	}

	_getch();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

able陈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值