demo16.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. program demo16;
  2. // RU: В этом файле конфигурации содержится "опция" USE_CHIPMUNK_STATIC для статической компиляции с Chipmunk
  3. // EN: This file contains "option" USE_CHIPMUNK_STATIC for static compilation with Chipmunk
  4. {$I zglCustomConfig.cfg}
  5. uses
  6. {$IFDEF UNIX}
  7. cthreads,
  8. {$ENDIF}
  9. zglChipmunk,
  10. {$IFDEF USE_ZENGL_STATIC}
  11. zgl_screen,
  12. zgl_window,
  13. zgl_timers,
  14. zgl_keyboard,
  15. zgl_mouse,
  16. zgl_textures,
  17. zgl_textures_png,
  18. zgl_render_2d,
  19. zgl_font,
  20. zgl_text,
  21. zgl_primitives_2d,
  22. zgl_math_2d,
  23. zgl_utils
  24. {$ELSE}
  25. zglHeader
  26. {$ENDIF}
  27. ;
  28. var
  29. dirRes : UTF8String {$IFNDEF MACOSX} = '../data/' {$ENDIF};
  30. fntMain : Byte;
  31. space : PcpSpace;
  32. bCount : Integer;
  33. Bodies : array of PcpBody;
  34. Shapes : array of PcpShape;
  35. TimePhisics: Byte;
  36. // RU: Добавить объект "шар"
  37. // x, y - координаты центра
  38. // mass - масса
  39. // r - радиус
  40. // e - коэффициент эластичности
  41. // u - коэффициент трения
  42. //
  43. // EN: Add new object "ball"
  44. // x, y - coordinates
  45. // mass - mass
  46. // r - radius
  47. // e - coefficient of restitution. (elasticity)
  48. // u - coefficient of friction
  49. procedure cpAddBall(x, y, r, mass, e, u : cpFloat);
  50. begin
  51. INC(bCount);
  52. SetLength(Bodies, bCount);
  53. SetLength(Shapes, bCount);
  54. Bodies[bCount - 1] := cpBodyNew(mass, cpMomentForCircle(mass, 0, r, cpvzero));
  55. Bodies[bCount - 1]^.p := cpv(x, y);
  56. cpSpaceAddBody(space, Bodies[bCount - 1]);
  57. Shapes[bCount - 1] := cpCircleShapeNew(Bodies[bCount - 1], r, cpvzero);
  58. Shapes[bCount - 1]^.e := e;
  59. Shapes[bCount - 1]^.u := u;
  60. cpSpaceAddShape( space, Shapes[ bCount - 1 ] );
  61. end;
  62. // RU: Добавить объект "коробка"
  63. // Схож с процедурой cpAddBall по аргументам
  64. // x, y - координаты центра
  65. // w, h - ширина и высота
  66. //
  67. // EN: Add bew object "box"
  68. // Arguments are similar to arguments of procedure cpAddBall
  69. // x, y - coordinates of center
  70. // w, h - width and height
  71. procedure cpAddBox(x, y, w, h, mass, e, u : cpFloat);
  72. var
  73. points : array[0..3] of cpVect;
  74. f : cpFloat;
  75. begin
  76. INC(bCount);
  77. SetLength(Bodies, bCount);
  78. SetLength(Shapes, bCount);
  79. points[0].x := - w / 2;
  80. points[0].y := - h / 2;
  81. points[1].x := - w / 2;
  82. points[1].y := h / 2;
  83. points[2].x := w / 2;
  84. points[2].y := h / 2;
  85. points[3].x := w / 2;
  86. points[3].y := - h / 2;
  87. f := cpMomentForPoly(mass, 4, @points[0], cpvzero);
  88. Bodies[bCount - 1] := cpBodyNew(mass, f);
  89. Bodies[bCount - 1]^.p := cpv(x + w / 2, y + h / 2);
  90. cpSpaceAddBody(space, Bodies[bCount - 1]);
  91. Shapes[bCount - 1] := cpPolyShapeNew(Bodies[bCount - 1], 4, @points[0], cpvzero);
  92. Shapes[bCount - 1]^.e := e;
  93. Shapes[bCount - 1]^.u := u;
  94. cpSpaceAddShape(space, Shapes[bCount - 1]);
  95. end;
  96. procedure Init;
  97. var
  98. staticBody : PcpBody;
  99. ground : PcpShape;
  100. e, u : cpFloat;
  101. begin
  102. fntMain := font_LoadFromFile(dirRes + 'font.zfi');
  103. setFontTextScale(15, fntMain);
  104. cpInitChipmunk();
  105. // RU: Создаем новый "мир".
  106. // EN: Create new world.
  107. space := cpSpaceNew();
  108. // RU: Задаем количество итераций обработки(рекомендуется 10).
  109. // EN: Set count of iterations of processing(recommended is 10).
  110. space^.iterations := 10;
  111. space^.elasticIterations := 10;
  112. // RU: Задаем силу гравитации.
  113. // EN: Set the gravity.
  114. space^.gravity := cpv(1, 100);
  115. // RU: Задаем коэффициент "затухания" движения объектов.
  116. // EN: Set the damping for moving of objects.
  117. space^.damping := 0.99;
  118. e := 1;
  119. u := 0.9;
  120. // RU: Создадим статичное "тело".
  121. // EN: Create a static "body".
  122. staticBody := cpBodyNew(INFINITY, INFINITY);
  123. // RU: Добавим три отрезка для ограничения мира. Первый параметр - указатель на созданное тело, два последующих - координаты точек отрезка, последний - толщина отрезка.
  124. // EN: Add three segments for restriction of world. First parameter - pointer of created body, next two - coordinates of segment points, the last one - width of segment.
  125. ground := cpSegmentShapeNew(staticBody, cpv(5, 0), cpv(5, 590), 1);
  126. ground^.e := e;
  127. ground^.u := u;
  128. cpSpaceAddStaticShape(space, ground );
  129. ground := cpSegmentShapeNew(staticBody, cpv(795, 0), cpv(795, 590), 1);
  130. ground^.e := e;
  131. ground^.u := u;
  132. cpSpaceAddStaticShape(space, ground);
  133. ground := cpSegmentShapeNew(staticBody, cpv(0, 590), cpv(800, 590), 1);
  134. ground^.e := e;
  135. ground^.u := u;
  136. cpSpaceAddStaticShape(space, ground);
  137. // RU: Добавим треугольник.
  138. // EN: Add the triangle.
  139. staticBody := cpBodyNew(INFINITY, INFINITY);
  140. ground := cpSegmentShapeNew(staticBody, cpv(400, 300), cpv(200, 350), 1);
  141. ground^.e := e;
  142. ground^.u := u;
  143. cpSpaceAddStaticShape(space, ground);
  144. ground := cpSegmentShapeNew(staticBody, cpv(200, 350), cpv(700, 350), 1);
  145. ground^.e := e;
  146. ground^.u := u;
  147. cpSpaceAddStaticShape(space, ground);
  148. ground := cpSegmentShapeNew(staticBody, cpv(700, 350), cpv(400, 300), 1);
  149. ground^.e := e;
  150. ground^.u := u;
  151. cpSpaceAddStaticShape(space, ground);
  152. end;
  153. procedure Draw;
  154. begin
  155. // batch2d_Begin();
  156. // RU: Рендерим объекты указанного "мира". Второй аргумент функции отвечает за показ точек соприкосновения.
  157. // EN: Render objects for specified "world". Second argument responsible for rendering of collision points.
  158. cpDrawSpace(space, TRUE);
  159. text_Draw(fntMain, 10, 5, 'FPS: ' + u_IntToStr(zgl_Get(RENDER_FPS)));
  160. text_Draw(fntMain, 10, 25, 'Use your mouse: Left Click - box, Right Click - ball');
  161. // batch2d_End();
  162. end;
  163. procedure KeyMouseEvent;
  164. begin
  165. if mBClickCanClick(M_BLEFT_CLICK) Then
  166. cpAddBox(mouseX - 10, mouseY - 10, 48, 32, 1, 0.5, 0.5);
  167. if mBClickCanClick(M_BRIGHT_CLICK) Then
  168. cpAddBall(mouseX, mouseY, 16, 2, 0.5, 0.1);
  169. (* код, который можно использовать, если ZenGL не скомпилированная библиотека.
  170. if (mouseClickCanClick and M_BLEFT_CLICK) > 0 then
  171. cpAddBox(mouse_X() - 10, mouse_Y() - 10, 48, 32, 1, 0.5, 0.5);
  172. *)
  173. end;
  174. procedure Phisics;
  175. begin
  176. cpSpaceStep(space, 1 / zgl_Get(RENDER_FPS));
  177. end;
  178. procedure Quit;
  179. begin
  180. // RU: Очистка объектов и "мира".
  181. // EN: Free objects and "world".
  182. cpSpaceFreeChildren(space);
  183. cpSpaceFree(space);
  184. end;
  185. Begin
  186. randomize();
  187. {$IFNDEF USE_ZENGL_STATIC}
  188. if not zglLoad( libZenGL ) Then exit;
  189. {$ENDIF}
  190. {$IFNDEF USE_CHIPMUNK_STATIC}
  191. if not cpLoad( libChipmunk ) Then exit;
  192. {$ENDIF}
  193. TimePhisics := timer_Add(@Phisics, 16, Start);
  194. zgl_Reg(SYS_EVENTS, @KeyMouseEvent);
  195. zgl_Reg(SYS_LOAD, @Init);
  196. zgl_Reg(SYS_DRAW, @Draw);
  197. zgl_Reg(SYS_EXIT, @Quit);
  198. wnd_SetCaption(utf8_Copy('16 - Physics Simple'));
  199. zgl_Init();
  200. End.