贪吃蛇游戏分析

Windows、VS2017

链接:点这里 密码:n5nc

C++基础学习完后的小项目课程。


首先在cmd这个黑框框下绘制图像还是一样,定位,设置颜色,输出形状。我们要有一个工具类,来帮助我们定位,设置颜色(前景色&后景色),隐藏光标,设置标题等……在我们后面要重复利用到这里的工具函数,可以省一些事情。

Tools.h 

//Tools.h
#pragma once
#include <iostream>
#include <Windows.h>
using namespace std;
void set_windows_size(int x, int y);
void hide_cursor();
void set_cursor_position(const int x, const int y);
void set_text_color(int color_id);
void set_background_color();

 Tools.cpp

#include "stdafx.h"
#include "Tools.h"

//设置窗口
void set_windows_size(int x, int y)
{
	system("title GAME");	//设置窗口标题
	char cmd[30];	//存储cmd命令
	sprintf_s(cmd, "mode con cols=%d lines=%d", x * 2, y);//拼接命令//x*2是因为在cmd中字符是长的,一个字符的高=2*宽
	system(cmd);
}

//隐藏光标
void hide_cursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

//设置光标坐标
void set_cursor_position(const int x, const int y)
{
	COORD position;
	position.X = x * 2;
	position.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}

//设置文本颜色
void set_text_color(int color_id)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_id);
}

//设置背景颜色、前景色
void set_background_color() 
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 
		FOREGROUND_BLUE|
		BACKGROUND_BLUE|
		BACKGROUND_GREEN|
		BACKGROUND_RED
	);
}

 


下来咋弄呢?我们要绘制地图,当然需要绘制点、方框什么的了,那在这个游戏里,点是一个二维点,我们创建一个Point的类,需要x,y两个成员变量,这个类可以根据xy绘制出正方形和圆形(还可以加别的形状)。在后面我们用方块来表示地图,开始界面动画,食物等。圆形用来表示蛇。

Point.h

#pragma once
class Point
{
public:
	Point():m_x(0),m_y(0){}
	Point(const int x,const int y):m_x(x),m_y(y){}
	void print_rect();	//输出方框 ■
	void print_circular();	//输出圆 ●

	void clear();
	void move(const int x,const int y);

	bool operator ==(const Point& point)
	{
		return (point.m_x == m_x) && (point.m_y == m_y);
	}
	int get_x()
	{
		return m_x;
	}
	int get_y()
	{
		return m_y;
	}
	
private:
	int m_x, m_y;
};

Point.cpp

#include "stdafx.h"
#include "Point.h"
#include "Tools.h"


void Point::print_rect()
{
	set_cursor_position(m_x, m_y);
	cout << "■";
}

void Point::print_circular()
{
	set_cursor_position(m_x, m_y);
	cout << "●";
}

void Point::clear()
{
	set_cursor_position(m_x, m_y);
	cout << " ";
}

void Point::move(const int x, const int y)
{
	m_x = x;
	m_y = y;
}

贪吃蛇……我们要有蛇和食物吧,下来我们来看这两个。蛇用链表弄,用到<list>。

Foods.h

#pragma once
#include "Point.h"
#include "Snake.h"
class Snake;
class Foods
{
	friend class Snake;
public:
	Foods():m_cnt(0), 
		m_x(0), m_y(0), 
		m_big_foods_x(0), m_big_foods_y(0), 
		m_bar(0),
		m_flash(false), 
		m_big_flag(false)
	{}
	
	void draw_foods(Snake& snake);
	void draw_big_foods(Snake& snake);
	void big_foods_flash();
	bool get_big_flag();
	int change_bar();
private:
	int m_cnt;
	int m_x, m_y;	//标准食物
	int m_big_foods_x, m_big_foods_y;	//限时食物坐标
	int m_bar;	//限时食物进度条
	bool m_flash;	//限时食物闪烁标记
	bool m_big_flag;	//限时食物消失

};

Foods.cpp

#include "stdafx.h"
#include "Foods.h"
#include <stdlib.h>
#include "Tools.h"
#include "Snake.h"
void Foods::draw_foods(Snake& snake)
{
	//随机生成坐标,范围2~29,每5个正常食物后出现一个限时食物
	while (true)
	{
		int tmp_x = rand() % 30;
		int tmp_y = rand() % 30;
		if (tmp_x < 2)
			tmp_x += 2;
		if (tmp_y < 2)
			tmp_y += 2;
		bool flag = false;
		for (auto& point : snake.list_snake)
		{
			if ((point.get_x() == tmp_x) && (point.get_y() == tmp_y) ||
				tmp_x == m_big_foods_x && tmp_y == m_big_foods_y)
			{
				flag = true;
				break;
			}
		}
		if (flag)
			continue;

		m_x = tmp_x;
		m_y = tmp_y;
		set_cursor_position(m_x, m_y);
		set_text_color(13);
		cout << "■";
		++m_cnt;
		if (!(m_cnt % 5))
		{
			draw_big_foods(snake);
		}
		break;
	}
}

void Foods::draw_big_foods(Snake & snake)
{
	set_cursor_position(5, 0);
	set_text_color(11);
	cout << "------------------------------------------";	//进度条
	m_bar = 42;
	while (true)
	{
		int tmp_x = rand() % 30;
		int tmp_y = rand() % 30;
		if (tmp_x < 2)
			tmp_x += 2;
		if (tmp_y < 2)
			tmp_y += 2;

		for (auto& point : snake.list_snake)
		{
			if ((point.get_x() == tmp_x) && (point.get_y() == tmp_y) ||
				tmp_x == m_x && tmp_y == m_y)
			{
				continue;
			}
		}

		m_big_foods_x = tmp_x;
		m_big_foods_y = tmp_y;
		set_cursor_position(m_big_foods_x, m_big_foods_y);
		set_text_color(13);
		cout << "■";
		m_flash = true;
		m_big_flag = true;
		break;
	}
}

void Foods::big_foods_flash()
{
	set_cursor_position(m_big_foods_x, m_big_foods_y);
	set_text_color(18);
	if (m_flash)
	{
		cout << " ";
		m_flash = false;
	}
	else
	{
		cout << "■";
		m_flash = true;
	}
	set_cursor_position(26, 0);
	set_text_color(11);
	for (int i = 42; i >= m_bar; --i)
	{
		cout << "\b \b";
	}
	--m_bar;
	if (0 == m_bar)
	{
		set_cursor_position(m_big_foods_x, m_big_foods_y);
		cout << " ";
		m_big_flag = false;
		m_big_foods_x = 0;
		m_big_foods_y = 0;
	}
}

bool Foods::get_big_flag()
{
	return m_big_flag;
}

Snake.h

#pragma once
#include <list>
#include "Point.h"
using namespace std;

class Foods;

class Snake
{
	friend class Foods;
public:
	enum Direction{UP,DOWN,LEFT,RIGHT};
	Snake() 
	{
		list_snake.emplace_back(14, 8);
		list_snake.emplace_back(18, 8);
		list_snake.emplace_back(16, 8);
		direction = DOWN;
	}

	void print_init_snake();	//打印开始时的蛇
	void snake_move();	//蛇移动
	void snake_add();
	bool over_edge();	//撞墙
	bool eat_self();	//撞自己
	bool change_direction();//改变方向
	bool eat_foods(const Foods&);//吃食物
	bool eat_time_limit_foods(Foods&);//吃限时食物
private:
	list<Point>list_snake;	//蛇
	Direction direction;	//当前朝向
};

Snake.cpp

#include "stdafx.h"
#include "Snake.h"
#include "Tools.h"
#include "Foods.h"
#include <conio.h>

void Snake::print_init_snake()
{
	for (auto&point : list_snake)
		point.print_circular();
}

void Snake::snake_move()
{
	snake_add();	//蛇头+1
	// 去掉蛇尾 -1
	list_snake.front().clear();
	list_snake.pop_front();
}

void Snake::snake_add()
{
	switch (direction)
	{
	case UP:
		list_snake.emplace_back(Point(list_snake.back().get_x(), list_snake.back().get_y() - 1));
		break;
	case DOWN:
		list_snake.emplace_back(Point(list_snake.back().get_x(), list_snake.back().get_y() + 1));
		break;
	case LEFT:
		list_snake.emplace_back(Point(list_snake.back().get_x() - 1, list_snake.back().get_y()));
		break;
	case RIGHT:
		list_snake.emplace_back(Point(list_snake.back().get_x() + 1, list_snake.back().get_y()));
		break;
	}
	set_text_color(14);
	list_snake.back().print_circular();
}

bool Snake::over_edge()
{
	return !(list_snake.back().get_x() < 30 && list_snake.back().get_y() < 30
		&& list_snake.back().get_x() > 1 && list_snake.back().get_y() > 1);
}

bool Snake::eat_self()
{
	size_t count = 1;
	Point* head = new Point(list_snake.back().get_x(), list_snake.back().get_y());
	for (auto& point : list_snake)
	{
		if (!(point == *head))
		{
			count++;
		}
		else
			break;
		//delete head;
	}
	if (count == list_snake.size())
	{
		return false;
	}
	return true;
	
}

bool Snake::change_direction()
{
	char ch;
	if (_kbhit())	//_kbhit() 非阻塞函数
	{
		ch = _getch();
		switch (ch)
		{
		case -32:
			ch = _getch();
			switch (ch)
			{
			case 72:
				if (direction != DOWN)
					direction = UP;
				break;
			case 80:
				if (direction != UP)
					direction = DOWN;
				break;
			case 75:
				if (direction != RIGHT)
					direction = LEFT;
				break;
			case 77:
				if (direction != LEFT)
					direction = RIGHT;
				break;
			}
			return true;
		case 27:	//ESC
			return false;
		default:
			return true;
		}
	}
	return false;
}

bool Snake::eat_foods(const Foods& foods)
{
	if (list_snake.back().get_x() == foods.m_x&&list_snake.back().get_y() == foods.m_y)
	{
		return true;
	}
	return false;
}

bool Snake::eat_time_limit_foods(Foods & foods)
{
	if (list_snake.back().get_x() == foods.m_big_foods_x&&list_snake.back().get_y() == foods.m_big_foods_y)
	{
		foods.m_big_flag = false;
		foods.m_big_foods_x = 0;
		foods.m_big_foods_y = 0;
		set_cursor_position(1, 0);
		//cout << "------------------------------------------";	//进度条
		cout << "                                           ";
		return true;
	}
	return false;
}

蛇和食物都准备完了,下来就是给个地图让他吃咯。

Map.h

#pragma once
#include <vector>
#include "Point.h"
using namespace std;
class Map
{
public:
	Map() 
	{
		for (int i = 1; i <= 30; i++)
		{
			vec_map.emplace_back(Point(i, 1));
			vec_map.emplace_back(Point(1, i));
			vec_map.emplace_back(Point(30, i));
			vec_map.emplace_back(Point(i, 30));
		}
	}
	void print_map();	//绘制初始地图 方框
private:
	vector<Point>vec_map;
};

Map.cpp 

#include "stdafx.h"
#include "Map.h"
#include <Windows.h>
void Map::print_map()
{
	for (auto& point : vec_map)
	{
		point.print_rect();
		Sleep(2);
	}
}

玩游戏,我们需要一个能控制游戏是否继续或者退出,选择难度之类的东西来控制(就是调用函数,循环之类的)

Controller.h

#pragma once
class Controller
{
public:
	Controller() : leval(1), score(0), speed(20) {};
	~Controller();
	void snake_game();	//开始游戏
	void game_start();	//开始界面
	void select_leval();//选择难度
	void draw_map();	//画地图
	int play_game();	//玩游戏
	void update_score();//计分
	void pause_menu();	//游戏暂停菜单
	int game_over();	//die
private:
	int leval;	//难度
	int score;	//成绩
	int speed;	//速度
};

Controller.cpp

#include "stdafx.h"
#include <iostream>
#include "Controller.h"
#include "Tools.h"
#include <conio.h>
#include <Windows.h>
#include "Animation.h"
#include "Map.h"
#include "Snake.h"
#include "Foods.h"
#include <time.h>
using namespace std;
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")


void Controller::snake_game()
{
	PlaySound(TEXT(".//1.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
	game_start();
	
	//游戏循环,直到推出
	while (true)
	{
		select_leval();
		draw_map();
		if (play_game())
		{
			system("cls");
			continue;
		}
		break;
		game_over();
	}
}

void Controller::game_start()
{
	//蛇动画	文字动画		下方提示文字出现
	set_windows_size(41, 32);	//设置窗口大小
	set_text_color(2);		//设置文字颜色 绿色
	hide_cursor();	//隐藏光标

	Animation* act = new Animation;
	act->Action();
	delete act;
	

	// 设置提示文字
	//set_cursor_position(13, 26);
	//cout << "按下任意键,开始游戏!";
	//set_cursor_position(13, 27);
	//cout << "press any key to start!";
	//system("pause");
}

void Controller::select_leval()
{
	//TODO:上下选择难度	选中的变色	记录难度更改速度
	//上下选择难度	选中的变色
	set_text_color(3);
	set_cursor_position(13, 26);
	cout << "                          ";
	set_cursor_position(13, 27);
	cout << "                          ";
	set_cursor_position(10, 21);
	cout << " ";
	set_cursor_position(10, 22);
	cout << "选择游戏难度:";
	set_cursor_position(10, 23);
	cout << " ";
	set_cursor_position(27, 22);
	set_background_color();	//第一个选项设置背景颜色表示已经选择
	cout << "简单";
	set_cursor_position(27, 24);
	set_text_color(3);
	cout << "普通";
	set_cursor_position(27, 26);
	cout << "困难";
	set_cursor_position(27, 28);
	cout << "炼狱";
	set_cursor_position(0, 31);

	score = 0;	//成绩清 0
	leval = 1;	//难度复位
	// 上下选择难度
	int ch;	//记录上下键盘值
	bool flag = false;	//记录是否按下enter
	while (ch = _getch())	//获取单个字符,并且不会显示
	{
		switch (ch)
		{
		case 72:	// 72是上方向键
			if (leval > 1)
			{
				switch (leval)
				{
				case 2:
					set_cursor_position(27, 24);
					set_text_color(3);
					cout << "普通";

					set_cursor_position(27, 22);
					set_background_color();
					cout << "简单";
					--leval;
					break;
				case 3:
					set_cursor_position(27, 26);
					set_text_color(3);
					cout << "困难";

					set_cursor_position(27, 24);
					set_background_color();
					cout << "普通";
					--leval;
					break;
				case 4:
					set_cursor_position(27, 28);
					set_text_color(3);
					cout << "炼狱";

					set_cursor_position(27, 26);
					set_background_color();
					cout << "困难";
					--leval;
					break;
				}
			}
			break;
		case 80:	// 下
			if (leval < 4)
			{
				switch (leval)
				{
				case 1:
					set_cursor_position(27, 22);
					set_text_color(3);
					cout << "简单";

					set_cursor_position(27, 24);
					set_background_color();
					cout << "普通";
					++leval;
					break;
				case 2:
					set_cursor_position(27, 24);
					set_text_color(3);
					cout << "普通";

					set_cursor_position(27, 26);
					set_background_color();
					cout << "困难";
					++leval;
					break;
				case 3:
					set_cursor_position(27, 26);
					set_text_color(3);
					cout << "困难";

					set_cursor_position(27, 28);
					set_background_color();
					cout << "炼狱";
					++leval;
					break;
				}
			}
			break;
		case 13:
			flag = true;
			break;	//enter
		default:
			break;
		}
		// 判断是否按下回车
		if (flag)
			break;
	}

	// 记录难度,更改速度
	switch (leval)	//根据难度修改速度
	{
	case 1:
		speed = 135;
		break;
	case 2:
		speed = 100;
		break;
	case 3:
		speed = 60;
		break;
	case 4:
		speed = 10;
		break;
	}
}

void Controller::draw_map()
{
	system("cls");
	//清屏cls	绘制游戏地图		绘制记侧边分栏
	// 绘制地图,边框
	set_text_color(3);

	Map* init_map = new Map;
	init_map->print_map();
	delete init_map;

	//绘制侧边记分栏
	set_text_color(3);
	set_cursor_position(33, 1);
	cout << "Game";
	set_cursor_position(34, 2);
	cout << "贪吃蛇";
	set_cursor_position(31, 4);
	cout << "难度:";
	set_cursor_position(36, 5);
	switch (leval)
	{
	case 1:
		cout << "简单模式";
		break;
	case 2:
		cout << "普通模式";
		break;
	case 3:
		cout << "困难模式";
		break;
	case 4:
		cout << "炼狱模式";
		break;
	}
	set_cursor_position(31, 7);
	cout << "得分:";
	set_cursor_position(37, 8);
	cout << "     0";
	set_cursor_position(33, 13);
	cout << "方向键移动";
	set_cursor_position(33, 15);
	cout << "ESC暂停";
}

int Controller::play_game()
{
	//初始化蛇、食物		循环接收键盘信息		蛇死亡
	Snake* psnake = new Snake;
	Foods* pfoods = new Foods;
	set_text_color(6);
	psnake->print_init_snake();
	srand(time(0));	//设置随机数种子
	pfoods->draw_foods(*psnake);

	while ((!(psnake->over_edge())) && (!(psnake->eat_self())))//判断是否撞墙或者撞到自己
	{
		if (!psnake->change_direction())	//ESC按下
		{
			pause_menu();
		}


		if (psnake->eat_foods(*pfoods))
		{
			psnake->snake_add();
			update_score();
			pfoods->draw_foods(*psnake);
		}
		else
		{
			psnake->snake_move();
		}
		if (psnake->eat_time_limit_foods(*pfoods))
		{
			psnake->snake_add();
			update_score();
		}
		if (pfoods->get_big_flag())
		{
			pfoods->big_foods_flash();
		}
		Sleep(speed);
	}
	// die snake
	delete psnake;
	delete pfoods;
	
	return game_over();

	return false;
}

void Controller::update_score()
{
	//更新成绩
	score += leval * 5;
	set_cursor_position(37, 8);
	set_text_color(11);
	// TODO:限时食物分数
	
	cout << score;
}

void Controller::pause_menu()
{
	// 绘制暂停菜单	  选择(继续?从新开始?退出?)
	set_text_color(11);
	set_cursor_position(32, 19);
	cout << "菜单:";

	Sleep(100);
	set_cursor_position(32, 21);
	cout << "继续游戏";
	Sleep(100);
	set_cursor_position(32, 23);
	cout << "重新开始";
	Sleep(100);
	set_cursor_position(32, 25);
	cout << "退出游戏";
	//TODO:选择之后操作
}

int Controller::game_over()
{
	//TODO:结束
	// 绘制游戏界面
	Sleep(200);
	set_text_color(11);
	set_cursor_position(10, 8);
	cout << "——————————————————";

	Sleep(20);
	set_cursor_position(9, 9);
	cout << " |            game over!!!             |";

	Sleep(20);
	set_cursor_position(9, 10);
	cout << " |                                     |";
	set_cursor_position(9, 11);
	cout << " |             you die!!!              |";
	set_cursor_position(9, 12);
	cout << " |                                     |";

	Sleep(20);
	set_cursor_position(9, 13);
	cout << " |            你的分数:               |";
	set_cursor_position(24, 13);
	cout << score;

	Sleep(20);
	set_cursor_position(9, 14);
	cout << " |                                     |";
	set_cursor_position(9, 15);
	cout << " | 再来一局?                          |";
	set_cursor_position(9, 16);
	cout << " |                                     |";
	set_cursor_position(9, 17);
	cout << " |                                     |";

	Sleep(20);
	set_cursor_position(9, 18);
	cout << " |  嗯好。            拒绝。           |";
	set_cursor_position(9, 19);
	cout << " |                                     |";
	set_cursor_position(9, 20);
	cout << " |                                     |";
	set_cursor_position(10, 21);
	cout << "——————————————————";

	Sleep(20);
	set_cursor_position(12, 18);
	set_background_color();
	cout << "嗯好。";

	//TODO:左右选择效果
	char ch;
	int result = 1;
	bool flag = false;
	while ((ch=_getch()))
	{
		switch (ch)
		{
		case 75:
			if (result > 1)
			{
				set_cursor_position(11, 18);
				set_background_color();
				cout << "嗯好。";
				set_cursor_position(19, 18);
				cout << "拒绝。";
				--result;
			}
			break;
		case 77:
			if (result < 2)
			{
				set_cursor_position(12, 18);
				cout << "嗯好。";

				set_cursor_position(20, 18);
				set_background_color();
				cout << "拒绝。";
				++result;
			}
			break;
		case 13://enter
			flag = true;
			break;
		default:
			break;
		}

		if (flag)
		{
			break;
		}

		set_text_color(11);
		return result;
	}
	//return 1;
}

做一点开始动画~~~

Animation.h

#pragma once
#include <deque>	//双端队列
#include <vector>
#include "Point.h"
using namespace std;
class Animation
{
public:
	Animation() :speed(60) 
	{
		//蛇
		deq_start_snake.emplace_back(Point(0, 14));
		deq_start_snake.emplace_back(Point(1, 14));
		deq_start_snake.emplace_back(Point(2, 15));
		deq_start_snake.emplace_back(Point(3, 16));
		deq_start_snake.emplace_back(Point(4, 17));
		deq_start_snake.emplace_back(Point(5, 18));
		deq_start_snake.emplace_back(Point(6, 17));
		deq_start_snake.emplace_back(Point(7, 16));
		deq_start_snake.emplace_back(Point(8, 15));
		deq_start_snake.emplace_back(Point(9, 14));

		vec_start_text.emplace_back(Point(-26, 14));//S
		vec_start_text.emplace_back(Point(-25, 14));
		vec_start_text.emplace_back(Point(-27, 15));
		vec_start_text.emplace_back(Point(-26, 16));
		vec_start_text.emplace_back(Point(-25, 17));
		vec_start_text.emplace_back(Point(-27, 18));
		vec_start_text.emplace_back(Point(-26, 18));

		vec_start_text.emplace_back(Point(-23, 14));//N
		vec_start_text.emplace_back(Point(-23, 15));
		vec_start_text.emplace_back(Point(-23, 16));
		vec_start_text.emplace_back(Point(-23, 17));
		vec_start_text.emplace_back(Point(-23, 18));
		vec_start_text.emplace_back(Point(-22, 15));
		vec_start_text.emplace_back(Point(-21, 16));
		vec_start_text.emplace_back(Point(-20, 17));
		vec_start_text.emplace_back(Point(-19, 14));
		vec_start_text.emplace_back(Point(-19, 15));
		vec_start_text.emplace_back(Point(-19, 16));
		vec_start_text.emplace_back(Point(-19, 17));
		vec_start_text.emplace_back(Point(-19, 18));

		vec_start_text.emplace_back(Point(-17, 18));//A
		vec_start_text.emplace_back(Point(-16, 17));
		vec_start_text.emplace_back(Point(-15, 16));
		vec_start_text.emplace_back(Point(-14, 15));
		vec_start_text.emplace_back(Point(-14, 16));
		vec_start_text.emplace_back(Point(-13, 14));
		vec_start_text.emplace_back(Point(-13, 16));
		vec_start_text.emplace_back(Point(-12, 15));
		vec_start_text.emplace_back(Point(-12, 16));
		vec_start_text.emplace_back(Point(-11, 16));
		vec_start_text.emplace_back(Point(-10, 17));
		vec_start_text.emplace_back(Point(-9, 18));

		vec_start_text.emplace_back(Point(-7, 14));//K
		vec_start_text.emplace_back(Point(-7, 15));
		vec_start_text.emplace_back(Point(-7, 16));
		vec_start_text.emplace_back(Point(-7, 17));
		vec_start_text.emplace_back(Point(-7, 18));
		vec_start_text.emplace_back(Point(-6, 16));
		vec_start_text.emplace_back(Point(-5, 15));
		vec_start_text.emplace_back(Point(-5, 17));
		vec_start_text.emplace_back(Point(-4, 14));
		vec_start_text.emplace_back(Point(-4, 18));

		vec_start_text.emplace_back(Point(-2, 14));//E
		vec_start_text.emplace_back(Point(-2, 15));
		vec_start_text.emplace_back(Point(-2, 16));
		vec_start_text.emplace_back(Point(-2, 17));
		vec_start_text.emplace_back(Point(-2, 18));
		vec_start_text.emplace_back(Point(-1, 14));
		vec_start_text.emplace_back(Point(-1, 16));
		vec_start_text.emplace_back(Point(-1, 18));
		vec_start_text.emplace_back(Point(0, 14));
		vec_start_text.emplace_back(Point(0, 16));
		vec_start_text.emplace_back(Point(0, 18));
	}
	
	void print_text();
	void clear_text();
	void Action();
private:
	//开始动画中的蛇
	deque<Point> deq_start_snake;
	//开始动画中的字
	vector<Point> vec_start_text;

	int speed;	//动画速度

};

Animation.cpp

#include "stdafx.h"
#include "Animation.h"
#include <Windows.h>

void Animation::print_text()
{
	for (auto& point : vec_start_text)
	{
		if (point.get_x() >= 0)
			point.print_rect();
	}
}

void Animation::clear_text()
{
	for (auto& point : vec_start_text)
	{
		if (point.get_x() >= 0)
			point.clear();
		point.move(point.get_x() + 1, point.get_y());
	}
}

void Animation::Action()
{
	//蛇头从左到完全出现的过程
	for (auto& point : deq_start_snake)
	{
		point.print_rect();
		Sleep(speed);
	}

	//蛇头从左往右移动
	for (int i = 10; i != 40; ++i)
	{
		int j = (((i - 2) % 8) < 4) ? (15 + (i - 2) % 8) : (21 - (i - 2) % 8);
		deq_start_snake.emplace_back(Point(i, j));
		deq_start_snake.back().print_rect();

		deq_start_snake.front().clear();
		deq_start_snake.pop_front();
		Sleep(speed);
	}

	//当蛇还没有消失或者文字还没有移动到指定位置时
	while (!deq_start_snake.empty() || vec_start_text.back().get_x()<33)
	{
		if (!deq_start_snake.empty())
		{
			deq_start_snake.front().clear();
			deq_start_snake.pop_front();
			Sleep(speed);
		}
		clear_text();//清除已有文字
		print_text();//打印更新位置的文字
	}
}

main~main~

// 贪吃蛇.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "Controller.h"

int main()
{
	
	Controller sgame;
	sgame.snake_game();


    return 0;
}

OK~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值