No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 

207 líneas
4.7 KiB

  1. /*
  2. * ttyvaders Textmode shoot'em up
  3. * Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include "config.h"
  23. #include <stdlib.h>
  24. #include "common.h"
  25. /* Init tunnel */
  26. tunnel * create_tunnel(game *g, int w, int h)
  27. {
  28. int i;
  29. tunnel *t = malloc(sizeof(tunnel));
  30. if(t == NULL)
  31. exit(1);
  32. t->left = malloc(h*sizeof(int));
  33. if(t->left == NULL)
  34. exit(1);
  35. t->right = malloc(h*sizeof(int));
  36. if(t->right == NULL)
  37. exit(1);
  38. t->w = w;
  39. t->h = h;
  40. if(t->w >= g->w)
  41. {
  42. for(i = 0; i < g->h; i++)
  43. {
  44. t->left[i] = -10;
  45. t->right[i] = g->w + 10;
  46. }
  47. }
  48. else
  49. {
  50. t->left[0] = (g->w - w) / 2;
  51. t->right[0] = (g->w + w) / 2;
  52. /* Yeah, sub-efficient, but less code to do :-) */
  53. for(i = 0; i < g->h; i++)
  54. {
  55. update_tunnel(g, t);
  56. }
  57. }
  58. return t;
  59. }
  60. void free_tunnel(tunnel *t)
  61. {
  62. free(t->left);
  63. free(t->right);
  64. free(t);
  65. }
  66. void draw_tunnel(game *g, tunnel *t)
  67. {
  68. int i, j;
  69. char c;
  70. caca_set_color(EE_GREEN);
  71. /* Left border */
  72. for(i = 0; i < g->h ; i++)
  73. {
  74. if(t->left[i] <= -10)
  75. continue;
  76. if(i + 1 == g->h || t->left[i] > t->left[i+1])
  77. c = (i == 0 || t->left[i] > t->left[i-1]) ? '>' : '/';
  78. else
  79. c = (i == 0 || t->left[i] > t->left[i-1]) ? '\\' : '<';
  80. caca_putchar(t->left[i] + 1, i, c);
  81. if(i + 1 < g->h)
  82. for(j = 1; j < t->left[i+1] - t->left[i]; j++)
  83. caca_putchar(t->left[i] + j + 1, i, '_');
  84. }
  85. /* Right border */
  86. for(i = 0; i < g->h ; i++)
  87. {
  88. if(t->right[i] >= g->w + 10)
  89. continue;
  90. if(i + 1 == g->h || t->right[i] > t->right[i+1])
  91. c = (i == 0 || t->right[i] > t->right[i-1]) ? '>' : '/';
  92. else
  93. c = (i == 0 || t->right[i] > t->right[i-1]) ? '\\' : '<';
  94. if(i + 1 < g->h)
  95. for(j = 1; j < t->right[i] - t->right[i+1]; j++)
  96. caca_putchar(t->right[i+1] + j - 1, i, '_');
  97. caca_putchar(t->right[i] - 1, i, c);
  98. }
  99. caca_set_color(EE_RED);
  100. /* Left concrete */
  101. for(i = 0; i < g->h ; i++)
  102. for(j = 0 ; j <= t->left[i]; j++)
  103. caca_putchar(j, i, '#');
  104. /* Right concrete */
  105. for(i = 0; i < g->h ; i++)
  106. for(j = t->right[i] ; j < g->w ; j++)
  107. caca_putchar(j, i, '#');
  108. }
  109. void update_tunnel(game *g, tunnel *t)
  110. {
  111. static int const delta[] = { -3, -2, -1, 1, 2, 3 };
  112. int i,j,k;
  113. /* Slide tunnel one block vertically */
  114. for(i = t->h - 1; i--;)
  115. {
  116. t->left[i+1] = t->left[i];
  117. t->right[i+1] = t->right[i];
  118. }
  119. /* Generate new values */
  120. i = delta[caca_rand(0,5)];
  121. j = delta[caca_rand(0,5)];
  122. /* Check in which direction we need to alter tunnel */
  123. if(t->right[1] - t->left[1] < t->w)
  124. {
  125. /* Not wide enough, make sure i <= j */
  126. if(i > j)
  127. {
  128. k = j; j = i; i = k;
  129. }
  130. }
  131. else if(t->right[1] - t->left[1] - 2 > t->w)
  132. {
  133. /* Too wide, make sure i >= j */
  134. if(i < j)
  135. {
  136. k = j; j = i; i = k;
  137. }
  138. }
  139. else
  140. {
  141. /* No need to mess with i and j: width is OK */
  142. }
  143. /* If width doesn't exceed game size, update coords */
  144. if(t->w <= g->w || t->right[1] - t->left[1] < t->w)
  145. {
  146. t->left[0] = t->left[1] + i;
  147. t->right[0] = t->right[1] + j;
  148. }
  149. else
  150. {
  151. t->left[0] = -10;
  152. t->right[0] = g->w + 10;
  153. }
  154. if(t->w > g->w)
  155. {
  156. if(t->left[0] < 0 && t->right[0] < g->w - 2)
  157. {
  158. t->left[0] = t->left[1] + 1;
  159. }
  160. if(t->left[0] > 1 && t->right[0] > g->w - 1)
  161. {
  162. t->right[0] = t->right[1] - 1;
  163. }
  164. }
  165. else
  166. {
  167. if(t->left[0] < 0)
  168. {
  169. t->left[0] = t->left[1] + 1;
  170. }
  171. if(t->right[0] > g->w - 1)
  172. {
  173. t->right[0] = t->right[1] - 1;
  174. }
  175. }
  176. }