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

Last change on this file since 19 was 19, checked in by Sam Hocevar, 20 years ago
  • real Debian package files.
  • two new types of aliens. only one rules.
  • removed gfx_write in favor of gfx_putchar and gfx_putstr.
  • added bonuses at alien death. they do nothing yet.
  • seeker missiles. 'b' to test.
  • weapon resolution is now 16*char. needs to be generalized.
  • fixed the supernova bugs. center could collide with the tunnel, and the last frame was badly displayed.
  • lots of cleanups everywhere.
File size: 5.8 KB
Line 
1
2#include <stdlib.h>
3#include <math.h>
4
5#include "common.h"
6
7static void draw_nuke( int x, int y, int frame );
8static void draw_circle( int x, int y, int r, char c );
9
10void init_weapons( game *g, weapons *wp )
11{
12    int i;
13
14    for( i = 0; i < WEAPONS; i++ )
15    {
16        wp->type[i] = WEAPON_NONE;
17    }
18}
19
20void draw_weapons( game *g, weapons *wp )
21{
22    int i;
23
24    for( i = 0; i < WEAPONS; i++ )
25    {
26        switch( wp->type[i] )
27        {
28            case WEAPON_LASER:
29                gfx_color( WHITE );
30                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
31                gfx_putchar( '|' );
32                gfx_color( CYAN );
33                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
34                gfx_putchar( '|' );
35                break;
36            case WEAPON_SEEKER:
37                gfx_color( CYAN );
38                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
39                gfx_putchar( '.' );
40                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
41                gfx_putchar( 'o' );
42                gfx_color( WHITE );
43                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
44                gfx_putchar( '@' );
45                break;
46            case WEAPON_NUKE:
47                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
48                break;
49            case WEAPON_NONE:
50                break;
51        }
52    }
53}
54
55void update_weapons( game *g, weapons *wp )
56{
57    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
58
59    for( i = 0; i < WEAPONS; i++ )
60    {
61        switch( wp->type[i] )
62        {
63            case WEAPON_LASER:
64                wp->x[i] += wp->vx[i];
65                wp->y[i] += wp->vy[i];
66                if( wp->y[i] < 0 )
67                {
68                    wp->type[i] = WEAPON_NONE;
69                }
70                break;
71            case WEAPON_SEEKER:
72                /* Update tail */
73                wp->x3[i] = wp->x2[i];
74                wp->y3[i] = wp->y2[i];
75
76                wp->x2[i] = wp->x[i];
77                wp->y2[i] = wp->y[i];
78
79                wp->x[i] += wp->vx[i];
80                wp->y[i] += wp->vy[i];
81
82                if( wp->y[i] < 0 )
83                {
84                    wp->type[i] = WEAPON_NONE;
85                    break;
86                }
87
88                if( wp->n[i] < 0 )
89                {
90                    /* Stop updating direction */
91                    break;
92                }
93
94                wp->n[i]--;
95
96                /* Estimate our position in 2 frames */
97                xnew = wp->x[i] + 4 * wp->vx[i];
98                ynew = wp->y[i] + 4 * wp->vy[i];
99
100                xmin = xnew;
101                ymin = - (g->h << 4);
102                dist = (xnew - xmin) * (xnew - xmin)
103                        + 4 * (ynew - ymin) * (ynew - ymin);
104
105                /* Find the nearest alien */
106                for( j = 0; j < ALIENS; j++ )
107                {
108                    if( g->al->type[j] != ALIEN_NONE )
109                    {
110                        int alx = g->al->x[j] << 4;
111                        int aly = g->al->y[j] << 4;
112                        int new = (xnew - alx) * (xnew - alx)
113                                   + 4 * (ynew - aly) * (ynew - aly);
114                        if( new <= dist )
115                        {
116                            dist = new;
117                            xmin = alx;
118                            ymin = aly;
119                        }
120                    }
121                }
122
123                /* Find our new direction */
124                dx = xmin - wp->x[i];
125                dy = ymin - wp->y[i];
126
127                /* Normalize and update speed */
128                wp->vx[i] = (7 * wp->vx[i]
129                              + (dx * 48) / sqrt(dx*dx+dy*dy) ) / 8;
130                wp->vy[i] = (7 * wp->vy[i]
131                              + (dy * 24) / sqrt(dx*dx+dy*dy) ) / 8;
132
133                break;
134            case WEAPON_NUKE:
135                wp->n[i]--;
136                if( wp->n[i] < 0 )
137                {
138                    wp->type[i] = WEAPON_NONE;
139                }
140                break;
141            case WEAPON_NONE:
142                break;
143        }
144    }
145}
146
147void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
148{
149    int i;
150
151    for( i = 0; i < WEAPONS; i++ )
152    {
153        if( wp->type[i] == WEAPON_NONE )
154        {
155            wp->x[i] = x;
156            wp->y[i] = y;
157            wp->vx[i] = vx;
158            wp->vy[i] = vy;
159            wp->type[i] = type;
160            switch( type )
161            {
162                case WEAPON_LASER:
163                    break;
164                case WEAPON_SEEKER:
165                    wp->x2[i] = x;
166                    wp->y2[i] = y;
167                    wp->x3[i] = x;
168                    wp->y3[i] = y;
169                    wp->n[i] = 10;
170                    break;
171                case WEAPON_NUKE:
172                    wp->n[i] = 25;
173                    break;
174                case WEAPON_NONE:
175                    break;
176            }
177            break;
178        }
179    }
180}
181
182static void draw_nuke( int x, int y, int frame )
183{
184    int r = (29 - frame) * (29 - frame) / 8;
185
186    /* Lots of duplicate pixels, but we don't care */
187    gfx_color( BLUE );
188    draw_circle( x, y, r++, ':' );
189    gfx_color( CYAN );
190    draw_circle( x, y, r++, '%' );
191    gfx_color( WHITE );
192    draw_circle( x, y, r++, '#' );
193    draw_circle( x, y, r++, '#' );
194}
195
196static void draw_circle( int x, int y, int r, char c )
197{
198    int test, dx, dy;
199
200    /* Optimized Bresenham. Kick ass. */
201    for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
202    {
203        gfx_putcharTO( x + dx, y + dy / 2, c );
204        gfx_putcharTO( x - dx, y + dy / 2, c );
205        gfx_putcharTO( x + dx, y - dy / 2, c );
206        gfx_putcharTO( x - dx, y - dy / 2, c );
207
208        gfx_putcharTO( x + dy, y + dx / 2, c );
209        gfx_putcharTO( x - dy, y + dx / 2, c );
210        gfx_putcharTO( x + dy, y - dx / 2, c );
211        gfx_putcharTO( x - dy, y - dx / 2, c );
212
213        test += test > 0 ? dx - dy-- : dx;
214    }
215}
216
Note: See TracBrowser for help on using the repository browser.