C语⾔编程实战——编写简单贪吃蛇程序
  ⼼之何如,有似万丈迷津,遥亘千⾥,其中并⽆⾈⼦可渡⼈,除了⾃渡,他⼈爱莫能助。
                          —-三⽑
编程环境:VC++
⼀、相关结构体以及函数:
1、Windows下坐标结构体COORD:
  COORD是Windows API中定义的⼀种结构,表⽰⼀个字符在控制台屏幕上的坐标。其定义为:
typedef struct _COORD {
SHORT X;    // horizontal coordinate
SHORT Y;    // vertical coordinate
} COORD;
2、SetConsoleCursorPosition()函数:
  Windows API中设置光标坐标的函数。头⽂件为#include < windows.h>
实例:该程序实现将“Helloword”打印到固定坐标。
#include<stdio.h>
#include<windows.h>
int main()
{
HANDLE hOut;
COORD pos={15,5};
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos); //将光标位置设置为(15,5)
printf("HelloWorld!\n");
return0;
}
  GetStdHandle()函数⽤于从⼀个特定的标准设备(标准输⼊、标准输出或标准错误)中取得⼀个句柄(⽤来标识不同设备的数值)。可以嵌套使⽤。每次设置光标之前必须先调⽤获得⼀个值hOut,所以可以把hOut定义成全局变量。
3、kbhit()按键捕捉函数:
  检查当前是否有键盘输⼊,若有则返回⼀个⾮0值,否则返回0 。
实例:程序⼀直打印HelloWorld,直到按“ESC”结束。
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main(void)
{
char ch;
while(ch!=27) //27为按键ESC的ASCII码
{
printf("HelloWorld\n");
if(kbhit())  //捕捉按键
ch=getch();  //将捕捉到的按键赋值给ch
}
printf("End!\n");
system("pause");
return0;
}
4、rand()函数:
  rand()函数是产⽣随机数的⼀个随机函数。包含于头⽂件#include< stdlib.h >中。
  我们通常通过伪随机数⽣成器提供⼀粒新的随机种⼦。函数 srand()(来⾃stdlib.h)可以为随机数⽣成器播散种⼦
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int seed; /*申明初始化器的种⼦,注意是unsigned int 型的*/
int k;
printf("Enter a positive integer seed value: \n");
scanf("%u",&seed);
srand(seed); //srand函数是随机数发⽣器的初始化函数
printf("Random Numbers are:\n");
for(k = 1; k <= 10; k++)
{
printf("%i",rand()); //若是rand()%n表⽰⽣成n以内的所有整数
printf("\n");
}
return0;
}
  %i和%d都是表⽰有符号⼗进制整数,但%i可以⾃动将输⼊的⼋进制(或者⼗六进制)转换为⼗进制,⽽%d则不会进⾏转换。
⼆、分模块写程序:
1、绘制边框draw_frame():
  因为我这⾥边框有游戏边框,和计分的边框两个,所以我封装了⼀个函数,⽅便直接调⽤。注意,这⼀Y轴正半轴是往下的,区别于我们数学中的坐标。
⽐如我调⽤draw_frame(30,20,0,0);
得到如下结果:
2、计分框:score_frame()
  主要是调⽤上⾯画框函数,但是还需要作相关处理,因为要打印“得分”,以及还要能够更新数据。
void  draw_frame(int  W,int  H,int  initX,int  initY)  //顺时针画框函数W 、H 为长度⾼度;initX ,initY 为起点坐标
{
COORD pos1={initX,initY};
int  i;
for (i= 0; i< W;i++)
{
pos1.X++;  //先不断往右移动
SetConsoleCursorPosition(hOut,pos1);
printf(".");
}
for (i= 0; i< H;i++)
{
pos1.Y++;  //再向下
SetConsoleCursorPosition(hOut,pos1);
printf(".");
}
for (i= 0; i< W;i++) //再向左
{
pos1.X--;
SetConsoleCursorPosition(hOut,pos1);
printf(".");
}
for (i= 0; i< H;i++)
{
pos1.Y--;  //再向上
SetConsoleCursorPosition(hOut,pos1);
printf(".");
}
}
//计分⽅框
draw_frame(10,5,WIDTH+10,0);  //调⽤上⾯画框函数画⼀个宽度为5,⾼度为10,起始坐标为(WIDTH+10,0)的框。这⾥我们把起始坐标放在了原来边框右
//将光标挪到⽅框内,打印“得分:”提⽰字符
COORD pos1={WIDTH+11,1};
SetConsoleCursorPosition(hOut,pos1);
printf("得分:");
//将光标继续挪动,⽤于计分:
COORD pos2={WIDTH+12,2};  //写计分位置的初始坐标,因为之前⽅框的起始坐标为(10,1),所以这⾥都加1。
SetConsoleCursorPosition(hOut,pos2);
printf("%d",score);
}
3、初始化贪吃蛇⾝:
  想要画出⼀条蛇,⼀个点⼀个点画,将每个点的坐标都保存在⼀个数组⾥⾯。
void InitSnake(COORD SnakeHead)
{
int i;
COORD temp = SnakeHead; //蛇头的起始坐标
for( i=0 ; i< InitLEN ; i++ )
{
arr[i]=temp;  //通过数组来存储蛇,⽅便后⾯显⽰
SetConsoleCursorPosition(hOut,temp);
temp.X--;    //打印⼀截,光标移动,避免覆盖打印在同⼀个点上。
}
SnakeLEN = InitLEN; //InitLEN是⼀个宏定义,蛇的初始长度
}
4、显⽰蛇⾝:
int i;
for( i=0; i < SnakeLEN;i++)
{
SetConsoleCursorPosition(hOut,arr[i]); //设置光标位置
if(i == 0)
{
printf("@"); //最先打印的是蛇头
}
else
{
printf("*"); 蛇⾝
}
贪吃蛇的编程代码
}
}
蛇头坐标为(5,3)
4、⽤随机数产⽣随机⾷物:
void creatFood()
{
srand((unsigned)time(NULL));
int x = (rand()%(WIDTH-1)+1);  //-1为了产⽣随机数⼩于WIDTH,+1为了使产⽣随机数⼤于0
int y = (rand()%(HIGH-1)+1);
food_pos.X =x; //food_pos是⼀个COORD变量
food_pos.Y =y;
SetConsoleCursorPosition(hOut,food_pos);
printf("o");  //打印⾷物图样
}
5.1、清除蛇⾝函数clearSnake()
void clearSnake()
{
int i;
for( i=0; i < SnakeLEN;i++)
{
SetConsoleCursorPosition(hOut,arr[i]);
printf(" ");  //打印空格来覆盖之前的轨迹。
}
}
5.2、移动move():
  上⾯画出了⼀条蛇,但是是静态的,我们要想办法让它动起来,动次动次,⼩⽕车要跑起来了。
  移动的主要思想就是通过单位时间上的位移来实现的,也相当于设定时间的画线,不过每次移动都需要把之前的蛇清除,然后再打印⼀次,让我们看起来就像有⼀条蛇在动。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。