demo08.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #define ZGL_IMPORT
  2. #include <math.h>
  3. #include <memory.h>
  4. #include "zglHeader.h"
  5. typedef struct
  6. {
  7. // RU: Обязательная часть нового типа спрайта.
  8. // EN: New type should start with this.
  9. ZGLTSPRITE2D
  10. // RU: Новые параметры.
  11. // EN: New params.
  12. zglTPoint2D Speed;
  13. } zglTMiku, *zglPMiku;
  14. zglPFont fntMain;
  15. zglPTexture texLogo;
  16. zglPTexture texMiku;
  17. int time;
  18. zglTSEngine2D sengine2d;
  19. char resource[256];
  20. char* GetResource( char* FileName )
  21. {
  22. #ifndef __MACOSX__
  23. sprintf_s( resource, "../data/%s", FileName );
  24. return resource;
  25. #else
  26. return FileName;
  27. #endif
  28. }
  29. // Miku
  30. void MikuInit( zglPMiku Miku )
  31. {
  32. Miku->X = 800.0f + rand() % 800;
  33. Miku->Y = (float)( rand() % ( 600 - 128 ) );
  34. // RU: Задаем скорость движения.
  35. // EN: Set the moving speed.
  36. Miku->Speed.X = -( rand() % 10 ) / 5.0f - 0.5f;
  37. Miku->Speed.Y = ( rand() % 10 - 5 ) / 5.0f;
  38. }
  39. void MikuDraw( zglPMiku Miku )
  40. {
  41. asprite2d_Draw( Miku->Texture, Miku->X, Miku->Y, Miku->W, Miku->H, Miku->Angle, (ushort)Miku->Frame, Miku->Alpha, Miku->FxFlags );
  42. }
  43. void MikuProc( zglPMiku Miku )
  44. {
  45. Miku->X += Miku->Speed.X;
  46. Miku->Y += Miku->Speed.Y;
  47. Miku->Frame += ( abs( Miku->Speed.X ) + abs( Miku->Speed.Y ) ) / 25.0f;
  48. if ( Miku->Frame > 8 )
  49. Miku->Frame = 1;
  50. // RU: Если спрайт выходит за пределы по X, сразу же удаляем его.
  51. // EN: Delete the sprite if it goes beyond X.
  52. if ( Miku->X < -128 ) sengine2d_DelSprite( Miku->ID );
  53. // RU: Если спрайт выходит за пределы по Y, ставим его в очередь на удаление.
  54. // EN: Add sprite to queue for delete if it goes beyond Y.
  55. if ( Miku->Y < -128 )
  56. Miku->Destroy = TRUE;
  57. if ( Miku->Y > 600 )
  58. Miku->Destroy = TRUE;
  59. }
  60. void MikuFree( zglPMiku Miku )
  61. {
  62. }
  63. // RU: Добавить 100 спрайтов.
  64. // EN: Add 100 sprites.
  65. void AddMiku()
  66. {
  67. // RU: При добавлении спрайта в менеджер спрайтов указывается текстура, слой(положение по Z) и указатели на основные функции - Инициализация, Рендер, Обработка и Уничтожение.
  68. // EN: For adding sprite to sprite engine must be set next parameters: texture, layer(Z-coordinate) and pointers to Initialization, Render, Process and Destroy functions.
  69. for ( int i = 1; i <= 100; i++ )
  70. sengine2d_AddCustom( texMiku, sizeof( zglTMiku ), rand() % 10, (zglSpriteFunc)&MikuInit, (zglSpriteFunc)&MikuDraw, (zglSpriteFunc)&MikuProc, (zglSpriteFunc)&MikuFree );
  71. }
  72. // RU: Удалить 100 спрайтов.
  73. // EN: Delete 100 sprites.
  74. void DelMiku()
  75. {
  76. if ( sengine2d.Count < 100 )
  77. return;
  78. // RU: Удалим 100 спрайтов со случайным ID.
  79. // EN: Delete 100 sprites with random ID.
  80. for ( int i = 1; i <= 100; i++ )
  81. sengine2d_DelSprite( rand() % sengine2d.Count );
  82. }
  83. void Init()
  84. {
  85. texLogo = tex_LoadFromFile( GetResource( "zengl.png" ), TEX_NO_COLORKEY, TEX_DEFAULT_2D );
  86. texMiku = tex_LoadFromFile( GetResource( "miku.png" ), TEX_NO_COLORKEY, TEX_DEFAULT_2D );
  87. tex_SetFrameSize( &texMiku, 128, 128 );
  88. // RU: Устанавливаем текущим менеджером спрайтов свой.
  89. // EN: Set own sprite engine as current.
  90. sengine2d_Set( &sengine2d );
  91. // RU: Создадим 1000 спрайтов Miku-chan :)
  92. // EN: Create 1000 sprites of Miku-chan :)
  93. for ( int i = 0; i < 10; i++ )
  94. AddMiku();
  95. fntMain = font_LoadFromFile( GetResource( "font.zfi" ) );
  96. }
  97. void Draw()
  98. {
  99. batch2d_Begin();
  100. // RU: Рисуем все спрайты находящиеся в текущем спрайтовом менеджере.
  101. // EN: Render all sprites contained in current sprite engine.
  102. if ( time > 255 )
  103. sengine2d_Draw();
  104. if ( time <= 255 )
  105. ssprite2d_Draw( texLogo, 400 - 256, 300 - 128, 512, 256, 0, time, FX_BLEND );
  106. else if ( time < 510 )
  107. {
  108. pr2d_Rect( 0, 0, 800, 600, 0x000000, 510 - time, PR2D_FILL );
  109. ssprite2d_Draw( texLogo, 400 - 256, 300 - 128, 512, 256, 0, 510 - time, FX_BLEND );
  110. }
  111. if ( time > 255 )
  112. {
  113. char text[256];
  114. pr2d_Rect( 0, 0, 256, 64, 0x000000, 200, PR2D_FILL );
  115. sprintf_s( text, "FPS: %i", (int)zgl_Get( RENDER_FPS ) );
  116. text_Draw( fntMain, 0, 0, text, 0 );
  117. sprintf_s( text, "Sprites: %i", sengine2d.Count );
  118. text_Draw( fntMain, 0, 20, text, 0 );
  119. text_Draw( fntMain, 0, 40, "Up/Down - Add/Delete Miku :)", 0 );
  120. }
  121. batch2d_End();
  122. }
  123. void Timer()
  124. {
  125. time +=2;
  126. // RU: Выполняем обработку всех спрайтов в текущем спрайтовом менеджере.
  127. // EN: Process all sprites contained in current sprite engine.
  128. sengine2d_Proc();
  129. // RU: По нажатию пробела очистить все спрайты.
  130. // EN: Delete all sprites if space was pressed.
  131. if ( key_Press( K_SPACE ) ) sengine2d_ClearAll();
  132. if ( key_Press( K_UP ) ) AddMiku();
  133. if ( key_Press( K_DOWN ) ) DelMiku();
  134. if ( key_Press( K_ESCAPE ) ) zgl_Exit();
  135. key_ClearState();
  136. }
  137. void Quit()
  138. {
  139. // RU: Очищаем память от созданных спрайтов.
  140. // EN: Free allocated memory for sprites.
  141. sengine2d_Set( &sengine2d );
  142. sengine2d_ClearAll();
  143. }
  144. int main()
  145. {
  146. if ( !zglLoad( libZenGL ) ) return 0;
  147. srand( 0xDeaDBeeF );
  148. timer_Add( (void*)&Timer, 16, FALSE, NULL );
  149. timer_Add( (void*)&AddMiku, 1000, FALSE, NULL );
  150. zgl_Reg( SYS_LOAD, (void*)&Init );
  151. zgl_Reg( SYS_DRAW, (void*)&Draw );
  152. zgl_Reg( SYS_EXIT, (void*)&Quit );
  153. wnd_SetCaption( "08 - Sprite Engine" );
  154. wnd_ShowCursor( TRUE );
  155. scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
  156. zgl_Init( 0, 0 );
  157. zglFree();
  158. return 0;
  159. }