鱼C论坛

 找回密码
 立即注册
查看: 1513|回复: 3

[技术交流] 这个应该叫飞机打豆豆 不叫飞机大战

[复制链接]
发表于 2020-3-7 17:25:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 就是要努力呀 于 2020-3-8 12:39 编辑

感觉比昨天写的贪吃蛇差远了
不知道怎么解决在用户没有输入的时候不会卡在scanf那里,后果就是游戏是一帧一帧的,你按一下他就刷新一下
有点赶懒 飞机就是个^ 简单明了
进步就是用了昨天大佬说的gotoxy函数,不再像昨天贪吃蛇那样一直用clear一直清屏了
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>

  5. #define MAX 50
  6. #define RANGE 20        //飞机射程 值越小射程越远
  7. int X = 40;        //飞机x坐标
  8. int Y = 24;        //飞机y坐标
  9. int COUNT = 0;        //得分

  10. void gotoxy(int x, int y);
  11. void printmain(void);        //打印主菜单
  12. void map_set_up(char (*map)[MAX]);        //生成地图
  13. void plane_set_up(char (*map)[MAX]);        //生成飞机
  14. void enemy_set_up(char (*enemymap)[MAX]);        //生成敌机
  15. void print_all(char (*map)[MAX], char (*enemymap)[MAX]);        //打印所有物品
  16. int get_move(char (*map)[MAX], char (*enemymap)[MAX]);        //获取指令
  17. void attack(char (*map)[MAX], char (*enemymap)[MAX]);        //进行攻击
  18. int check_attack(int i, char (*map)[MAX], char (*enemymap)[MAX]);        //检测攻击是否命中
  19. int do_move(char move, char (*map)[MAX], char (*enemymap)[MAX]);        //进行移动
  20. int check_plane(char(*map)[MAX], char (*enemymap)[MAX]);        //检测飞机是否越界或碰到敌机
  21. void reset_plane(char (*map)[MAX]);        //刷新飞机

  22. void gotoxy(int x, int y)
  23. {
  24.         printf("%c[%d;%df", 0x1B, x, y);
  25. }

  26. void reset_plane(char (*map)[MAX])        //刷新飞机
  27. {
  28.         map[X][Y] = ' ';
  29. }

  30. int check_plane(char(*map)[MAX], char (*enemymap)[MAX])        //检测飞机是否越界或碰到敌机
  31. {
  32.         if(enemymap[X][Y] == '*')
  33.         {
  34.                 return 0;
  35.         }

  36.         if(X == 0 || X == MAX - 1 || Y == 0 || Y == MAX - 1)
  37.         {
  38.                 return 0;
  39.         }

  40.         return 1;
  41. }

  42. int do_move(char move, char (*map)[MAX], char (*enemymap)[MAX])        //进行移动
  43. {
  44.         reset_plane(map);

  45.         switch(move)
  46.         {
  47.                 case 'w':
  48.                         X--;
  49.                         break;
  50.                 case 'a':
  51.                         Y--;
  52.                         break;
  53.                 case 's':
  54.                         X++;
  55.                         break;
  56.                 case 'd':
  57.                         Y++;
  58.                         break;
  59.         }

  60.         plane_set_up(map);
  61.         return check_plane(map, enemymap);
  62. }

  63. int check_attack(int i, char (*map)[MAX], char (*enemymap)[MAX])        //检测攻击是否命中
  64. {
  65.         if(enemymap[X - i][Y] == '*')
  66.         {
  67.                 COUNT++;

  68.                 enemymap[X - i][Y] = ' ';
  69.         }

  70.         print_all(map, enemymap);
  71. }

  72. void attack(char (*map)[MAX], char (*enemymap)[MAX])        //进行攻击
  73. {
  74.         int i;
  75.         time_t begin, end;

  76.         begin = clock();

  77.         for(i = 1; i <  RANGE && X - i > 0; i++)
  78.         {
  79.                 check_attack(i, map, enemymap);

  80.                 map[X - i][Y] = '|';
  81.         }

  82.         end = clock();
  83.        
  84.         print_all(map, enemymap);

  85.         do
  86.         {
  87.                 end = clock();
  88.         }
  89.         while((end - begin) <= 80000);

  90.         for(i = 1; i <  RANGE && X - i > 0; i++)
  91.         {
  92.                 map[X - i][Y] = ' ';
  93.         }

  94.         print_all(map, enemymap);
  95. }

  96. int get_move(char (*map)[MAX], char (*enemymap)[MAX])        //获取指令
  97. {
  98.         char move;

  99.         system("stty raw -echo");

  100.         do
  101.         {
  102.                 scanf("%c", &move);
  103.         }
  104.         while(move != 'w' && move != 'a' && move != 's' && move != 'd' && move != ' ' && move != 'q');

  105.         system("stty cooked echo");

  106.         if(move == 'q')
  107.         {
  108.                 return 0;
  109.         }

  110.         if(move == ' ')
  111.         {
  112.                 attack(map, enemymap);
  113.         }
  114.         else return do_move(move, map, enemymap);
  115. }

  116. void print_all(char (*map)[MAX], char (*enemymap)[MAX])        //打印所有物品
  117. {
  118.         int i, j;

  119.         gotoxy(0, 0);
  120.         printf("得分:%d\n", COUNT);

  121.         for(i = 0; i < MAX; i++)
  122.         {
  123.                 for(j = 0; j < MAX; j++)
  124.                 {
  125.                         if(enemymap[i][j] != ' ')
  126.                         {
  127.                                 printf("%c ", enemymap[i][j]);
  128.                         }
  129.                         else printf("%c ", map[i][j]);
  130.                 }

  131.                 putchar('\n');
  132.         }
  133. }

  134. void enemy_set_up(char (*enemymap)[MAX])        //生成敌机
  135. {
  136.         int count, i, j;

  137.         srand(time(NULL) + 1.345);

  138.         for(count = 0; count < 5; count++)
  139.         {
  140.                 do
  141.                 {
  142.                         i = rand()%47 + 1;
  143.                         j = rand()%47 + 1;
  144.                 }
  145.                 while(i != X && j != Y);
  146.                
  147.                 enemymap[i][j] = '*';
  148.         }
  149. }

  150. void plane_set_up(char (*map)[MAX])        //生成飞机
  151. {
  152.         map[X][Y] = '^';
  153. }

  154. void map_set_up(char (*map)[MAX])        //生成地图
  155. {
  156.         int i, j;

  157.         memset(map, ' ', MAX * MAX);

  158.         for(i = 0; i < MAX; i++)
  159.         {
  160.                 for(j = 0; j < MAX; j++)
  161.                 {
  162.                         if(i == 0 || j == 0 || i == MAX - 1 || j == MAX - 1)
  163.                         {
  164.                                 map[i][j] = '0';
  165.                         }
  166.                 }
  167.         }
  168. }

  169. void printmain(void)        //打印主菜单
  170. {
  171.         printf("1.开始游戏\n");
  172.         printf("2.退出游戏\n");
  173.         printf(":");
  174. }

  175. int main(void)
  176. {
  177.         char move;
  178.         char map[MAX][MAX];
  179.         char enemymap[MAX][MAX];
  180.         time_t begin, end;

  181.         memset(enemymap, ' ', MAX * MAX);

  182.         do
  183.         {
  184.                 printmain();
  185.                 scanf("%c", &move);
  186.                 getchar();
  187.         }
  188.         while(move != '1' && move != '2');


  189.         if(move == '1')
  190.         {
  191.                 map_set_up(map);
  192.                 plane_set_up(map);

  193.                 system("clear");

  194.                 begin = time(NULL);

  195.                 do
  196.                 {
  197.                         end = time(NULL);

  198.                         if(((end - begin) % 3) == 0)
  199.                         {
  200.                                 enemy_set_up(enemymap);
  201.                         }

  202.                         print_all(map, enemymap);
  203.                         gotoxy(52, 0);
  204.                         printf("请输入指令(w/a/s/d/j/q):");
  205.                 }
  206.                 while(get_move(map, enemymap));
  207.         }

  208.         system("stty cooked echo");
  209.        
  210.         return 0;
  211. }
复制代码




小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-7 17:45:29 | 显示全部楼层
空格是攻击
提示里忘记改了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-7 18:20:41 | 显示全部楼层
你需要的是非阻塞输入,可以试试ncurses库

  1. #include <stdio.h>
  2. #include <ncurses.h>
  3. #include <unistd.h>

  4. int main(void)
  5. {
  6.     WINDOW *w = initscr();
  7.     cbreak();
  8.     nodelay(w, TRUE);    // 进入非阻塞模式
  9.     noecho();           // 不要回显

  10.     sleep(3);
  11.     mvprintw(10, 5, "hello\n");
  12.     int ch;
  13.     ch = getch();
  14.     printw("%hhx\n", ch);

  15.     // 退出非阻塞模式
  16.     nodelay(w, FALSE);
  17.     getch();
  18.     endwin();
  19.     return 0;
  20. }
复制代码


这个程序用来测试非阻塞模式是不是正确
你有3秒时间按任意一个键,如果有按键,程序就输出这个按键
如果没有那就输出 ff
阻塞是由sleep(3);实现的,如果没有这个,你根本没有机会按下任何键
程序最后退出非阻塞模式,等待按下一个键后退出

编译这个程序用
  1. gcc -o main main.c -lncurses
复制代码


我使用的是
  1. gcc -g -Wall -o main main.c -lncurses
复制代码

  1. -lncurses
复制代码

这个是关键

值得一提的是之前的gotoxy作废,ncurses中使用mvprintw

还有一件事,你上面的gotoxy拼错了,写成了goutoxy

^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-8 12:37:59 From FishC Mobile | 显示全部楼层
人造人 发表于 2020-3-7 18:20
你需要的是非阻塞输入,可以试试ncurses库



ok谢谢大佬虽然看完一脸懵逼
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-6 20:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表