Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

235 Zeilen
5.1 KiB

  1. /*
  2. * ttyvaders Textmode shoot'em up
  3. * Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id: tunnel.c,v 1.8 2002/12/23 12:47:36 sam Exp $
  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. t->left = malloc(h*sizeof(int));
  31. t->right = malloc(h*sizeof(int));
  32. t->w = w;
  33. t->h = h;
  34. if( t->w >= g->w )
  35. {
  36. for( i = 0; i < g->h; i++ )
  37. {
  38. t->left[i] = -10;
  39. t->right[i] = g->w + 10;
  40. }
  41. }
  42. else
  43. {
  44. t->left[0] = (g->w - w) / 2;
  45. t->right[0] = (g->w + w) / 2;
  46. /* Yeah, sub-efficient, but less code to do :-) */
  47. for( i = 0; i < g->h; i++ )
  48. {
  49. update_tunnel( g, t );
  50. }
  51. }
  52. return t;
  53. }
  54. void free_tunnel( tunnel *t )
  55. {
  56. free( t->left );
  57. free( t->right );
  58. free( t );
  59. }
  60. void draw_tunnel( game *g, tunnel *t )
  61. {
  62. int i, j;
  63. char c;
  64. gfx_color( GREEN );
  65. /* Left border */
  66. for( i = 0; i < g->h ; i++ )
  67. {
  68. if( t->left[i] <= -10 )
  69. {
  70. continue;
  71. }
  72. if( i + 1 == g->h || t->left[i] > t->left[i+1] )
  73. {
  74. c = ( i == 0 || t->left[i] > t->left[i-1] ) ? '>' : '/';
  75. }
  76. else
  77. {
  78. c = ( i == 0 || t->left[i] > t->left[i-1] ) ? '\\' : '<';
  79. }
  80. gfx_goto( t->left[i] + 1, i );
  81. gfx_putchar( c );
  82. if( i + 1 < g->h )
  83. {
  84. for( j = 1; j < t->left[i+1] - t->left[i]; j++ )
  85. {
  86. gfx_goto( t->left[i] + j + 1, i );
  87. gfx_putchar( '_' );
  88. }
  89. }
  90. }
  91. /* Right border */
  92. for( i = 0; i < g->h ; i++ )
  93. {
  94. if( t->right[i] >= g->w + 10 )
  95. {
  96. continue;
  97. }
  98. if( i + 1 == g->h || t->right[i] > t->right[i+1] )
  99. {
  100. c = ( i == 0 || t->right[i] > t->right[i-1] ) ? '>' : '/';
  101. }
  102. else
  103. {
  104. c = ( i == 0 || t->right[i] > t->right[i-1] ) ? '\\' : '<';
  105. }
  106. if( i + 1 < g->h )
  107. {
  108. for( j = 1; j < t->right[i] - t->right[i+1]; j++ )
  109. {
  110. gfx_goto( t->right[i+1] + j - 1, i );
  111. gfx_putchar( '_' );
  112. }
  113. }
  114. gfx_goto( t->right[i] - 1, i );
  115. gfx_putchar( c );
  116. }
  117. gfx_color( RED );
  118. /* Left concrete */
  119. for( i = 0; i < g->h ; i++ )
  120. {
  121. for( j = 0 ; j <= t->left[i]; j++ )
  122. {
  123. gfx_goto( j, i );
  124. gfx_putchar( '#' );
  125. }
  126. }
  127. /* Right concrete */
  128. for( i = 0; i < g->h ; i++ )
  129. {
  130. for( j = t->right[i] ; j < g->w ; j++ )
  131. {
  132. gfx_goto( j, i );
  133. gfx_putchar( '#' );
  134. }
  135. }
  136. }
  137. void update_tunnel( game *g, tunnel *t )
  138. {
  139. static int const delta[] = { -3, -2, -1, 1, 2, 3 };
  140. int i,j,k;
  141. /* Slide tunnel one block vertically */
  142. for( i = t->h - 1; i--; )
  143. {
  144. t->left[i+1] = t->left[i];
  145. t->right[i+1] = t->right[i];
  146. }
  147. /* Generate new values */
  148. i = delta[GET_RAND(0,6)];
  149. j = delta[GET_RAND(0,6)];
  150. /* Check in which direction we need to alter tunnel */
  151. if( t->right[1] - t->left[1] < t->w )
  152. {
  153. /* Not wide enough, make sure i <= j */
  154. if( i > j )
  155. {
  156. k = j; j = i; i = k;
  157. }
  158. }
  159. else if( t->right[1] - t->left[1] - 2 > t->w )
  160. {
  161. /* Too wide, make sure i >= j */
  162. if( i < j )
  163. {
  164. k = j; j = i; i = k;
  165. }
  166. }
  167. else
  168. {
  169. /* No need to mess with i and j: width is OK */
  170. }
  171. /* If width doesn't exceed game size, update coords */
  172. if( t->w <= g->w || t->right[1] - t->left[1] < t->w )
  173. {
  174. t->left[0] = t->left[1] + i;
  175. t->right[0] = t->right[1] + j;
  176. }
  177. else
  178. {
  179. t->left[0] = -10;
  180. t->right[0] = g->w + 10;
  181. }
  182. if( t->w > g->w )
  183. {
  184. if( t->left[0] < 0 && t->right[0] < g->w - 2 )
  185. {
  186. t->left[0] = t->left[1] + 1;
  187. }
  188. if( t->left[0] > 1 && t->right[0] > g->w - 1 )
  189. {
  190. t->right[0] = t->right[1] - 1;
  191. }
  192. }
  193. else
  194. {
  195. if( t->left[0] < 0 )
  196. {
  197. t->left[0] = t->left[1] + 1;
  198. }
  199. if( t->right[0] > g->w - 1 )
  200. {
  201. t->right[0] = t->right[1] - 1;
  202. }
  203. }
  204. }