• lv6 嵌入式开发-Flappy bird项目(功能实现)


    目录

    项目安排:

    1 阶段

            1.1 初始化Ncurses库

            1.2 设置定时时间

            1.3 实现小鸟功能(显示小鸟、清除小鸟、移动小鸟)

    2 阶段

            2.1 创建链表

            2.2 显示管道

            2.3 清除管道

            2.4 移动管道

    3 阶段

            3.1 判断游戏结束:小鸟与管道碰到

            3.2 循环创建管道

            3.3 为管道和小鸟添加色彩

    4 完整代码:


    项目安排:

    阶段1:初始化工作,小鸟功能实现

    阶段2:管道功能实现

    阶段3:完善代码,进行项目总结

    1 阶段

            1.1 初始化Ncurses库

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. void init_curses()
    8. {
    9. initscr();
    10. curs_set(0); //禁止光标显示
    11. noecho(); //禁止输入字符显示
    12. keypad(stdscr, 1); //启动功能按键
    13. start_color();
    14. init_pair(1,COLOR_WHITE, COLOR_RED);//小鸟颜色设置
    15. init_pair(2,COLOR_WHITE, COLOR_GREEN);//管道颜色设置
    16. }

            1.2 设置定时时间

    1. int set_timer(int ms_t)//设置定时器--ms
    2. {
    3. struct itimerval timer;
    4. long t_sec,t_usec;
    5. int ret;
    6. t_sec = ms_t / 1000; //s
    7. t_usec = (ms_t % 1000) * 1000;//us
    8. timer.it_value.tv_sec = t_sec;
    9. timer.it_value.tv_usec = t_usec;//首次启动定时值
    10. timer.it_interval.tv_sec = t_sec;
    11. timer.it_interval.tv_usec = t_usec;//定时时间间隔
    12. ret = setitimer(ITIMER_REAL, &timer, NULL);
    13. return ret;
    14. }

            1.3 实现小鸟功能(显示小鸟、清除小鸟、移动小鸟)

    1. #define BIRD '@'
    2. #define BLANK ' '
    3. #define PIPE '+'
    4. void show_bird()//显示小鸟
    5. {
    6. attron(COLOR_PAIR(1));
    7. move(bird_y,bird_x);
    8. addch(BIRD);
    9. refresh();
    10. attroff(COLOR_PAIR(1));
    11. }
    12. void clear_bird()//清除小鸟
    13. {
    14. move(bird_y,bird_x);
    15. addch(BLANK);
    16. refresh();
    17. }
    18. void move_bird()//移动小鸟
    19. {
    20. char key;
    21. while(1)
    22. {
    23. key = getch();
    24. if(key == ' ')
    25. {
    26. clear_bird();
    27. bird_y--;
    28. show_bird();
    29. /*游戏结束判断*/
    30. if((char)inch() == PIPE)
    31. {
    32. set_timer(0);
    33. endwin();
    34. exit(1);
    35. }
    36. }
    37. }
    38. }

    2 阶段

            2.1 创建链表

    1. void creat_list()//创建链表
    2. {
    3. int i;
    4. Pipe_list p, new;
    5. head = (Pipe_list)malloc(sizeof(Pipe_node));
    6. head->next = NULL;
    7. p = head;
    8. for(i = 0; i < 5; i++)
    9. {
    10. new = (Pipe_list)malloc(sizeof(Pipe_node));
    11. new->x = (i + 1) * 20;
    12. new->y = + 5; // (5-15行)
    13. new->next = NULL;
    14. p->next = new;
    15. p = new;
    16. }
    17. tail = p;
    18. }

            2.2 显示管道

    1. /*定义关于管道的结构体*/
    2. typedef struct Pipe{
    3. int x;//列坐标
    4. int y;//横坐标
    5. struct Pipe *next;
    6. }Pipe_node, *Pipe_list;
    7. Pipe_list head, tail;
    8. void show_pipe()//显示管道
    9. {
    10. Pipe_list p;
    11. int i,j;
    12. p = head->next;
    13. attron(COLOR_PAIR(2));
    14. while(p)
    15. {
    16. for(i = p->x; i < p->x+10; i++)
    17. {
    18. /*上半部分管道*/
    19. for(j=0; jy; j++)
    20. {
    21. move(j,i);
    22. addch(PIPE);
    23. }
    24. /*下半部分管道创建*/
    25. for(j = p->y+5; j < 25; j++)
    26. {
    27. move(j,i);
    28. addch(PIPE);
    29. }
    30. }
    31. refresh();
    32. p = p->next;
    33. }
    34. attroff(COLOR_PAIR(2));
    35. }

            2.3 清除管道

    即把显示管道的字符改为空格

    1. void clear_pipe()
    2. {
    3. Pipe_list p;
    4. int i,j;
    5. p = head->next;
    6. while(p != NULL)
    7. {
    8. for(i = p->x; i < (p->x + 10); i++)
    9. {
    10. for(j = 0; j < p->y; j++)
    11. {
    12. move(j,i);
    13. addch(BLANK);
    14. }
    15. for(j = (p->y+5); j < 25; j++)
    16. {
    17. move(j,i);
    18. addch(BLANK);
    19. }
    20. }
    21. refresh();
    22. p = p->next;
    23. }
    24. }

            2.4 移动管道

    1. void move_pipe()
    2. {
    3. Pipe_list p;
    4. p = head->next;
    5. while(p)
    6. {
    7. p->x--;
    8. p = p->next;
    9. }
    10. }

    3 阶段

            3.1 判断游戏结束:小鸟与管道碰到

    1. void handle(int sig)
    2. {
    3. Pipe_list p, new;
    4. int i,j;
    5. //小鸟自动下落
    6. clear_bird();
    7. g_bird_y++;
    8. show_bird();
    9. //判断游戏是否结束
    10. if((char)inch() == PIPE)
    11. {
    12. set_timer(0);
    13. endwin();
    14. exit(1);
    15. }
    16. //管道自动左移
    17. p = head->next;
    18. if(p->x == 0)
    19. {
    20. head->next = p->next;
    21. for(i = p->x; i < p->x+10; i++)
    22. {
    23. /*上半部分管道*/
    24. for(j=0; jy; j++)
    25. {
    26. move(j,i);
    27. addch(BLANK);
    28. }
    29. /*下半部分管道创建*/
    30. for(j = p->y+5; j < 25; j++)
    31. {
    32. move(j,i);
    33. addch(BLANK);
    34. }
    35. refresh();
    36. }
    37. free(p);
    38. new = (Pipe_list)malloc(sizeof(Pipe_node));
    39. new->x = tail->x + 20;
    40. new->y = rand() % 11 + 5;
    41. new->next = NULL;
    42. tail->next = new;
    43. tail = new;
    44. }
    45. clear_pipe();
    46. move_pipe();
    47. show_pipe();
    48. }

            3.2 循环创建管道

    同上

            3.3 为管道和小鸟添加色彩

    同上

    4 完整代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define BIRD '@'
    8. #define BLANK ' '
    9. #define PIPE '+'
    10. typedef struct _Pipe_node
    11. {
    12. int x;
    13. int y;
    14. struct _Pipe_node * next;
    15. }Pipe_node, *Pipe_list;
    16. int g_bird_y,g_bird_x;
    17. Pipe_list head,tail;
    18. void init_curses();
    19. int set_timer(int ms);
    20. void handle(int sig); //闹钟信号回调处理
    21. void show_bird();
    22. void clear_bird();
    23. void move_bird();
    24. void creat_list();
    25. void show_pipe();
    26. void clear_pipe();
    27. void move_pipe();
    28. int main(int argc,char *argv[])
    29. {
    30. g_bird_y = 15;
    31. g_bird_x = 20;
    32. init_curses();
    33. signal(SIGALRM, handle);
    34. set_timer(300);
    35. srand(time(0)); //随机种子,不然每次开机都是一样的路线
    36. creat_list();
    37. show_bird();
    38. move_bird();
    39. while(1)
    40. {
    41. }
    42. return 0;
    43. }
    44. void init_curses()
    45. {
    46. initscr();
    47. curs_set(0); //禁止光标显示
    48. noecho(); //禁止输入字符显示
    49. keypad(stdscr, 1); //启动功能按键
    50. start_color();
    51. init_pair(1,COLOR_WHITE, COLOR_RED);//小鸟颜色设置
    52. init_pair(2,COLOR_WHITE, COLOR_GREEN);//管道颜色设置
    53. }
    54. int set_timer(int ms)
    55. {
    56. struct itimerval timer;
    57. long t_sec,t_usec;
    58. int ret;
    59. t_sec = ms / 1000; //s
    60. t_usec = (ms % 1000) * 1000;//us
    61. timer.it_value.tv_sec = t_sec;
    62. timer.it_value.tv_usec = t_usec;//首次启动定时值
    63. timer.it_interval.tv_sec = t_sec;
    64. timer.it_interval.tv_usec = t_usec;//定时时间间隔
    65. ret = setitimer(ITIMER_REAL, &timer, NULL);
    66. return ret;
    67. }
    68. void show_bird()
    69. {
    70. attron(COLOR_PAIR(1));
    71. move(g_bird_y,g_bird_x);
    72. addch(BIRD);
    73. refresh();
    74. attroff(COLOR_PAIR(1));
    75. }
    76. void clear_bird()
    77. {
    78. move(g_bird_y,g_bird_x);
    79. addch(BLANK);
    80. refresh();
    81. }
    82. void move_bird()
    83. {
    84. char ch;
    85. while(1)
    86. {
    87. ch = getch();
    88. if(ch == BLANK)
    89. {
    90. clear_bird();
    91. g_bird_y--;
    92. show_bird();
    93. }
    94. }
    95. }
    96. void creat_list()
    97. {
    98. Pipe_list p, new;
    99. int i;
    100. head = (Pipe_list)malloc(sizeof(Pipe_node));
    101. head->next = NULL;
    102. p = head;
    103. for(i = 0; i < 5; i++)
    104. {
    105. new = (Pipe_list)malloc(sizeof(Pipe_node));
    106. new->x = (i + 2) * 20; //20 40 60 80 100
    107. new->y = rand() % 11 + 5; // (0 + 5) <= y < (11 +5) 5-15行 
    108. new->next = NULL;
    109. p->next = new;
    110. p = new;
    111. }
    112. tail = p;
    113. }
    114. void show_pipe()
    115. {
    116. Pipe_list p;
    117. int i,j;
    118. p = head->next;
    119. attron(COLOR_PAIR(2));
    120. while(p != NULL)
    121. {
    122. for(i = p->x; i < (p->x + 10); i++)
    123. {
    124. //管道上半部分
    125. for(j = 0; j < p->y; j++)
    126. {
    127. move(j,i);
    128. addch(PIPE);
    129. }
    130. //管道下半部分
    131. for(j = (p->y+5); j < 25; j++)
    132. {
    133. move(j,i);
    134. addch(PIPE);
    135. }
    136. }
    137. refresh();
    138. p = p->next;
    139. }
    140. attroff(COLOR_PAIR(2));
    141. }
    142. void clear_pipe()
    143. {
    144. Pipe_list p;
    145. int i,j;
    146. p = head->next;
    147. while(p != NULL)
    148. {
    149. for(i = p->x; i < (p->x + 10); i++)
    150. {
    151. for(j = 0; j < p->y; j++)
    152. {
    153. move(j,i);
    154. addch(BLANK);
    155. }
    156. for(j = (p->y+5); j < 25; j++)
    157. {
    158. move(j,i);
    159. addch(BLANK);
    160. }
    161. }
    162. refresh();
    163. p = p->next;
    164. }
    165. }
    166. void move_pipe()
    167. {
    168. Pipe_list p;
    169. p = head->next;
    170. while(p)
    171. {
    172. p->x--;
    173. p = p->next;
    174. }
    175. }
    176. void handle(int sig)
    177. {
    178. Pipe_list p, new;
    179. int i,j;
    180. //小鸟自动下落
    181. clear_bird();
    182. g_bird_y++;
    183. show_bird();
    184. //判断游戏是否结束
    185. if((char)inch() == PIPE)
    186. {
    187. set_timer(0);
    188. endwin();
    189. exit(1);
    190. }
    191. //管道自动左移
    192. p = head->next;
    193. if(p->x == 0)
    194. {
    195. head->next = p->next;
    196. for(i = p->x; i < p->x+10; i++)
    197. {
    198. /*上半部分管道*/
    199. for(j=0; jy; j++)
    200. {
    201. move(j,i);
    202. addch(BLANK);
    203. }
    204. /*下半部分管道创建*/
    205. for(j = p->y+5; j < 25; j++)
    206. {
    207. move(j,i);
    208. addch(BLANK);
    209. }
    210. refresh();
    211. }
    212. free(p);
    213. new = (Pipe_list)malloc(sizeof(Pipe_node));
    214. new->x = tail->x + 20;
    215. new->y = rand() % 11 + 5;
    216. new->next = NULL;
    217. tail->next = new;
    218. tail = new;
    219. }
    220. clear_pipe();
    221. move_pipe();
    222. show_pipe();
    223. }

  • 相关阅读:
    使用枚举Enum代替Integer类型
    openGauss学习笔记-61 openGauss 数据库管理-常见主备部署方案
    Android使用setXfermode例子
    FPGA 20个例程篇:13.千兆网口实现ARP通信协议(下)
    开始使用 ELEMENTOR
    [附源码]Python计算机毕业设计Django项目管理系统的专家评审模块
    格力、美的、海尔“减震”
    [工业自动化-7]:西门子S7-15xxx编程 - PLC主站 - 电源模块
    JVM类加载器(详解)
    MySQL8 间隙锁在11种情况下的锁持有情况分析
  • 原文地址:https://blog.csdn.net/m0_60718520/article/details/133500000