source: ttyvaders/trunk/src/tunnel.c @ 54

Last change on this file since 54 was 54, checked in by Sam Hocevar, 19 years ago
  • lasers are now twice as fast.
  • walls are now filled, and displayed on top of aliens.
File size: 4.9 KB
Line 
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.7 2002/12/23 12:03:31 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
23#include <stdlib.h>
24
25#include "common.h"
26
27static void draw_wall( game *g, int *wall, int delta );
28
29/* Init tunnel */
30tunnel * create_tunnel( game *g, int w, int h )
31{
32    int i;
33    tunnel *t = malloc(sizeof(tunnel));
34
35    t->left = malloc(h*sizeof(int));
36    t->right = malloc(h*sizeof(int));
37    t->w = w;
38    t->h = h;
39
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
59    return t;
60}
61
62void free_tunnel( tunnel *t )
63{
64    free( t->left );
65    free( t->right );
66    free( t );
67}
68
69void draw_tunnel( game *g, tunnel *t )
70{
71    /* Print tunnel */
72    draw_wall( g, t->left, 1 );
73    draw_wall( g, t->right, -1 );
74}
75
76void update_tunnel( game *g, tunnel *t )
77{
78    static int const delta[] = { -3, -2, -1, 1, 2, 3 };
79    int i,j,k;
80
81    /* Slide tunnel one block vertically */
82    for( i = t->h - 1; i--; )
83    {
84        t->left[i+1] = t->left[i];
85        t->right[i+1] = t->right[i];
86    }
87
88    /* Generate new values */
89    i = delta[GET_RAND(0,6)];
90    j = delta[GET_RAND(0,6)];
91
92    /* Check in which direction we need to alter tunnel */
93    if( t->right[1] - t->left[1] < t->w )
94    {
95        /* Not wide enough */
96        if( i > j )
97        {
98            k = j; j = i; i = k;
99        }
100    }
101    else if( t->right[1] - t->left[1] - 2 > t->w )
102    {
103        /* Too wide */
104        if( i < j )
105        {
106            k = j; j = i; i = k;
107        }
108    }
109    else
110    {
111        /* No need to mess with i and j: width is OK */
112    }
113
114    /* If width doesn't exceed game size, update coords */
115    if( t->w <= g->w || t->right[1] - t->left[1] < t->w )
116    {
117        t->left[0] = t->left[1] + i;
118        t->right[0] = t->right[1] + j;
119    }
120    else
121    {
122        t->left[0] = -10;
123        t->right[0] = g->w + 10;
124    }
125
126    if( t->w > g->w )
127    {
128        if( t->left[0] < 0 && t->right[0] < g->w - 2 )
129        {
130             t->left[0] = t->left[1] + 1;
131        }
132
133        if( t->left[0] > 1 && t->right[0] > g->w - 1 )
134        {
135             t->right[0] = t->right[1] - 1;
136        }
137    }
138    else
139    {
140        if( t->left[0] < 0 )
141        {
142            t->left[0] = t->left[1] + 1;
143        }
144
145        if( t->right[0] > g->w - 1 )
146        {
147            t->right[0] = t->right[1] - 1;
148        }
149    }
150}
151
152static void draw_wall( game *g, int *wall, int delta )
153{
154    int i, j;
155
156    gfx_color( RED );
157
158    if( delta == -1 )
159    {
160        for( i = 0; i < g->h ; i++ )
161        {
162            for( j = wall[i] ; j < g->w ; j++ )
163            {
164                gfx_goto( j, i );
165                gfx_putchar( '#' );
166            }
167        }
168    }
169    else
170    {
171        for( i = 0; i < g->h ; i++ )
172        {
173            for( j = 0 ; j <= wall[i]; j++ )
174            {
175                gfx_goto( j, i );
176                gfx_putchar( '#' );
177            }
178        }
179    }
180
181    gfx_color( GREEN );
182
183    for( i = 0; i < g->h ; i++ )
184    {
185        char c;
186
187        if( wall[i] <= -10 || wall[i] >= g->w + 10 )
188        {
189            continue;
190        }
191
192        if( i + 1 == g->h || wall[i] > wall[i+1] )
193        {
194            c = ( i == 0 || wall[i] > wall[i-1] ) ? '>' : '/';
195        }
196        else
197        {
198            c = ( i == 0 || wall[i] > wall[i-1] ) ? '\\' : '<';
199        }
200
201        if( delta == -1 && i + 1 < g->h )
202        {
203            for( j = 1; j < wall[i] - wall[i+1]; j++ )
204            {
205                gfx_goto( wall[i+1] + j - 1, i );
206                gfx_putchar( '_' );
207            }
208        }
209
210        gfx_goto( wall[i] + delta, i );
211        gfx_putchar( c );
212
213        if( delta == +1 && i + 1 < g->h )
214        {
215            for( j = 1; j < wall[i+1] - wall[i]; j++ )
216            {
217                gfx_goto( wall[i] + j + 1, i );
218                gfx_putchar( '_' );
219            }
220        }
221    }
222}
223
Note: See TracBrowser for help on using the repository browser.