demo16.pas 7.0 KB

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