demo16.pas 6.8 KB

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