/*
*****************************************************************************************
* Copyright (C) 2012 - ?, Changsha Spon Electronic Co., Ltd
*****************************************************************************************
* Filename : Snake.c
* Author : Shangguan Juehen
* Created : 2012/10/25
* Description : Beginner's first game
*****************************************************************************************
* $Id:$
本程序流程:初始化(环境,空间) —> (获取并判断按键值) —> (执行相应操作) —>
(如果吃到苹果,及坐标相等) —> (增大存储空间,分值++) —> (输出到显示) —> (返回)
*****************************************************************************************
*/
#include<windows.h>
#include<time.h>
#include<conio.h>
#include <iostream>
using namespace std;
#define N 21
void gotoxy(int x,int y)//位置函数
{
COORD pos;
pos.X = 2 * x;
pos.Y = y;
//GetStdHandle()函数获得标准输入输出的设备的句柄,参数STD_OUTPUT_HANDLE是个宏,
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);//代表标准输出,可以看作显示器
// 看函数名称:设置控制台光标坐标,参数就是设备句柄,那么把标准输出的句柄传给函数,
SetConsoleCursorPosition(hout,pos);//就可以把光标定位在对应的位置了
}
void color(int a)//颜色函数
{
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hout,a);
}
void init(int apple[2])//初始化函数(初始化围墙、显示信息、苹果)
{
int i,j;//初始化围墙
int wall[N + 2][N + 2] = {{0,0}};
for (i = 1; i <= N; i++)
{
for (j = 1; j <= N; j++)
wall[i][j] = 1;
}
color(13);//围墙颜色
for (i = 0; i < N + 2; i++)//围墙区域显示
{
for (j = 0; j < N + 2; j++)
{
if (wall[i][j] == 1)
cout << " ";
else cout << "■";//"□" ;//围墙
}
cout << endl;
}
gotoxy(N + 3,1);//设置光标到文本屏幕的指定位置,其中参数x,y为文本屏幕的坐标。
color(30);//显示信息颜色设置
cout << "按 W S A D 移动方向" << endl;
gotoxy(N + 3,2);
color(30);
cout << "按R加速,按T减速" << endl;
gotoxy(N + 3,3);
color(30);
cout << "按其它键暂停" << endl;
gotoxy(N+3,4);
color(30);
cout << "速度等级: 3" << endl;
gotoxy(N+3,5);
color(30);
cout << "得分: 0" << endl;
apple[0] = rand()%N + 1;//函数rand()是随机数生成器
apple[1] = rand()%N + 1;//函数rand()会返回一个处于0和你所指定的数值(缺省为1)之间的分数
gotoxy(apple[0],apple[1]);
color(12);//红色
cout << "●" << endl;//苹果
}
int main()
{
int i;
int** snake = NULL;//指向蛇的二维指针;snake[0][1]表示蛇的纵坐标;snake[0][0]表示蛇的横坐标
int apple[2] = {0,0};//保存当前苹果的坐标
int score = 0;//计算得分
int len = 3;//开始蛇身长
char ch = 'p', b_ch = 'p';
int speed = 200;
int splevel = 2;
//srand()会设置供rand()使用的随机数种子
srand((unsigned)time(NULL));//使用系统定时/计数器的值做为随机种子
init(apple);
snake = (int**)realloc(snake,sizeof(int*) * len);//重新分配能容纳蛇全身的空间
for (i = 0; i < len; i++)
snake[i] = (int*)malloc(sizeof(int) * 2);//分配容纳蛇一段的空间
for (i = 0; i < len; i++)
{
snake[i][0] = N/2;
snake[i][1] = N/2 + i;
//gotoxy(x, y); x代表左右,y代表上下,x越大坐标越往右,y越大坐标越往下
gotoxy(snake[i][0], snake[i][1]);
color(14);
cout << "★" << endl;//开始时的蛇身~小花蛇
}
while(1)
{
gotoxy(snake[len - 1][0], snake[len - 1][1]);
color(11);
cout<<" "<< endl;//■ 清除尾巴
for (i = len - 1; i > 0; i--)
{
snake[i][0] = snake[i - 1][0];
snake[i][1] = snake[i - 1][1];
gotoxy(snake[i][0], snake[i][1]);
color(14);
cout << "■" << endl;//尾巴形状显示
}
gotoxy(snake[0][0], snake[0][1]);
color(14);
cout << "★" << endl;//头显示
for(int i=0;i<10;i++)
{
if (kbhit() != 0)//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
{
gotoxy(0, N + 2);
ch = getche();
if (ch == 'w' || ch == 's' || ch == 'a' || ch == 'd')
b_ch = ch;
if (speed <= 40)
speed = 40;
else if (speed >= 340)
speed = 340;
splevel = speed / 50;
gotoxy(N + 8, 4);
color(10);
cout << 7 - splevel << endl;//速度
}
Sleep((abs(speed - 0.5 * score) / 10));//蛇速度设置
}
switch(ch)
{
case 'w':snake[0][1]--; break;
case 's':snake[0][1]++; break;
case 'a':snake[0][0]--; break;
case 'd':snake[0][0]++; break;
case 'r':
speed += 10;
switch (b_ch)
{
case 'w':snake[0][1]--; break;
case 's':snake[0][1]++; break;
case 'a':snake[0][0]--; break;
case 'd':snake[0][0]++; break;
default: break;
}break;
case 't':
speed -= 10;
switch (b_ch)
{
case 'w':snake[0][1]--; break;
case 's':snake[0][1]++; break;
case 'a':snake[0][0]--; break;
case 'd':snake[0][0]++; break;
default: break;
}break;
default: break;
}
if (snake[0][0] == apple[0] && snake[0][1] == apple[1])//吃掉苹果后蛇分数加1,蛇长加1
{
score++;
len++;
snake = (int**)realloc(snake,sizeof(int*) * len);//增大空间
snake[len - 1] = (int*)malloc(sizeof(int) * 2);//为新增空间分配内存
apple[0] = rand() % N + 1;//获取随机坐标
apple[1] = rand() % N + 1;
gotoxy(apple[0], apple[1]);
color(12);
cout << "●" << endl;//苹果
gotoxy(N + 6, 5);
color(10);
cout << score;
}
// 上 下 左 右
if (snake[0][1] == 0 || snake[0][1] == N + 1 || snake[0][0] == 0 || snake[0][0] == N + 1)
{ //撞到围墙后结束游戏
gotoxy(N/2, N/2);
color(60);
cout << "Game over" << endl;
for (i = 0; i < len; i++)
free(snake[i]);
Sleep(INFINITE);
exit(0);
}
}
return 0;
}