source: libcaca/trunk/src/weapons.c @ 23

Last change on this file since 23 was 23, checked in by Sam Hocevar, 20 years ago
  • new weapon: bomb.
  • beam now collides with aliens.
File size: 15.3 KB
Line 
1
2#include <stdlib.h>
3#include <math.h>
4
5#include "common.h"
6
7static void draw_bomb( int x, int y, int vx, int vy );
8static void draw_nuke( int x, int y, int frame );
9static void draw_beam( int x, int y, int frame );
10static void draw_circle( int x, int y, int r, char c );
11
12void init_weapons( game *g, weapons *wp )
13{
14    int i;
15
16    for( i = 0; i < WEAPONS; i++ )
17    {
18        wp->type[i] = WEAPON_NONE;
19    }
20}
21
22void draw_weapons( game *g, weapons *wp )
23{
24    int i;
25
26    for( i = 0; i < WEAPONS; i++ )
27    {
28        switch( wp->type[i] )
29        {
30            case WEAPON_LASER:
31                gfx_color( WHITE );
32                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
33                gfx_putchar( '|' );
34                gfx_color( CYAN );
35                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
36                gfx_putchar( '|' );
37                break;
38            case WEAPON_SEEKER:
39                gfx_color( CYAN );
40                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
41                gfx_putchar( '.' );
42                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
43                gfx_putchar( 'o' );
44                gfx_color( WHITE );
45                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
46                gfx_putchar( '@' );
47                break;
48            case WEAPON_BOMB:
49                gfx_color( GRAY );
50                gfx_goto( (wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4 );
51                gfx_putchar( '.' );
52                gfx_goto( (wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4 );
53                gfx_putchar( '.' );
54                gfx_goto( (wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4 );
55                gfx_putchar( '.' );
56                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
57                gfx_putchar( '.' );
58                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
59                gfx_putchar( '.' );
60                draw_bomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i] );
61                break;
62            case WEAPON_BEAM:
63                draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
64                break;
65            case WEAPON_NUKE:
66                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
67                break;
68            case WEAPON_NONE:
69                break;
70        }
71    }
72}
73
74void update_weapons( game *g, weapons *wp )
75{
76    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
77
78    for( i = 0; i < WEAPONS; i++ )
79    {
80        switch( wp->type[i] )
81        {
82            case WEAPON_LASER:
83                wp->x[i] += wp->vx[i];
84                wp->y[i] += wp->vy[i];
85                if( wp->y[i] < 0 )
86                {
87                    wp->type[i] = WEAPON_NONE;
88                }
89                break;
90            case WEAPON_BOMB:
91            case WEAPON_SEEKER:
92                /* Update tail */
93                wp->x3[i] = wp->x2[i];
94                wp->y3[i] = wp->y2[i];
95
96                wp->x2[i] = wp->x[i];
97                wp->y2[i] = wp->y[i];
98
99                wp->x[i] += wp->vx[i];
100                wp->y[i] += wp->vy[i];
101
102                if( wp->y[i] < 0 )
103                {
104                    wp->type[i] = WEAPON_NONE;
105                    break;
106                }
107
108                if( wp->n[i] < 0 )
109                {
110                    /* Stop updating direction */
111                    break;
112                }
113
114                wp->n[i]--;
115
116                /* Estimate our position in 2 frames */
117                xnew = wp->x[i] + 4 * wp->vx[i];
118                ynew = wp->y[i] + 4 * wp->vy[i];
119
120                xmin = xnew;
121                ymin = - (g->h << 4);
122                dist = (xnew - xmin) * (xnew - xmin)
123                        + 4 * (ynew - ymin) * (ynew - ymin);
124
125                /* Find the nearest alien */
126                for( j = 0; j < ALIENS; j++ )
127                {
128                    if( g->al->type[j] != ALIEN_NONE )
129                    {
130                        int alx = g->al->x[j] << 4;
131                        int aly = g->al->y[j] << 4;
132                        int new = (xnew - alx) * (xnew - alx)
133                                   + 4 * (ynew - aly) * (ynew - aly);
134                        if( new <= dist )
135                        {
136                            dist = new;
137                            xmin = alx;
138                            ymin = aly;
139                        }
140                    }
141                }
142
143                /* Find our new direction */
144                dx = xmin - wp->x[i];
145                dy = ymin - wp->y[i];
146
147                /* Normalize and update speed */
148                wp->vx[i] = (7 * wp->vx[i]
149                              + (dx * 48) / sqrt(dx*dx+dy*dy) ) / 8;
150                wp->vy[i] = (7 * wp->vy[i]
151                              + (dy * 24) / sqrt(dx*dx+dy*dy) ) / 8;
152
153                break;
154            case WEAPON_BEAM:
155                wp->x[i] = (g->p->x + 2) << 4;
156                wp->y[i] = g->p->y << 4;
157                wp->n[i]--;
158                if( wp->n[i] < 0 )
159                {
160                    wp->type[i] = WEAPON_NONE;
161                }
162                break;
163            case WEAPON_NUKE:
164                wp->n[i]--;
165                if( wp->n[i] < 0 )
166                {
167                    wp->type[i] = WEAPON_NONE;
168                }
169                break;
170            case WEAPON_NONE:
171                break;
172        }
173    }
174}
175
176void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
177{
178    int i;
179
180    for( i = 0; i < WEAPONS; i++ )
181    {
182        if( wp->type[i] == WEAPON_NONE )
183        {
184            wp->x[i] = x;
185            wp->y[i] = y;
186            wp->vx[i] = vx;
187            wp->vy[i] = vy;
188            wp->type[i] = type;
189            switch( type )
190            {
191                case WEAPON_LASER:
192                    break;
193                case WEAPON_SEEKER:
194                case WEAPON_BOMB:
195                    wp->x2[i] = x;
196                    wp->y2[i] = y;
197                    wp->x3[i] = x;
198                    wp->y3[i] = y;
199                    wp->n[i] = 10;
200                    break;
201                case WEAPON_BEAM:
202                    wp->n[i] = 25;
203                    break;
204                case WEAPON_NUKE:
205                    wp->n[i] = 25;
206                    break;
207                case WEAPON_NONE:
208                    break;
209            }
210            break;
211        }
212    }
213}
214
215static void draw_bomb( int x, int y, int vx, int vy )
216{
217    vy *= 2;
218    gfx_color( CYAN );
219
220    if( vx > vy )
221    {
222        if( vx > -vy ) /* right quarter */
223        {
224            if( vy > vx/4 )
225            {
226                /* -1pi/6 */
227                gfx_goto( x-4, y-1 );
228                gfx_putstr( "/`-." );
229                gfx_goto( x-4, y );
230                gfx_putstr( "`-._\\" );
231                gfx_goto( x, y+1 );
232                gfx_putchar( '`' );
233            }
234            else if( vy < -vx/4 )
235            {
236                /* 1pi/6 */
237                gfx_goto( x-1, y-1 );
238                gfx_putstr( "_," );
239                gfx_goto( x-4, y );
240                gfx_putstr( ",-' /" );
241                gfx_goto( x-4, y+1 );
242                gfx_putstr( "\\,-'" );
243            }
244            else
245            {
246                /* 0pi/6 */
247                gfx_goto( x-4, y-1 );
248                gfx_putstr( "____" );
249                gfx_goto( x-5, y );
250                gfx_putstr( "|____>" );
251            }
252        }
253        else /* top quarter */
254        {
255            if( vx > -vy/4 )
256            {
257                /* 2pi/6 */
258                gfx_goto( x-1, y-1 );
259                gfx_putstr( "_," );
260                gfx_goto( x-2, y );
261                gfx_putstr( "/ |" );
262                gfx_goto( x-3, y+1 );
263                gfx_putstr( "/ /" );
264                gfx_goto( x-3, y+2 );
265                gfx_putstr( "`'" );
266            }
267            else if( vx < vy/4 )
268            {
269                /* 4pi/6 */
270                gfx_goto( x, y-1 );
271                gfx_putstr( "._" );
272                gfx_goto( x, y );
273                gfx_putstr( "| \\" );
274                gfx_goto( x+1, y+1 );
275                gfx_putstr( "\\ \\" );
276                gfx_goto( x+2, y+2 );
277                gfx_putstr( "`'" );
278            }
279            else
280            {
281                /* 3pi/6 */
282                gfx_goto( x-1, y );
283                gfx_putstr( ",^." );
284                gfx_goto( x-1, y+1 );
285                gfx_putstr( "| |" );
286                gfx_goto( x-1, y+2 );
287                gfx_putstr( "|_|" );
288            }
289        }
290    }
291    else
292    {
293        if( vx > -vy ) /* bottom quarter */
294        {
295            if( vx > vy/4 )
296            {
297                /* -2pi/6 */
298                gfx_goto( x-2, y-2 );
299                gfx_putstr( ",." );
300                gfx_goto( x-2, y-1 );
301                gfx_putstr( "\\ \\" );
302                gfx_goto( x-1, y );
303                gfx_putstr( "\\_|" );
304            }
305            else if( vx < -vy/4 )
306            {
307                /* -4pi/6 */
308                gfx_goto( x+1, y-2 );
309                gfx_putstr( ",." );
310                gfx_goto( x, y-1 );
311                gfx_putstr( "/ /" );
312                gfx_goto( x-1, y );
313                gfx_putstr( "|_/" );
314            }
315            else
316            {
317                /* -3pi/6 */
318                gfx_goto( x, y-3 );
319                gfx_putchar( '_' );
320                gfx_goto( x-1, y-2 );
321                gfx_putstr( "| |" );
322                gfx_goto( x-1, y-1 );
323                gfx_putstr( "| |" );
324                gfx_goto( x-1, y );
325                gfx_putstr( "`v'" );
326            }
327        }
328        else /* left quarter */
329        {
330            if( vy > -vx/4 )
331            {
332                /* -5pi/6 */
333                gfx_goto( x+1, y-1 );
334                gfx_putstr( ",-'\\" );
335                gfx_goto( x, y );
336                gfx_putstr( "/_,-'" );
337                gfx_goto( x, y+1 );
338                gfx_putchar( '\'' );
339            }
340            else if( vy < vx/4 )
341            {
342                /* 5pi/6 */
343                gfx_goto( x, y-1 );
344                gfx_putstr( "._" );
345                gfx_goto( x, y );
346                gfx_putstr( "\\ `-." );
347                gfx_goto( x+1, y+1 );
348                gfx_putstr( "`-./" );
349            }
350            else
351            {
352                /* 6pi/6 */
353                gfx_goto( x+1, y-1 );
354                gfx_putstr( "____" );
355                gfx_goto( x, y );
356                gfx_putstr( "<____|" );
357            }
358        }
359    }
360}
361
362static void draw_beam( int x, int y, int frame )
363{
364    int r = (29 - frame) * (29 - frame) / 8;
365    int i;
366
367    switch( frame )
368    {
369        case 24:
370            gfx_color( WHITE );
371            gfx_goto( x, y-3 );
372            gfx_putstr( "__" );
373            gfx_goto( x-1, y-2 );
374            gfx_putchar( '\'' );
375            gfx_goto( x+2, y-2 );
376            gfx_putchar( '`' );
377            break;
378        case 23:
379            gfx_color( CYAN );
380            gfx_goto( x, y-3 );
381            gfx_putstr( "__" );
382            gfx_color( WHITE );
383            gfx_goto( x-2, y-2 );
384            gfx_putstr( "-'" );
385            gfx_goto( x+2, y-2 );
386            gfx_putstr( "`-" );
387            break;
388        case 22:
389            gfx_color( CYAN );
390            gfx_goto( x, y-3 );
391            gfx_putstr( "__" );
392            gfx_goto( x-1, y-2 );
393            gfx_putchar( '\'' );
394            gfx_goto( x+2, y-2 );
395            gfx_putchar( '`' );
396            gfx_color( WHITE );
397            gfx_goto( x-3, y-2 );
398            gfx_putstr( ",-" );
399            gfx_goto( x+3, y-2 );
400            gfx_putstr( "-." );
401            break;
402        case 21:
403            gfx_color( CYAN );
404            gfx_goto( x-1, y-3 );
405            gfx_putstr( "____" );
406            gfx_goto( x-2, y-2 );
407            gfx_putchar( '\'' );
408            gfx_goto( x+3, y-2 );
409            gfx_putchar( '`' );
410            gfx_color( WHITE );
411            gfx_goto( x-4, y-2 );
412            gfx_putstr( ",-" );
413            gfx_goto( x+4, y-2 );
414            gfx_putstr( "-." );
415            break;
416        case 20:
417            gfx_color( WHITE );
418            gfx_goto( x, y-3 );
419            gfx_putstr( "%%" );
420            gfx_goto( x-4, y-2 );
421            gfx_putchar( ',' );
422            gfx_goto( x+5, y-2 );
423            gfx_putchar( '.' );
424            gfx_color( CYAN );
425            gfx_goto( x-1, y-3 );
426            gfx_putchar( ':' );
427            gfx_goto( x+2, y-3 );
428            gfx_putchar( ':' );
429            gfx_goto( x-3, y-2 );
430            gfx_putstr( "-'" );
431            gfx_goto( x+3, y-2 );
432            gfx_putstr( "`-" );
433            break;
434        case 19:
435            gfx_color( WHITE );
436            gfx_goto( x, y-4 );
437            gfx_putstr( "%%" );
438            gfx_goto( x, y-3 );
439            gfx_putstr( "##" );
440            gfx_color( CYAN );
441            gfx_goto( x-1, y-4 );
442            gfx_putchar( ':' );
443            gfx_goto( x+2, y-4 );
444            gfx_putchar( ':' );
445            gfx_goto( x-1, y-3 );
446            gfx_putchar( '%' );
447            gfx_goto( x+2, y-3 );
448            gfx_putchar( '%' );
449            gfx_goto( x-4, y-2 );
450            gfx_putstr( ",-'" );
451            gfx_goto( x+3, y-2 );
452            gfx_putstr( "`-." );
453            gfx_color( BLUE );
454            gfx_goto( x-2, y-3 );
455            gfx_putchar( ':' );
456            gfx_goto( x+3, y-3 );
457            gfx_putchar( ':' );
458            break;
459        case 18:
460        default:
461            r = (18 - frame) * (18 - frame);
462            gfx_color( WHITE );
463            gfx_goto( x-1, y-5-r );
464            gfx_putstr( ":%%:" );
465            gfx_goto( x-1, y-4-r );
466            gfx_putstr( "%##%" );
467            gfx_color( CYAN );
468            gfx_goto( x-2, y-4-r );
469            gfx_putchar( ':' );
470            gfx_goto( x+3, y-4-r );
471            gfx_putchar( ':' );
472            gfx_goto( x-2, y-2 );
473            gfx_putchar( '\'' );
474            gfx_goto( x+3, y-2 );
475            gfx_putchar( '`' );
476            gfx_color( BLUE );
477            gfx_goto( x-3, y-2 );
478            gfx_putchar( ':' );
479            gfx_goto( x+4, y-2 );
480            gfx_putchar( ':' );
481            for( i = 0; i <= r; i++ )
482            {
483                gfx_color( WHITE );
484                gfx_goto( x-1, y-3-i );
485                gfx_putstr( "####" );
486                gfx_color( CYAN );
487                gfx_goto( x-2, y-3-i );
488                gfx_putchar( '%' );
489                gfx_goto( x+3, y-3-i );
490                gfx_putchar( '%' );
491                gfx_color( BLUE );
492                gfx_goto( x-3, y-3-i );
493                gfx_putchar( ':' );
494                gfx_goto( x+4, y-3-i );
495                gfx_putchar( ':' );
496            }
497            break;
498    }
499}
500
501static void draw_nuke( int x, int y, int frame )
502{
503    int r = (29 - frame) * (29 - frame) / 8;
504
505    /* Lots of duplicate pixels, but we don't care */
506    gfx_color( BLUE );
507    draw_circle( x, y, r++, ':' );
508    gfx_color( CYAN );
509    draw_circle( x, y, r++, '%' );
510    gfx_color( WHITE );
511    draw_circle( x, y, r++, '#' );
512    draw_circle( x, y, r++, '#' );
513}
514
515static void draw_circle( int x, int y, int r, char c )
516{
517    int test, dx, dy;
518
519    /* Optimized Bresenham. Kick ass. */
520    for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
521    {
522        gfx_putcharTO( x + dx, y + dy / 2, c );
523        gfx_putcharTO( x - dx, y + dy / 2, c );
524        gfx_putcharTO( x + dx, y - dy / 2, c );
525        gfx_putcharTO( x - dx, y - dy / 2, c );
526
527        gfx_putcharTO( x + dy, y + dx / 2, c );
528        gfx_putcharTO( x - dy, y + dx / 2, c );
529        gfx_putcharTO( x + dy, y - dx / 2, c );
530        gfx_putcharTO( x - dy, y - dx / 2, c );
531
532        test += test > 0 ? dx - dy-- : dx;
533    }
534}
535
Note: See TracBrowser for help on using the repository browser.