零基础用c++实现诺基亚上的贪吃蛇,我惊呼爷青回!
Posted CodeBowl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零基础用c++实现诺基亚上的贪吃蛇,我惊呼爷青回!相关的知识,希望对你有一定的参考价值。
今天是六一儿童节,奖励了自己一瓶旺仔牛奶,觉得还是意犹未尽,作为六岁零170个月的小孩子,我翻出了大一写的贪吃蛇小游戏,玩起来虽然粗糙,但是惊呼“爷青回”啊,让我回到了小板砖一样诺基亚上的贪吃蛇时代。
六一儿童节,建议大家收藏找回童年嗷,哈哈哈,喜欢作者的希望一键三连点个关注。在文章最后附有完整代码。
本文实现的是一个基于控制台的贪吃蛇小游戏,当时还不会界面这些操作,但是就是因为这样才有童年那味!
界面展示
初始界面中有一些游戏提示信息,还有贪吃蛇和食物的初始位置,以及四周的边框。
#标识我们的贪吃小蛇,*表示食物,●表示边框。
游戏结束图:
设计思路
设计一个蛇的类,如图所示:
绘制边框等操作
具体实现可看下面源码
class snake;
void Init_Console();//控制台初始化
void gotoPos(SHORT x = 0, SHORT y = 0);//光标坐标控制
void Init_Map();//画边框
void KeyConctrl(snake &, int);//键盘控制函数
void is_gameover();//结束提示
void Prompt_info(int, int);//提示信息
void dis_date(int, int, double, int);//得分信息
如何表现位置
蛇身和食物的位置都是使用的COORD结构。
COORD是WindowsAPI中定义的一种结构,表示一个字符在控制台屏幕上的坐标。
typedef struct _COORD {
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate } COORD;
如何表现蛇身
使用“#”表示蛇身,每吃一个食物就变长一个“#”。
如何表现食物
使用“*”表现食物,每吃掉一个食物,下一个食物就会随机出现在地图里。
如何移动
用"#"表示贪吃蛇,每次移动从蛇头开始,所以蛇不能反向移动,也就是不能倒车。每次输入方向键后,蛇头就会朝着方向移动,然后蛇身在该点也改变自身的方向。
方向分为停止、左、右、上、下。
enum direction { go_stop = 0, go_left, go_right, go_up, go_down }dir;
每一次移动,都要进行碰撞检测,检测是否发生了碰撞。
// //移动
bool move()
{
switch (this->dir)
{
case go_stop:
break;
case go_left:
in_Pos.X -= 2;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_right:
in_Pos.X += 2;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_up:
in_Pos.Y--;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_down:
in_Pos.Y++;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
}
return false;
}
};
检验碰撞
检验膨胀边框比较简单,就是测试蛇头的坐标有没有超过边框的范围。
//撞蛇 撞边检测
bool check_snk(COORD snk_Pos)
{
//边界检测
if (snk_Pos.Y <= 1 || (snk_Pos.Y >= 23) || (snk_Pos.X <= 1) || snk_Pos.X >= 45)
{
return true;
}
for (int i = clear_bit; i <= print_bit; i++)
{
if (_Pos[i].X == snk_Pos.X && _Pos[i].Y == snk_Pos.Y) return true;
}
return false;
}
速度升级
每当贪吃蛇吃掉五个食物,得到500分之后,速度就会+1,速度最高设置为5。
void up_speed()
{
if (this->speed < 5)(this->speed)++;
}
源代码
#include <iomanip>
#include <windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//全局句柄
class snake;
void Init_Console();//控制台初始化
void gotoPos(SHORT x = 0, SHORT y = 0);//光标坐标控制
void Init_Map();//画边框
void KeyConctrl(snake &, int);//键盘控制函数
void is_gameover();//结束提示
void Prompt_info(int, int);//提示信息
void dis_date(int, int, double, int);//得分信息
bool gameOver = false;
bool withdraw = false;
class snake
{
private:
bool flash;
int speed, length, print_bit, clear_bit;
COORD in_Pos, bit_Pos;
COORD _Pos[255];
enum direction { go_stop = 0, go_left, go_right, go_up, go_down }dir;
public:
snake(SHORT x = 9, SHORT y = 5)
{
clear_bit = print_bit = length = speed = 0;
in_Pos.X = x; in_Pos.Y = y; bit_Pos.X = 11; bit_Pos.Y = 8;
flash = true;
dir = go_stop;
_Pos[0].X = in_Pos.X;
_Pos[0].Y = in_Pos.Y;
}
~snake() {}
void up_speed()
{
if (this->speed < 5)(this->speed)++;
}
double get_speed()
{
return this->speed;
}
int get_length()
{
return this->length;
}
//
void dir_control(char _dir)
{
switch (_dir)
{
case 's': this->dir = go_stop;
break;
case 'l': if (this->dir != go_right)this->dir = go_left;
break;
case 'r': if (this->dir != go_left)this->dir = go_right;
break;
case 'u': if (this->dir != go_down)this->dir = go_up;
break;
case 'd': if (this->dir != go_up)this->dir = go_down;
break;
}
}
//光标位置
void setPos(COORD pos)
{
SetConsoleCursorPosition(hOut, pos);
}
//碰撞检测
void check_bit()
{
if (in_Pos.X == bit_Pos.X && in_Pos.Y == bit_Pos.Y)
{
length++;
if ((length % 5 == 0))
{
if (this->speed < 5)this->speed++;
}
if (length == 254)
{
cout << "游戏通关!";
}
do
{
srand(time(NULL));
bit_Pos.X = 3 + (rand() % 20) * 2;
bit_Pos.Y = 2 + rand() % 20;
} while (check_snk(bit_Pos));
}
else
{
cle();
clear_bit++;
}
}
//撞蛇 撞边检测
bool check_snk(COORD snk_Pos)
{
//边界检测
if (snk_Pos.Y <= 1 || (snk_Pos.Y >= 23) || (snk_Pos.X <= 1) || snk_Pos.X >= 45)
{
return true;
}
for (int i = clear_bit; i <= print_bit; i++)
{
if (_Pos[i].X == snk_Pos.X && _Pos[i].Y == snk_Pos.Y) return true;
}
return false;
}
//显示
void dis()
{
if (!flash)
{
setPos(bit_Pos);
SetConsoleTextAttribute(hOut, 0x0e);
cout << " ";
flash = true;
}
else
{
setPos(bit_Pos);
SetConsoleTextAttribute(hOut, 0x0e);
cout << "*";
flash = false;
}
setPos(in_Pos);
SetConsoleTextAttribute(hOut, 0x09);
cout << "#";
}
void cle()
{
setPos(_Pos[clear_bit]);
SetConsoleTextAttribute(hOut, 0x05);
cout << " ";
}
void save_date()
{
if (print_bit == 254)
{
for (int i = 0; i <= length; i++)
{
_Pos[i].X = _Pos[clear_bit + i].X;
_Pos[i].Y = _Pos[clear_bit + i].Y;
}
clear_bit = 0;
print_bit = length;
}
print_bit++;
_Pos[print_bit].X = in_Pos.X;
_Pos[print_bit].Y = in_Pos.Y;
}
// //移动
bool move()
{
switch (this->dir)
{
case go_stop:
break;
case go_left:
in_Pos.X -= 2;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_right:
in_Pos.X += 2;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_up:
in_Pos.Y--;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
case go_down:
in_Pos.Y++;
if (check_snk(in_Pos))
{
return true;
}
dis();
save_date();
check_bit();
break;
}
return false;
}
};
int main()
{
do
{
Init_Console();
Init_Map();
Prompt_info(3, 3);
snake s(27, 11);
clock_t t_in, t_out;
t_in = clock();
s.dis();
//
while (!gameOver)
{
if (_kbhit())
{
KeyConctrl(s, _getch());
}
t_out = clock();
dis_date(3, 5, s.get_speed(), s.get_length());
if (t_out - t_in > ((0.25 - (s.get_speed() / 25)) * CLOCKS_PER_SEC))
{
t_in = t_out;
gameOver = s.move();
if (gameOver)
{
is_gameover();
}
}
Sleep(10);
}
//
while (gameOver)
{
if (_kbhit())
{
switch (_getch())
{
case 'y':
case 'Y':
gameOver = false;
system("cls");
break;
case 'n':
case 'N':
gameOver = false;
withdraw = true;
break;
}
}
Sleep(10);
}
} while (!withdraw);
gotoPos(15, 13);
return 0;
}
//控制台初始化
void Init_Console()
{
SetConsoleTitleA("Console_贪吃蛇");
COORD dSiz = { 80, 25 };
SetConsoleScreenBufferSize(hOut, dSiz);//设置窗口缓冲区大小
CONSOLE_CURSOR_INFO _guan_biao = { 1, FALSE };//设置光标大小,隐藏光标
SetConsoleCursorInfo(hOut, &_guan_biao);
system("color 0f");//设置画布颜色
}
//光标位置
void gotoPos(SHORT x, SHORT y)
{
COORD pos = { x, y };
SetConsoleCursorPosition(hOut, pos);
}
//画边框
void Init_Map()
{
//SetConsoleTextAttribute(hOut, 0xF0); //设置前景色,背景色
system("cls");
//左边框
for (int i = 0; i < 23; i++)
{
cout << endl << " ●";
}
//上边框
gotoPos(3, 1);
for (int i = 0; i < 21; i++)
{
cout << "●";
}
//下边框
gotoPos(3以上是关于零基础用c++实现诺基亚上的贪吃蛇,我惊呼爷青回!的主要内容,如果未能解决你的问题,请参考以下文章