admin管理员组文章数量:1794759
c语言入门级小游戏·飞机(2.0版)
目录
前言
制作可以自由移动并且发射子弹的飞机
介绍第一种清屏函数system("cls")
介绍kbhit函数
介绍方便的getch()函数
添加可以自己移动、击落后会重生的障碍物
标识符的命名
介绍rand函数
加上计分板,优化频闪问题
介绍gotoxy函数
介绍HideCursor函数
完整代码
前言
声明:本游戏参考《c语言课程设计与游戏开发实践教程》。
首先放一个小游戏视频效果(右边界有点凌乱,影响美观,但不影响效果,多多见谅😋)
game飞机2.0版
如何?这个单单用字符来完成的简略版小游戏,很适合c语言的新手锻炼实践能力(理论即可)。这个2.0版的飞机小游戏实际上是在我上次发的1.0版基础上优化的(t.csdn/O1jRV)相比之下,2.0版不再有画面和光标的频闪问题,发射方式从激光变成子弹,障碍物可移动并重现,有计分功能。
- 本游戏必备知识点:printf输出,for语句,if语句,while循环,函数的自定义和引用,自增自减运算符。
- 本游戏会介绍的知识点:标识符的命名,两种清屏函数,rand函数,方便的getch函数,kbhit函数,隐藏光标函数。(如果不知道这些小知识点并不影响,看了介绍和应用很基本就可以理解)。
- 该函数位于stdlib.h函数库,头文件要机上#include <stdlib.h>。
- 作用:该函数可以在循环中清空上一次的画面,在这里实现飞机的自由移动(要不然飞机移动就跟重影一样,跟李白技能一样)
- 使用:system("cls");
- 这个函数在conio.h函数库中,头文件要加上#include <conio.h>。
- 我们在这里是这样使用:if(kbhi()) {输入...运行...}
- 作用:该函数可以判断是否有输入,并且防止程序运行堵塞。一般情况下,如果有输入函数出现,程序会停下来等待输入,这时候程序就堵塞住了。kbhit的作用就是不让程序这时候发生堵塞。如果有输入,那么if内相应程序会运行;如果没有输入,if外程序仍然可以运行。
- 该函数位于conio.h函数库中,头文件要加上#include <conio.h>。
- 作用:getch()函数只接受单字符。原本的scanf会在输入之后按下回车键才能继续运行,但是getch()函数接受单个字符之后不需要按回车键就会结束输入,继续运行。
- 使用:a=grtch();
直接上代码,代🐎中有详细的注释解析哦
#include <stdio.h> #include <stdlib.h> //system函数库 #include <conio.h> //getch函数库 ,kbhit函数库 //飞机可移动,有子弹 //定义几个全局变量,方便所有函数使用 int x,y; //飞机坐标 int high,width; //画面宽度 int billx,billy; //子弹坐标 void start() //第一个自定义函数,作用是使数据初始化 { //一个不冷不热的知识:全局变量不能在函数外赋值,能在任意函数中赋值 high=20; width=30; x=width/2; y=high/2; billx=x; billy=0; } void show() //第二个函数,显示飞机和边界 { int i,n; system("cls");//这个清屏函数其实放很多地方都行 ,只要是在死循环里 for(i=0;i<high;i++) //外层循环,用于输出回车和左右边界 { printf("#"); //用于输出左侧边界 for(n=0;n<width;n++) //内层循环,用于输出空格、飞机、上下边界 {if((i==y)&&(n==x)) printf(" +");//&&两侧运算式最好都加() else { if((i==0)||(i==19)) printf("#"); //划定上下边界 else if((i==billy)&&(n==billx)) printf(" |"); //输出子弹。前面加三个空格,因为要和飞机头照齐 else if((i==y+1)&&(n==x)) printf("+---+"); else if((i==y+2)&&(n==x)) printf(" * *"); else printf(" ");//没错就是套娃,这个过程是在输出整个飞机体 } } printf("#"); //输出右方边界 //如果飞机移动时超出界限就会消失。但飞机仅仅是看不见了,实际上还存在 printf("\\n"); } } void unput() //第三个自定义函数,用于控制子弹 { if(billy>-1) billy--; //目的是让子弹一直往上飞 } void put() //第四个函数,输入字符控制飞机移动、放出子弹 { char move; if(kbhit()) { move=getch(); if(move=='a')x--; if(move=='d')x++; if(move=='w')y--; if(move=='s')y++; if(move==' '){ billx=x-1; //因为边界占一个字节位置,如果不-1会让子弹和飞机错开一个位置 billy=y-1; //因为要让子弹在飞机上一行输出 } } } int main() { start(); //第一个函数 while(1) //1代表正确,0代表非,所以while(1)一直满足条件,无限循环 { // system("cls");清屏函数加这也行 show(); //第二个函数 unput(); //第三个函数 put(); //第四个函数 //再次引用函数的时候不需要加数据类型 } return 0; } 添加可以自己移动、击落后会重生的障碍物 标识符的命名标识符一般包括变量名、常量名、函数名...
- 属于stdlib.h函数库,头文件要加上#include<stdlib.h>。
- 作用:使一个东西在一定范围内随机出现。在这里就是让障碍物小时候再重现
- 使用方式:a=rand()%rage;
(a是一个随机变量,在这里表示障碍物横坐标;rage是横坐标可以出现的宽度范围。在代码的运用中可以帮助你更好地理解作用)
来,上代码!(代码中每一步有详解)
#include <stdio.h> #include <stdlib.h>//system函数库 #include <conio.h>//getch函数库 #include <windows.h>//void gotoxy(int x,int y)和HideCursor()函数库 int x,y; //飞机的位置 int high,width; //画面宽度 int billx,billy; //子弹 int enermy_x,enermy_y;//敌机 。 int score; //定义全局变量 void start() //第一个自定义函数,作用是使数据初始化 { //一个不冷不热的知识:全局变量不能再函数外赋值,能在任意函数中赋值 high=20; width=30; x=width/2; y=high/2; billx=x; billy=0; enermy_x=x+5; enermy_y=2; score=0; } void show()//第二个函数,显示飞机 { int i,n; system("cls");//这个清屏函数其实加很多地方都行 ,只要是在死循环里 for(i=0; i<(high); i++) { printf("#"); for(n=0; n<width; n++) { if((i==y)&&(n==x)) printf(" +");//&&两侧运算式最好都加()。为了和身体对称,前面加空格 else { if((i==0)||(i==19)) printf("#"); //划定上下界限 else if((i==billy)&&(n==billx)) printf(" |"); else if((i==enermy_y)&&(n==enermy_x)) printf("*"); //输出障碍物,障碍物长啥样都可以 else if((i==y+1)&&(n==x)) printf("+---+"); else if((i==y+2)&&(n==x)) printf(" * *"); else printf(" "); //没错这就是套娃 } } printf("#"); //划定左右界限,如果飞机移动时超出界限会消失,飞机仅仅是看不见,实际上还存在。 printf("\\n"); } } void unput() //第三个函数,控制子弹飞行、控制障碍物掉落和消失重现 { if(billy>-1) billy--;//目的是让子弹一直往上飞 if((billx==enermy_x)&&(billy==enermy_y)) { score++; enermy_y=0;//让障碍物从顶上掉下来 enermy_x=rand()%width;//意思就是在该宽度范围内随机出现 billx=-2; //子弹横坐标为负,子弹就不再出现在画面内。产生了使子弹被击中后消失的效果 } static int speed=0; //static使得该变量作用域仅仅在当前函数内 if(speed==20){ enermy_y++; speed=0; } else speed++; //让敌机每循环20次下落一次,要不然掉的太快打不中 //这里两种表示方法都生效 } void put() //第四个函数,通过输入端控制飞机移动并发射子弹 { char move; if(kbhit()) { move=getch(); if(move=='a')x--; if(move=='d')x++; if(move=='w')y--; if(move=='s')y++; if(move==' ') { billx=x; billy=y-1;//因为要让子弹在飞机上方输出 } } } int main() { start(); while(1) { // system("cls");加这也行 show(); unput();//再次引用函数的时候不要加数据类型 put(); } return 0; } 加上计分板,优化频闪问题该游戏已经基本制作完成。这时候你会发现画面闪烁很厉害,而且光标的频闪也很影响美观。因此,这一步我们加上两个函数,分别优化画面频闪和光标频闪问题。同时加上计分板,统计击中障碍物个数。
介绍gotoxy函数这个函数代替了上一个清屏函数system函数,解决画面频闪问题。不用管任何别的东西,直接输入下面的函数内容。
void gotoxy(int x,int y) { HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X=x; pos.Y=y; SetConsoleCursorPosition(handle,pos); }
介绍HideCursor函数该函数作用是隐藏光标,解决光标频闪问题。使用方法如下(直接用)
void HideCursor() { CONSOLE_CURSOR_INFO cursor_info={1,0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); }
加上这最后两个函数,游戏画面就会变得更加清晰稳定啦!最后给大家放上完整代码👇🏻
完整代码 #include <stdio.h> #include <stdlib.h>//system函数库 #include <conio.h>//getch函数库 #include <windows.h>//void gotoxy(int x,int y)和HideCursor()函数库 //发挥 int x,y;//飞机的位置 int high,width;//画面宽度 int billx,billy; //子弹 int enermy_x,enermy_y;//敌机 。知识点标识符的用法 int score; //定义全局变量 void gotoxy(int x,int y) //清屏 { HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X=x; pos.Y=y; SetConsoleCursorPosition(handle,pos); } void start() //第一个自定义函数,作用是使数据初始化 { //一个不冷不热的知识:全局变量不能再函数外赋值,能在任意函数中赋值 high=20; width=30; x=width/2; y=high/2; billx=x; billy=0; enermy_x=x+5; enermy_y=2; score=0; } void show()//第二个函数,显示飞机 { int i,n; gotoxy(0,0); //将清屏函数引用进来 //system("cls");//这个清屏函数其实加很多地方都行 ,只要是在死循环里 for(i=0; i<(high); i++) { printf("#"); for(n=0; n<width; n++) { if((i==y)&&(n==x)) printf(" +"); else { if((i==0)||(i==19)) printf("#");//划定上下界限 else if((i==billy)&&(n==billx)) printf("|"); else if((i==enermy_y)&&(n==enermy_x)) printf("*"); else if((i==y+1)&&(n==x)) printf("+---+"); else if((i==y+2)&&(n==x)) printf(" * *"); else printf(" ");//没错就是套娃 } } printf("#");//划定左右界限,如果飞机移动时超出界限就会消失,划定界限会提醒你自己,不然飞机怎么没了都不知道 。飞机仅仅是不见了,但是还存在 printf("\\n"); } printf("Your's score is%d",score); //在画面最后部分输出计分板 } void unput()//第三个函数 { static int speed=0;//作用域仅仅在当前函数 int replace=20;//确实有调节素的的作用,不过超过一定数字之后就不会再次显示了 if(billy>-1) billy--;//目的是让子弹一直往上飞 if((billx==enermy_x)&&(billy==enermy_y)) { score++; enermy_y=0;//让障碍物从顶上掉下来 enermy_x=rand()%(width);//意思就是在宽度范围内的最上方可以随机出现 billx=-2;//让子弹击中障碍物之后消失 replace--; } // if(speed!=10)speed++; if(speed==replace){ enermy_y++; speed=0; } else speed++; //让敌机每循环十次下落一次 //这里两种表示方法都生效 } void put()//第四个函数,控制移动 { char move; if(kbhit()) { move=getch(); if(move=='a')x--; if(move=='d')x++; if(move=='w')y--; if(move=='s')y++; if(move==' ') { billx=x+2; billy=y-1;//因为要让子弹在飞机上方输出 } } } void HideCursor() //隐藏光标函数 { CONSOLE_CURSOR_INFO cursor_info={1,0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); } int main() { start(); while(1) { show(); unput();//再次引用函数的时候不要加数据类型 put(); HideCursor(); //引用隐藏光标函数 } return 0; }最后有2个小思考题:1.如何使用esc键暂停游戏? 2.如何使分数越高障碍物下落速度越快?
这两个问题目前我也没有解决,如果你们解决了请务必教教我🙏🏻
如果用不懂得地方可以随时评论或者私信我哦
就酱,拜拜~
版权声明:本文标题:c语言入门级小游戏·飞机(2.0版) 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686895263a115490.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论