当前位置:   article > 正文

Easyx | 游戏实例:见缝插针_python创建见缝插针小游戏的流程图

python创建见缝插针小游戏的流程图

目录

游戏简介

开始编写

1 预编译

2 初始化

全局变量

初始化函数 

3 插入新的针

检测键盘

新的针

判断游戏失败

CreatePin 函数

4 移动针

5 绘制屏幕

得分

按钮

Draw 函数

主页界面

Main 函数

扩展功能

音效

调整速度

效果截图

完整代码


游戏简介

见缝插针是一个经典的休闲小游戏,操作简单,图形简洁,写起来也十分容易。试试就逝世

本文介绍使用 C++ 的 Easyx图形库 来实现见缝插针。思路如下:

1. 初始化

2. 插入新的针(顺带判断游戏失败)

3. 移动针

4. 绘制屏幕

5. 主页界面

6. 扩展功能:音效、调整速度

因为这个游戏比较简单,所以步骤也比较少。

开始编写

1 预编译

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <math.h>
  4. #include <graphics.h>
  5. #pragma comment(lib, "winmm.lib")
  6. #define HEIGHT 800
  7. #define WIDTH 900
  8. #define PI 3.1415926
  9. #define PIN_L 120.0
  10. #define RADIO 120

stdio.h                                 用 sprintf_s 函数进行格式化字符数组;

conio.h                                用来接受用户键盘输入;

math.h                                 调用 sin 和 cos 函数计算针末端的坐标;

graphics.h                           EasyX 图形库的头文件;

pragma                                这行指令用于加载播放音乐的静态库;

HEIGHT , WIDTH              分别表示窗口的高和宽;

PI                                          表示圆周率的常量;

PIN_L                                   表示针的长度(用小数是因为它要和小数运算);

RADIO                                  表示圆的半径。

2 初始化

全局变量

  1. float pin_angle[1000];
  2. int pin_num = 0;
  3. float speed = PI / 360;

pin_angle              所有针的角度;

pin_num                针的数量;

speed                     旋转速度。

初始化函数 

每一局游戏开始的时候调用就行了

  1. void Init()
  2. {
  3. pin_num = 0;
  4. speed = PI / 360;
  5. }

3 插入新的针

检测键盘

利用 _kbhit()_getch() 函数检测用户是否按下了空格键 (speed != 0 是判断游戏有没有结束)

  1. if (_kbhit() && speed != 0)
  2. {
  3. char input = _getch();
  4. if (input == ' ')
  5. {
  6. // 按下空格键
  7. }
  8. }

新的针

把这根针的角度设为 PI

  1. // 增加一根针
  2. pin_num++;
  3. pin_angle[pin_num - 1] = PI;

判断游戏失败

简单说,就是判断新的针跟任何其他针的角度差是否小于一定的值,这里的标准是 PI / 40

  1. // 是否重合
  2. for (int i = 0; i < pin_num - 1; i++)
  3. {
  4. if (absent(pin_angle[i], pin_angle[pin_num - 1]) < (PI / 40))
  5. {
  6. speed = 0;
  7. return;
  8. }
  9. }

 这里的 absent 函数需要自己定义,因为角度都是浮点数类型,所以不能用 abs 函数取差。

  1. / 取差的绝对值
  2. float absent(float a, float b)
  3. {
  4. if (a > b) return a - b;
  5. else return b - a;
  6. }

CreatePin 函数

  1. // 发射针
  2. void CreatePin()
  3. {
  4. if (_kbhit() && speed != 0)
  5. {
  6. char input = _getch();
  7. if (input == ' ')
  8. {
  9. // 增加一根针
  10. pin_num++;
  11. pin_angle[pin_num - 1] = PI;
  12. // 是否重合
  13. for (int i = 0; i < pin_num - 1; i++)
  14. {
  15. if (absent(pin_angle[i], pin_angle[pin_num - 1]) < (PI / 40))
  16. {
  17. speed = 0;
  18. return;
  19. }
  20. }
  21. }
  22. }
  23. }

4 移动针

很简单,每根针的角度增加速度,如果转了一圈,角度重新归零。

  1. // 移动针
  2. void MovePin()
  3. {
  4. for (int i = 0; i < pin_num; i++)
  5. {
  6. pin_angle[i] += speed;
  7. if (pin_angle[i] > 2 * PI)
  8. {
  9. pin_angle[i] -= 2 * PI;
  10. }
  11. }
  12. }

5 绘制屏幕

直接上重点——

endx, endy 所表示的量如图,是直角三角形的直角边。

根据三角几何:

endy = sin(角度) (邻边除以斜边) × 斜边

endx = cos(角度) (对边除以斜边) × 斜边

然后再根据坐标绘制线

  1. // 针
  2. setlinecolor(RGB(20, 130, 255));
  3. line(0, HEIGHT / 2, PIN_L, HEIGHT / 2);
  4. for (int i = 0; i < pin_num; i++)
  5. {
  6. float endx = (PIN_L + RADIO) * cos(-pin_angle[i]) + WIDTH / 2;
  7. float endy = (PIN_L + RADIO) * sin(-pin_angle[i]) + HEIGHT / 2;
  8. setlinecolor(RGB(20, 130, 255));
  9. setfillcolor(RGB(20, 130, 255));
  10. if (i == pin_num - 1)
  11. {
  12. setlinecolor(RED);
  13. setfillcolor(RED);
  14. }
  15. line(WIDTH / 2, HEIGHT / 2, endx, endy);
  16. fillcircle(endx, endy, 10);
  17. }

其实真的绘制并不复杂,只需要亿点数学知识。

没什么好说的……

  1. // 圆
  2. setlinecolor(RGB(20, 130, 255));
  3. setfillcolor(RGB(70, 180, 255));
  4. setlinestyle(PS_SOLID, 3);
  5. fillcircle(WIDTH / 2, HEIGHT / 2, RADIO);

得分

这里要用一个函数:sprintf_s

它的作用就是格式化输出一串东西,只不过是打印到字符数组里面,跟 printf 一个样。

  1. // 得分
  2. char text[20];
  3. sprintf_s(text, "%d", pin_num);
  4. setbkcolor(RGB(70, 180, 255));
  5. settextcolor(WHITE);
  6. settextstyle(50, 20, "宋体");
  7. outtextxy(WIDTH / 2 - 20, HEIGHT / 2 - 15, text);

按钮

我在游戏界面设置了两个按钮,分别是 返回主页退出游戏 。

实现方法:

1. 画出长方形以及文字;

2. 检测鼠标按下并且坐标在按钮范围中。

在绘制屏幕的这一部分,只需要实现第一步就行了。

  1. // 按钮
  2. setlinecolor(RGB(20, 130, 255));
  3. roundrect(180, 10, 290, 60, 10, 10);
  4. settextstyle(30, 13, "楷体");
  5. outtextxy(185, 20, "返回主页");
  6. roundrect(300, 10, 410, 60, 10, 10);
  7. outtextxy(305, 20, "退出游戏");

Draw 函数

  1. void Draw()
  2. {
  3. // 针
  4. setlinecolor(RGB(20, 130, 255));
  5. line(0, HEIGHT / 2, PIN_L, HEIGHT / 2);
  6. for (int i = 0; i < pin_num; i++)
  7. {
  8. float endx = (PIN_L + RADIO) * cos(-pin_angle[i]) + WIDTH / 2;
  9. float endy = (PIN_L + RADIO) * sin(-pin_angle[i]) + HEIGHT / 2;
  10. setlinecolor(RGB(20, 130, 255));
  11. setfillcolor(RGB(20, 130, 255));
  12. if (i == pin_num - 1)
  13. {
  14. setlinecolor(RED);
  15. setfillcolor(RED);
  16. }
  17. line(WIDTH / 2, HEIGHT / 2, endx, endy);
  18. fillcircle(endx, endy, 10);
  19. }
  20. // 圆
  21. setlinecolor(RGB(20, 130, 255));
  22. setfillcolor(RGB(70, 180, 255));
  23. setlinestyle(PS_SOLID, 3);
  24. fillcircle(WIDTH / 2, HEIGHT / 2, RADIO);
  25. // 得分
  26. char text[20];
  27. sprintf_s(text, "%d", pin_num);
  28. setbkcolor(RGB(70, 180, 255));
  29. settextcolor(WHITE);
  30. settextstyle(50, 20, "宋体");
  31. outtextxy(WIDTH / 2 - 20, HEIGHT / 2 - 15, text);
  32. // 标题
  33. settextcolor(RGB(20, 130, 255));
  34. setbkcolor(RGB(150, 230, 255));
  35. settextstyle(45, 20, "隶书");
  36. outtextxy(10, 10, "见缝插针");
  37. // 按钮
  38. setlinecolor(RGB(20, 130, 255));
  39. roundrect(180, 10, 290, 60, 10, 10);
  40. settextstyle(30, 13, "楷体");
  41. outtextxy(185, 20, "返回主页");
  42. roundrect(300, 10, 410, 60, 10, 10);
  43. outtextxy(305, 20, "退出游戏");
  44. }

主页界面

显示一行字 “见缝插针” ,再放两个按钮。

  1. // 主页
  2. void Home()
  3. {
  4. BeginBatchDraw();
  5. while (true)
  6. {
  7. setbkcolor(RGB(150, 230, 255));
  8. cleardevice();
  9. settextcolor(RGB(20, 130, 255));
  10. settextstyle(130, 55, "隶书");
  11. outtextxy(230, 150, "见缝插针");
  12. setlinecolor(RGB(20, 130, 255));
  13. setlinestyle(PS_SOLID, 3);
  14. roundrect(350, 350, 550, 420, 10, 10);
  15. settextstyle(45, 20, "楷体");
  16. outtextxy(370, 360, "开始游戏");
  17. roundrect(350, 460, 550, 530, 10, 10);
  18. outtextxy(370, 470, "退出游戏");
  19. MOUSEMSG msg = GetMouseMsg();
  20. if (msg.uMsg == WM_LBUTTONDOWN)
  21. {
  22. if (msg.x >= 350 && msg.x <= 550)
  23. {
  24. if (msg.y >= 350 && msg.y <= 420)
  25. {
  26. break;
  27. }
  28. if (msg.y >= 460 && msg.y <= 530)
  29. {
  30. closegraph();
  31. exit(0);
  32. }
  33. }
  34. }
  35. FlushBatchDraw();
  36. }
  37. EndBatchDraw();
  38. }

Main 函数

  1. int main()
  2. {
  3. initgraph(WIDTH, HEIGHT);
  4. while (true)
  5. {
  6. Home();
  7. Init();
  8. BeginBatchDraw();
  9. while (true)
  10. {
  11. setbkcolor(RGB(150, 230, 255));
  12. cleardevice();
  13. CreatePin();
  14. MovePin();
  15. Draw();
  16. if (MouseHit())
  17. {
  18. MOUSEMSG msg = GetMouseMsg();
  19. if (msg.uMsg == WM_LBUTTONDOWN)
  20. {
  21. if (msg.y >= 10 && msg.y <= 60)
  22. {
  23. if (msg.x >= 180 && msg.x <= 290)
  24. {
  25. break;
  26. }
  27. if (msg.x >= 300 && msg.x <= 410)
  28. {
  29. closegraph();
  30. exit(0);
  31. }
  32. }
  33. }
  34. }
  35. FlushBatchDraw();
  36. Sleep(10);
  37. if (speed == 0)
  38. {
  39. break;
  40. }
  41. }
  42. EndBatchDraw();
  43. }
  44. return 0;
  45. }

扩展功能

音效

上一篇文章我讲过,这里我懒得讲了

ready go音效_站长素材ready go音效_站长素材icon-default.png?t=N7T8https://sc.chinaz.com/yinxiao/150112584240.htmgame over游戏声_站长素材game over游戏声_站长素材icon-default.png?t=N7T8https://sc.chinaz.com/yinxiao/130130363410.htm speed == 0 判断处加入:

  1. PlaySound(".\\Game Over.wav", NULL, SND_ASYNC | SND_FILENAME);
  2. Sleep(1000);

Init 函数调用的后面,即游戏开始前,加入:

  1. cleardevice();
  2. Draw();
  3. PlaySound(".\\Ready Go.wav", NULL, SND_ASYNC | SND_FILENAME);
  4. Sleep(1000);

调整速度

根据得分,速度不断增加

  1. // 调整速度
  2. void ChangeSpeed()
  3. {
  4. if (speed == 0) return;
  5. if (pin_num <= 10) speed = PI / 360;
  6. else if (pin_num <= 30) speed = PI / 240;
  7. else if (pin_num <= 50) speed = PI / 180;
  8. else if (pin_num <= 70) speed = PI / 120;
  9. else if (pin_num <= 100) speed = PI / 60;
  10. else speed = PI / 50;
  11. }

文章最后有完整代码!

效果截图

完整代码

  1. /*
  2. * 项目名称:见缝插针
  3. * 开发环境:vs2022 + Easyx
  4. * 作者:轩
  5. * 代码长度:232 行
  6. * 完成时间:2023.1.8
  7. * 用时:2 小时
  8. */
  9. #include <stdio.h>
  10. #include <conio.h>
  11. #include <math.h>
  12. #include <graphics.h>
  13. #pragma comment(lib, "winmm.lib")
  14. #define HEIGHT 800
  15. #define WIDTH 900
  16. #define PI 3.1415926
  17. #define PIN_L 120.0
  18. #define RADIO 120
  19. float pin_angle[1000];
  20. int pin_num = 0;
  21. float speed = PI / 360;
  22. // 取差的绝对值
  23. float absent(float a, float b)
  24. {
  25. if (a > b) return a - b;
  26. else return b - a;
  27. }
  28. // 主页
  29. void Home()
  30. {
  31. BeginBatchDraw();
  32. while (true)
  33. {
  34. setbkcolor(RGB(150, 230, 255));
  35. cleardevice();
  36. settextcolor(RGB(20, 130, 255));
  37. settextstyle(130, 55, "隶书");
  38. outtextxy(230, 150, "见缝插针");
  39. setlinecolor(RGB(20, 130, 255));
  40. setlinestyle(PS_SOLID, 3);
  41. roundrect(350, 350, 550, 420, 10, 10);
  42. settextstyle(45, 20, "楷体");
  43. outtextxy(370, 360, "开始游戏");
  44. roundrect(350, 460, 550, 530, 10, 10);
  45. outtextxy(370, 470, "退出游戏");
  46. MOUSEMSG msg = GetMouseMsg();
  47. if (msg.uMsg == WM_LBUTTONDOWN)
  48. {
  49. if (msg.x >= 350 && msg.x <= 550)
  50. {
  51. if (msg.y >= 350 && msg.y <= 420)
  52. {
  53. break;
  54. }
  55. if (msg.y >= 460 && msg.y <= 530)
  56. {
  57. closegraph();
  58. exit(0);
  59. }
  60. }
  61. }
  62. FlushBatchDraw();
  63. }
  64. EndBatchDraw();
  65. }
  66. void Init()
  67. {
  68. pin_num = 0;
  69. speed = PI / 360;
  70. }
  71. // 调整速度
  72. void ChangeSpeed()
  73. {
  74. if (speed == 0) return;
  75. if (pin_num <= 10) speed = PI / 360;
  76. else if (pin_num <= 30) speed = PI / 240;
  77. else if (pin_num <= 50) speed = PI / 180;
  78. else if (pin_num <= 70) speed = PI / 120;
  79. else if (pin_num <= 100) speed = PI / 60;
  80. else speed = PI / 50;
  81. }
  82. // 移动针
  83. void MovePin()
  84. {
  85. for (int i = 0; i < pin_num; i++)
  86. {
  87. pin_angle[i] += speed;
  88. if (pin_angle[i] > 2 * PI)
  89. {
  90. pin_angle[i] -= 2 * PI;
  91. }
  92. }
  93. }
  94. // 绘制
  95. void Draw()
  96. {
  97. // 针
  98. setlinecolor(RGB(20, 130, 255));
  99. line(0, HEIGHT / 2, PIN_L, HEIGHT / 2);
  100. for (int i = 0; i < pin_num; i++)
  101. {
  102. float endx = (PIN_L + RADIO) * cos(-pin_angle[i]) + WIDTH / 2;
  103. float endy = (PIN_L + RADIO) * sin(-pin_angle[i]) + HEIGHT / 2;
  104. setlinecolor(RGB(20, 130, 255));
  105. setfillcolor(RGB(20, 130, 255));
  106. if (i == pin_num - 1)
  107. {
  108. setlinecolor(RED);
  109. setfillcolor(RED);
  110. }
  111. line(WIDTH / 2, HEIGHT / 2, endx, endy);
  112. fillcircle(endx, endy, 10);
  113. }
  114. // 圆
  115. setlinecolor(RGB(20, 130, 255));
  116. setfillcolor(RGB(70, 180, 255));
  117. setlinestyle(PS_SOLID, 3);
  118. fillcircle(WIDTH / 2, HEIGHT / 2, RADIO);
  119. // 得分
  120. char text[20];
  121. sprintf_s(text, "%d", pin_num);
  122. setbkcolor(RGB(70, 180, 255));
  123. settextcolor(WHITE);
  124. settextstyle(50, 20, "宋体");
  125. outtextxy(WIDTH / 2 - 20, HEIGHT / 2 - 15, text);
  126. // 标题
  127. settextcolor(RGB(20, 130, 255));
  128. setbkcolor(RGB(150, 230, 255));
  129. settextstyle(45, 20, "隶书");
  130. outtextxy(10, 10, "见缝插针");
  131. // 按钮
  132. setlinecolor(RGB(20, 130, 255));
  133. roundrect(180, 10, 290, 60, 10, 10);
  134. settextstyle(30, 13, "楷体");
  135. outtextxy(185, 20, "返回主页");
  136. roundrect(300, 10, 410, 60, 10, 10);
  137. outtextxy(305, 20, "退出游戏");
  138. }
  139. // 发射针
  140. void CreatePin()
  141. {
  142. if (_kbhit() && speed != 0)
  143. {
  144. char input = _getch();
  145. if (input == ' ')
  146. {
  147. // 增加一根针
  148. pin_num++;
  149. pin_angle[pin_num - 1] = PI;
  150. // 是否重合
  151. for (int i = 0; i < pin_num - 1; i++)
  152. {
  153. if (absent(pin_angle[i], pin_angle[pin_num - 1]) < (PI / 40))
  154. {
  155. speed = 0;
  156. return;
  157. }
  158. }
  159. }
  160. }
  161. }
  162. int main()
  163. {
  164. initgraph(WIDTH, HEIGHT);
  165. while (true)
  166. {
  167. Home();
  168. Init();
  169. cleardevice();
  170. Draw();
  171. PlaySound(".\\Ready Go.wav", NULL, SND_ASYNC | SND_FILENAME);
  172. Sleep(1000);
  173. BeginBatchDraw();
  174. while (true)
  175. {
  176. setbkcolor(RGB(150, 230, 255));
  177. cleardevice();
  178. CreatePin();
  179. MovePin();
  180. ChangeSpeed();
  181. Draw();
  182. if (MouseHit())
  183. {
  184. MOUSEMSG msg = GetMouseMsg();
  185. if (msg.uMsg == WM_LBUTTONDOWN)
  186. {
  187. if (msg.y >= 10 && msg.y <= 60)
  188. {
  189. if (msg.x >= 180 && msg.x <= 290)
  190. {
  191. break;
  192. }
  193. if (msg.x >= 300 && msg.x <= 410)
  194. {
  195. closegraph();
  196. exit(0);
  197. }
  198. }
  199. }
  200. }
  201. FlushBatchDraw();
  202. Sleep(10);
  203. if (speed == 0)
  204. {
  205. PlaySound(".\\Game Over.wav", NULL, SND_ASYNC | SND_FILENAME);
  206. Sleep(1000);
  207. break;
  208. }
  209. }
  210. EndBatchDraw();
  211. }
  212. return 0;
  213. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/47887
推荐阅读
相关标签
  

闽ICP备14008679号