自己做的第一个游戏!!!
说说制作历程吧:
1.阅读并理解原作者(没有找到作者名)源码
2.仿写一边源码
3.经过一天的冥想(其实是玩了一天吃鸡)
4.然后不看源码,自己码出来,并且能正常运行,也就是下面的产物 (因为我不想这是强行记忆的产物)
在进行第一步的时候,我才看完了谭C,所以有很多头文件名都不知道有什么用。那时,我先查一遍,如果还是不懂,就看文中有什么函数没看过,例如:cout, time, kbhit() 其实印象最深的是 定位光标 ,这个用的好舒服啊!
看看哪天心血来潮,增加一些新玩法,比如说贪吃蛇互吃?
/************************************************/
/*本程序仅仅实现贪吃蛇最基本的功能,可供初学C/C++者参考*/
/************************************************/
//这条蛇能折返跑
# include <iostream>
# include <conio.h>
# include <time.h>
# include <cstdlib>
# include <windows.h>
using namespace std;
struct Snake
{
int x, y;
struct Snake * pNext;
};
void gotoXY(short x, short y); //定位光标,指哪画哪
void Draw_Map(void); //画地图
void Initialize_Snake(void); //初始蛇身
void Draw_Snake(void); //画蛇(给光标加*)
void Move_Snake(void); //移动蛇
void Del_Snake(void); //删除蛇尾
void Control_Snake(void); //控制蛇
void Draw_Food(void); //生成食物
const int wall_x = 50; //横边界
const int wall_y = 25; //竖边界
struct Snake * head = new Snake;
struct Snake * body1 = new Snake;
struct Snake * body2 = new Snake;
int direction = 4; //确保用户不输入,蛇也能运动
int Food = 0, Food_x = 10, Food_y = 10; //定义全局变量,函数内部修改也行,免去在主函数过量使用指针的麻烦。最好先初始化变量,上面我没有先初始化,用Initialize_Snake赋值了
int count = 0;
int main(void)
{
Draw_Map();
Initialize_Snake();
Draw_Snake();
Draw_Food(); //引用没有形参函数的时候不能少了()!!! Draw_Food;不报错,但是函数不产生作用!
gotoXY(55, 8);
cout<<"W = ↑ ,S = ↓";
gotoXY(55, 10);
cout<<"A = ← ,D = →";
while(1)
{
gotoXY(57, 15);
cout<<"当前得分:"<<count;
Control_Snake();
Move_Snake();
Draw_Snake();//Move + Draw = 蛇头前进一格(移动方向加*)
if (head->x == Food_x && head->y == Food_y) //吃到食物
{
Move_Snake();
Draw_Snake();
Food = 0;
++count;
Draw_Food();
}
Del_Snake();//去掉一格蛇尾
if(head->x == 0 || head->x == 49 || head->y == 0 || head->y == 24) //撞墙
{
cout<<"游戏结束!";
break;
}
Sleep(100);// 控制循环速度,即控制蛇速
}
return 0;
}
void gotoXY(short x, short y)
{
COORD loc = {x, y};
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(out, loc);
}
void Draw_Map(void) //画地图
{
for(int i=0; i<wall_x; ++i)
{
gotoXY(i, 0);
cout<<"-";
gotoXY(i, wall_y-1);
cout<<"-";
}
for(int j=0; j<wall_y; ++j)
{
gotoXY(0, j);
cout<<"|";
gotoXY(wall_x-1, j);
cout<<"|";
}
}
void Initialize_Snake(void) //初始蛇身
{
head->x = 5;
head->y = 5;
head->pNext = body1;
body1->x = 4;
body1->y = 5;
body1->pNext = body2;
body2->x = 3;
body2->y = 5;
body2->pNext = NULL;
}
void Draw_Snake(void) //画蛇
{
struct Snake * p = head;
while(p != NULL)
{
gotoXY(p->x, p->y);
cout<<"*";
p = p->pNext;
}
}
void Move_Snake(void) //移动蛇,应该是链表的知识,在前面添加数据,因为我还没有开始看数据结构,以此判断。
{
struct Snake * pNew = new Snake;
if (1 == direction) //上↑
{
pNew->x = head->x;
pNew->y = head->y - 1;
pNew->pNext = head;
head = pNew;
}
if (2 == direction) //下↓
{
pNew->x = head->x;
pNew->y = head->y + 1;
pNew->pNext = head;
head = pNew;
}
if (3 == direction) //左←
{
pNew->x = head->x - 1;
pNew->y = head->y;
pNew->pNext = head;
head = pNew;
}
if (4 == direction) //右→
{
pNew->x = head->x + 1;
pNew->y = head->y;
pNew->pNext = head;
head = pNew;
}
}
void Del_Snake(void) //删除蛇尾
{
struct Snake * p = head;
while((p->pNext)->pNext != NULL) //很棒的表达方式!(这样后面才能释放内存 又保证循环可行)
{
p = p->pNext;
}
gotoXY(p->pNext->x, p->pNext->y);
cout<<' ';
delete p->pNext; //释放内存,减少内存使用
p->pNext = 0; //不能少!!! 以此重复使用此循环!
}
void Control_Snake(void) // 控制蛇
{
char ch = 0;
while(kbhit()) //kbhit();功能及返回值:检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
{
ch = getch(); //会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句(非标准函数,注意移植性!)
if ('w' == ch || 'W' == ch)
direction = 1;
if ('s' == ch || 'S' == ch)
direction = 2;
if ('a' == ch || 'A' == ch)
direction = 3;
if ('d' == ch || 'D' == ch)
direction = 4;
}
}
void Draw_Food(void) // 生成食物
{
srand(time(NULL)); //随机数,自己百度
if (0 == Food)
{
Food_x = rand() % 47 + 2;
Food_y = rand() % 22 + 2;
struct Snake * p = head;
while(p != 0) 避免新产生的食物,出现在自己的身体位置
{
if (Food_x == p->x && Food_y == p->y)
{
Food_x = rand() % 47 + 2;
Food_y = rand() % 22 + 2;
}
p = p->pNext;
}
gotoXY(Food_x, Food_y);
cout<<'*';
Food = 1;
}
}