dialogbox.d 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. module dialogs.dialogbox;
  2. import raylib;
  3. import std.string;
  4. import std.stdio;
  5. import std.conv;
  6. import std.uni;
  7. import std.typecons;
  8. import std.algorithm;
  9. int currentPage = 0;
  10. float textDisplayProgress = 0.0f;
  11. bool textFullyDisplayed = false;
  12. void displayDialog(string[] pages, string[] choices, ref int selectedChoice, int choicePage, Font dialogFont,
  13. bool *showDialog, float textSpeed) {
  14. int pagesLength = cast(int)pages.length;
  15. int screenWidth = GetScreenWidth();
  16. int screenHeight = GetScreenHeight();
  17. DrawRectangle(
  18. 0,
  19. screenHeight - screenHeight / 3,
  20. screenWidth,
  21. screenHeight / 3,
  22. Color(20, 20, 20, 220)
  23. );
  24. float marginLeft = screenWidth/6.5f;
  25. float marginRight = screenWidth/6.5f;
  26. float marginTop = screenHeight - screenHeight/3.3f;
  27. float textWidth = screenWidth - marginLeft - marginRight;
  28. float fontSize = 40.0f;
  29. float spacing = 1.0f;
  30. string currentText = pages[currentPage];
  31. int textLength = cast(int)currentText.length;
  32. if (IsKeyPressed(KeyboardKey.KEY_ENTER) && !textFullyDisplayed) {
  33. textDisplayProgress = textLength;
  34. textFullyDisplayed = true;
  35. }
  36. else if (IsKeyPressed(KeyboardKey.KEY_ENTER) && textFullyDisplayed) {
  37. currentPage += 1;
  38. textDisplayProgress = 0.0f;
  39. textFullyDisplayed = false;
  40. }
  41. else if (!textFullyDisplayed) {
  42. textDisplayProgress += textSpeed;
  43. if (textDisplayProgress >= textLength) {
  44. textDisplayProgress = textLength;
  45. textFullyDisplayed = true;
  46. }
  47. }
  48. int charsToShow = cast(int)textDisplayProgress;
  49. string displayedText = currentText[0 .. min(charsToShow, textLength)];
  50. string[] lines;
  51. string remainingText = displayedText;
  52. while (remainingText.length > 0) {
  53. int fitChars = 0;
  54. float width = 0.0f;
  55. while (fitChars < remainingText.length) {
  56. int nextChar = fitChars;
  57. while (nextChar < remainingText.length && !isWhite(remainingText[nextChar])) {
  58. nextChar++;
  59. }
  60. string word = remainingText[fitChars..nextChar];
  61. float wordWidth = MeasureTextEx(dialogFont, word.toStringz(), fontSize, spacing).x;
  62. if (width + wordWidth > textWidth && width > 0) {
  63. break;
  64. }
  65. width += wordWidth;
  66. fitChars = nextChar;
  67. while (fitChars < remainingText.length && isWhite(remainingText[fitChars])) {
  68. width += MeasureTextEx(dialogFont, " ".toStringz(), fontSize, spacing).x;
  69. fitChars++;
  70. }
  71. }
  72. if (fitChars == 0) {
  73. fitChars = 1;
  74. }
  75. lines ~= remainingText[0..fitChars];
  76. remainingText = remainingText[fitChars..$];
  77. }
  78. // Draw each line of text
  79. float lineHeight = MeasureTextEx(dialogFont, "A", fontSize, spacing).y * 1.4;
  80. for (int i = 0; i < lines.length; i++) {
  81. DrawTextEx(
  82. dialogFont,
  83. lines[i].toStringz(),
  84. Vector2(marginLeft, marginTop + i * lineHeight),
  85. fontSize,
  86. spacing,
  87. Colors.WHITE
  88. );
  89. }
  90. if (textFullyDisplayed) {
  91. drawSnakeAnimation(
  92. 0,
  93. screenHeight - screenHeight / 3,
  94. screenWidth,
  95. screenHeight / 3
  96. );
  97. }
  98. if (currentPage == choicePage) {
  99. // Обработка выбора ответа (вверх/вниз)
  100. if (IsKeyPressed(KeyboardKey.KEY_DOWN)) {
  101. selectedChoice = cast(int)((selectedChoice + 1) % choices.length);
  102. }
  103. if (IsKeyPressed(KeyboardKey.KEY_UP)) {
  104. selectedChoice = cast(int)((selectedChoice - 1 + choices.length) % choices.length);
  105. }
  106. for (int i = 0; i < choices.length; i++) {
  107. Color color = (i == selectedChoice) ? Colors.YELLOW : Colors.WHITE;
  108. DrawTextEx(
  109. dialogFont,
  110. toStringz(choices[i]),
  111. Vector2(marginLeft, 60 + marginTop + i * 40),
  112. fontSize,
  113. spacing,
  114. color
  115. );
  116. }
  117. }
  118. if (currentPage >= pagesLength) {
  119. currentPage = 0;
  120. textDisplayProgress = 0.0f;
  121. textFullyDisplayed = false;
  122. pages = [];
  123. *showDialog = false;
  124. return;
  125. }
  126. }
  127. void drawSnakeAnimation(int rectX, int rectY, int rectWidth, int rectHeight) {
  128. static float animTimer = 0.0f;
  129. animTimer += GetFrameTime();
  130. if (animTimer > 0.1f) animTimer = 0.0f;
  131. int animWidth = 300;
  132. int animHeight = 100;
  133. int animX = rectX + rectWidth - animWidth - 20;
  134. int animY = rectY + rectHeight - animHeight - 20;
  135. int cubeSize = 5;
  136. int cubesInRow = 5;
  137. int spacing = 1;
  138. int centerX = animX + animWidth/2 - (cubesInRow*cubeSize + (cubesInRow-1)*spacing)/2;
  139. int centerY = animY + animHeight/2 - (cubesInRow*cubeSize + (cubesInRow-1)*spacing)/2;
  140. for (int y = 0; y < cubesInRow; y++) {
  141. for (int x = 0; x < cubesInRow; x++) {
  142. DrawRectangle(
  143. centerX + x*(cubeSize + spacing),
  144. centerY + y*(cubeSize + spacing),
  145. cubeSize, cubeSize, Color(50, 50, 50, 255)
  146. );
  147. }
  148. }
  149. static int snakePosition = 0;
  150. if (animTimer == 0.0f) snakePosition = (snakePosition + 1) % 16;
  151. Tuple!(int, int)[] snakePath = [
  152. tuple(2, 0), tuple(3, 0), tuple(4, 0), tuple(4, 1),
  153. tuple(4, 2), tuple(4, 3), tuple(4, 4), tuple(3, 4),
  154. tuple(2, 4), tuple(1, 4), tuple(0, 4), tuple(0, 3),
  155. tuple(0, 2), tuple(0, 1), tuple(0, 0), tuple(1, 0)
  156. ];
  157. for (int i = 0; i < snakePath.length; i++) {
  158. int relPos = cast(int)((i + snakePosition) % snakePath.length);
  159. int x = snakePath[relPos][0];
  160. int y = snakePath[relPos][1];
  161. float t = cast(float)i / snakePath.length;
  162. Color cubeColor = Color(0, cast(ubyte)(50 + 70 * (1 - t)), 0, 255);
  163. DrawRectangle(
  164. centerX + x*(cubeSize + spacing),
  165. centerY + y*(cubeSize + spacing),
  166. cubeSize, cubeSize, cubeColor
  167. );
  168. }
  169. }