前言
很多学过C语言的朋友都说已经学完了C语言入门,但是实际能力还处于很低的水平。基本上就是他们设置几个for循环,暴力解决排列组合问题的关卡。很多人基本都无法独立编写一个小程序。今天给大家举一个我很久以前做过的简单的吃蛇案例。
这一次编写控制台蛇程序,对于学过C语言没有做过任何项目的小伙伴来说,可能是一个不小的挑战。
本文中蛇案用到的东西不多,游戏的实现主要是按照一定的逻辑对一个二维数组进行修改和变换(实际操作中,我使用了字符串来减少闪烁)。这里就不重复编写过程了,主要说一下最基本的函数的逻辑,还有一些以前很少用到的函数。
一.基本功能逻辑
1。游戏背景,打印
定义一个二维字符串,用“”和空格表示边界、蛇体、空白等。打印是用for循环遍历整个字符串,并以一定的频率刷新,可以达到游戏效果。
2。构建蛇形数组
考虑到我没做过链表,也不是很熟练,所以用array做蛇。数组容量有限,需要先定义最长长度(只要我设置的足够长hhhh),很多地方需要获取地址(敲n次“&”)等缺点。存储阵列蛇的结数、XY坐标、移动方向等参数。需要注意的是,“”占用了两个字节,很多地方写坐标都要乘以二。
3。生成蛇的随机坐标
首先,种植随机种子,使用系统时间作为种子。两个变量x和y被定义为坐标值,rand()函数用于获得所需的坐标值范围。那么最初将生成两个或三个部分。
4。在地图上画蛇
构建一个for循环遍历整条蛇,使用strncpy()函数将空的白色部分***到" "。
5。蛇的运动
我被困在这里很久了。期间去玩过饕餮蛇,发现蛇的移动方式并不是很复杂。可以说是蛇尾去了一个,蛇头加了一个。我采用了整个蛇身前移,蛇头分开处理的方法,也便于以后的方向控制。
6。擦除运动轨迹
写到最后一步你会发现蛇越来越长。。。。就像崩溃后的鼠标光标一样。。。。因为虽然前一个节点的属性赋给了后一个节点,但是这个节点并没有改变。所以每次运动前,把你面前的蛇擦掉。方法同第四步,只需将“”替换为两个空方块即可。
7。这条蛇改变了方向
由于蛇运动的特殊性,只需要对蛇头进行处理。用GetAsyncKeyState()函数读取键盘输入,注意防止snake被附加条件调头。
8。生产食物
随机坐标,复印打印。
9。蛇吃长的食物
蛇运动到食物的地方会把食物覆盖掉,所以吃掉食物的效果不用写。只用判断蛇头坐标和食物坐标重合,然后判断运动方向来确定在哪里加一节就行了。然后用一个布尔值判断场上是否还有食物,来生成新的食物。计分也可以在此处写。
蛇移动到食物的地方会把食物盖住,吃到食物的效果就不用写了。只需要判断蛇头坐标和食物坐标的重合,然后判断移动的方向就可以确定在哪里加一段了。然后用一个布尔值来判断场上是否有食物,从而生成新的食物。分数也可以写在这里。
网络效果图
代码如下:
# define _ CRT _ SECURE _ NO _ WARNINGS 1 # include <stdio.h & gt# include & ltstdlib.h & gt# include & lt***th.h & gt# include & ltconio.h & gt# include & lttime.h & gt# include & ltwindows.h & gt# define ***x width 30 # define ***x height 30 # define initlen 3//snake结构的初始长度{
char * chint颜色;字符类型;
}
charBorder = { & # 8220”,4,1 },//border charBg = { “”,2,2 },//background char snake = { “”,0xe,3 },//蛇节点charFood = { & # 8220”,0xc,4 };//Food//用数组结构保存地图中的每个点结构{
字符类型;int索引;
} global ***p[MAXWIDTH][***x height];结构{
int x;int y;
} snake ***p[(MAXWIDTH –2)*(***x height –2)],scoresPostionint分数= 0;//score int snake ***plen =(MAXWIDTH –2)*(***x height –2);int headerIndex,tailIndex
处理hStdin
//设置光标位置,其中x是行,y是列void setPosition(int x,int y){
COORD coord
坐标。x = 2 * y;
坐标。y = x;
SetConsoleCursorPosition(HST din,coord);
}//设置颜色void setColor(int color){
SetConsoleTextAttribute(hStdin,color);
}//创建food void创建food () {int index,rang,x,y;
srand((无符号)时间(空));if(tail index <headerIndex){
rang = headerIndex & # 8211tailIndex & # 82111;
index = rand()% rang+tail index+1;
}否则{
rang = snakeMapLen & # 8211(tailIndex & # 8211header index+1);
index = rand()% rang;if(index >= headerIndex){
index+=(tail index –header index+1);
}
}
x = snakeMap[index]。x;
y = snakeMap[index]。y;
setPosition(x,y);
set color(char food . color);printf(“% s & # 8221,char food . ch);
全球地图[x][y]。type = charFood.type
}//dead void ***(){ int xcenter = ***x height % 2 = = 0?***x height/2:***x height/2+1;int yCenter = MAXWIDTH % 2 == 0?MAXWIDTH/2:MAXWIDTH/2+1;
setPosition(xCenter,yCenter & # 82115);
set color(0xC);出口(1);
_ getch();退出(0);
}//Snake moves void move (char方向){int新头x,新头y;//新蛇头的坐标
int newHeaderPreIndex//新蛇头坐标的前一个索引
int newHeaderPreX,newHeaderPreY//之前新蛇头的索引对应的坐标
int newHeaderPreType//新蛇头的先前类型
int oldTailX,oldTailY//旧蛇尾坐标
开关(方向){案例‘w & # 8217:
newHeaderX = snakeMap[header index]。x & # 82111;
new headery = snake ***p[header index]。y;打破;案例‘s & # 8217:
newHeaderX = snakeMap[header index]。x+1;
new headery = snake ***p[header index]。y;打破;案例‘一’:
newHeaderX = snakeMap[header index]。x;
new headery = snake ***p[header index]。y & # 82111;打破;案例‘d & # 8217:
newHeaderX = snakeMap[header index]。x;
new headery = snake ***p[header index]。y+1;打破;
}
headerIndex = headerIndex == 0?snakeMapLen & # 82111:header index –1;
newHeaderPreIndex = global ***p[newHeaderX][newHeaderY]。指数;
newHeaderPreX = snakeMap[header index]。x;
newHeaderPreY = snakeMap[header index]。y;
snakeMap[headerIndex]。x = newHeaderX
snakeMap[headerIndex]。y = newHeaderY
global ***p[newHeaderX][newHeaderY]。index = headerIndex
snakeMap[newHeaderPreIndex]。x = newHeaderPreX
snakeMap[newHeaderPreIndex]。y = newHeaderPreY
global ***p[new header prex][new header prey]。index = newHeaderPreIndex//新蛇头的先前类型
newHeaderPreType = global ***p[newHeaderX][newHeaderY]。类型;//设置新的蛇头类型
global ***p[newHeaderX][newHeaderY]。type = charSnake.type//判断自己是出界还是打自己
if(new header pretype = = char border . type | | new header pretype = = char snake . type){
***();
}//输出新的蛇头
setPosition(newHeaderX,newHeaderY);
set color(char snake . color);printf(“% s & # 8221,char snake . ch);//判断你是否吃食物
if(newheaderpretype = = char food . type){//吃菜
create food();//更改分数
set position(scores position . x,scores position . y);printf(“% d & # 8221,++分数);
} else{ //旧蛇尾坐标
oldTailX = snakeMap[tailIndex]。x;
oldTailY = snakeMap[tailIndex]。y;//删除蛇尾
setPosition(oldTailX,oldTailY);
set color(charbg . color);printf(“% s & # 8221,charbg . ch);
globalMap[oldTailX][oldTailY]。type = charBg.type
tailIndex = (tailIndex == 0)?snakeMapLen & # 82111:tail index –1;
}
}//下一步棋的方向是charnext direction (charch,char direction old){ int sum = ch+direction old;
ch = to lower(ch);if((ch = = ‘w & # 8217| | ch = = & # 8216一’| | ch = = & # 8216s & # 8217| | ch = = & # 8216d & # 8217)& amp& amp求和!= 197 & amp& amp求和!= 234){ return ch;
} else { return directionOld
}
}//Pause char Pause(){ return _ getch();
}//初始化void init(){ //设置相关变量
int x,y,indexint xCenter = MAXHEIGHT % 2 == 0?***x height/2:***x height/2+1;int yCenter = MAXWIDTH % 2 == 0?MAXWIDTH/2:MAXWIDTH/2+1;
控制台_光标_信息CCI;//控制台光标信息
//判断相关设置是否合理。
if(MAXWIDTH <16){ printf(“‘MAXWIDTH & # 8217太小了!”);
_ getch();退出(0);
}//设置窗口大小
系统(“模式con:cols = 96 lines = 32 ”);//隐藏光标
HST din = GetStdHandle(STD _ OUTPUT _ HANDLE);
GetConsoleCursorInfo(HST din &CCI);
CCI . b visible = 0;
SetConsoleCursorInfo(HST din &CCI);//打印背景
for(x = 0;x & ltMAXHEIGHTx++){ for(y = 0;y & ltMAXWIDTHy++){ if(y = = 0 | | y = = MAXWIDTH –1 | | x = = 0 | | x = = MAXHEIGHT & # 82111){
全球地图[x][y]。type = charBorder.type
set color(char border . color);printf(“% s & # 8221,char border . ch);
}否则{
index =(x –1)*(MAXWIDTH –2)+(y –1);
snake ***p[索引]。x = x
snake ***p[索引]。y = y
全球地图[x][y]。type = charBg.type
全球地图[x][y]。index =索引;
set color(charbg . color);printf(“% s & # 8221,charbg . ch);
}
} printf(“n & # 8221);
}//初始化Snake
global ***p[xCenter][y center –1].type = global ***p[xCenter][y center]。type = global ***p[xCenter][y center+1]。type = charSnake.type
header index =(xCenter –1)*(MAXWIDTH –2)+(y center –1) –1;
tail index = header index+2;
setPosition(xCenter,yCenter & # 82111);
set color(char snake . color);for(y = y center –1;y & lt= y center+1;y++){ printf(“% s & # 8221,char snake . ch);
}//生成食物
create food();//设置程序信息
set position(xCenter –1,MAXWIDTH+2);printf(”得分:0 ″);
setPosition(xCenter,MAXWIDTH+2);printf(”班级名称:杨超,33班”);
scores position . x = xCenter –1;
scores position . y = MAXWIDTH+8;
}int ***in(){ char charInput,direction = & # 8216一’;
init();
charin put = to lower(_ getch());
direction = next direction(charInput,direction);while (1){ if (_kbhit()){
charin put = to lower(_ getch());if(charin put = = ‘‘){
charin put = pause();
}
direction = next direction(charInput,direction);
}
移动(方向);
睡眠(500);
}
_ getch();返回0;
}
希望对大家有帮助~
本文来自我要无比强大投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/478114.html