Browse Source

* moved nuke from explosions to weapons.

* used a cool Bresenham algorithm to draw the nuke circles.
  * nuke collides with aliens.
tags/v0.99.beta14
Sam Hocevar sam 22 years ago
parent
commit
49b8b99b8f
6 changed files with 156 additions and 148 deletions
  1. +55
    -25
      collide.c
  2. +10
    -6
      common.h
  3. +0
    -100
      explosions.c
  4. +9
    -5
      main.c
  5. +6
    -0
      player.c
  6. +76
    -12
      weapons.c

+ 55
- 25
collide.c View File

@@ -7,7 +7,7 @@ void collide_weapons_tunnel( game *g, weapons *wp, tunnel *t, explosions *ex )
{ {
int i; int i;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
if( wp->y[i] >= 0 ) if( wp->y[i] >= 0 )
{ {
@@ -59,47 +59,77 @@ void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex )
{ {
int i, j; int i, j;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
if( wp->y[i] >= 0 ) if( wp->y[i] >= 0 )
{ {
int ok = 0; int ok = 0;
int r;


for( j = 0; j < ALIENS; j++ )
switch( wp->type[i] )
{ {
if( wp->x[i] >= al->x[j]
&& wp->x[i] <= al->x[j] + 4
&& wp->y[i] >= al->y[j]
&& wp->y[i] <= al->y[j] + 2 )
case 2:
/* Big nuke */
r = (34 - wp->n[i]) * (34 - wp->n[i]) / 10;

for( j = 0; j < ALIENS; j++ )
{ {
al->life[j]--;
if( al->life[j] == 0 )
if( al->x[j] < 0 )
{
continue;
}

if( (al->x[j] - wp->x[i]) * (al->x[j] - wp->x[i])
+ 4 * (al->y[j] - wp->y[i]) * (al->y[j] - wp->y[i])
<= r * r )
{ {
/* Kill alien, not nuke */
add_explosion( g, ex, al->x[j], al->y[j], 0, 0, 1 );
al->x[j] = -1; al->x[j] = -1;
al->y[j] = -1; al->y[j] = -1;
add_explosion( g, ex, wp->x[i], wp->y[i], 0, 0, 1 );
} }
ok = 1;
} }
else if( wp->x[i] >= al->x[j]
&& wp->x[i] <= al->x[j] + 4
&& wp->y[i]+1 >= al->y[j]
&& wp->y[i]+1 <= al->y[j] + 2 )
break;

case 1:
default:
for( j = 0; j < ALIENS; j++ )
{ {
al->life[j]--;
if( al->life[j] == 0 )
if( wp->x[i] >= al->x[j]
&& wp->x[i] <= al->x[j] + 4
&& wp->y[i] >= al->y[j]
&& wp->y[i] <= al->y[j] + 2 )
{ {
al->x[j] = -1;
al->y[j] = -1;
add_explosion( g, ex, wp->x[i], wp->y[i]+1, 0, 0, 1 );
al->life[j]--;
if( al->life[j] == 0 )
{
al->x[j] = -1;
al->y[j] = -1;
add_explosion( g, ex, wp->x[i], wp->y[i], 0, 0, 1 );
}
ok = 1;
}
else if( wp->x[i] >= al->x[j]
&& wp->x[i] <= al->x[j] + 4
&& wp->y[i]+1 >= al->y[j]
&& wp->y[i]+1 <= al->y[j] + 2 )
{
al->life[j]--;
if( al->life[j] == 0 )
{
al->x[j] = -1;
al->y[j] = -1;
add_explosion( g, ex, wp->x[i], wp->y[i]+1, 0, 0, 1 );
}
ok = 1;
} }
ok = 1;
} }
}


if( ok )
{
wp->y[i] = -1;
if( ok )
{
wp->y[i] = -1;
}
break;
} }
} }
} }


+ 10
- 6
common.h View File

@@ -1,6 +1,6 @@


#define STARS 50 #define STARS 50
#define SHOTS 50
#define WEAPONS 50
#define ROCKS 10 #define ROCKS 10
#define ALIENS 10 #define ALIENS 10
#define EXPLOSIONS 20 #define EXPLOSIONS 20
@@ -17,6 +17,8 @@
# define GFX_WRITE(x) addch(x) # define GFX_WRITE(x) addch(x)
#endif #endif


#define GFX_WRITETO(x,y,c) do{ GFX_GOTO(x,y); GFX_WRITE(c); }while(0)

#define GET_RAND(p,q) ((p)+(int)((1.0*((q)-(p)))*rand()/(RAND_MAX+1.0))) #define GET_RAND(p,q) ((p)+(int)((1.0*((q)-(p)))*rand()/(RAND_MAX+1.0)))


typedef struct typedef struct
@@ -54,9 +56,11 @@ typedef struct


typedef struct typedef struct
{ {
int x[SHOTS];
int y[SHOTS];
int v[SHOTS];
int x[WEAPONS];
int y[WEAPONS];
int v[WEAPONS];
int n[WEAPONS];
int type[WEAPONS];


} weapons; } weapons;


@@ -64,7 +68,7 @@ typedef struct
{ {
int x, y; int x, y;
int dir; int dir;
int weapon;
int weapon, nuke;


} player; } player;


@@ -112,7 +116,7 @@ void update_player( game *g, player *p );
void init_weapons( game *g, weapons *wp ); void init_weapons( game *g, weapons *wp );
void draw_weapons( game *g, weapons *wp ); void draw_weapons( game *g, weapons *wp );
void update_weapons( game *g, weapons *wp ); void update_weapons( game *g, weapons *wp );
void add_weapon( game *g, weapons *wp, int x, int y );
void add_weapon( game *g, weapons *wp, int x, int y, int type );


void init_starfield( game *g, starfield *s ); void init_starfield( game *g, starfield *s );
void draw_starfield( game *g, starfield *s ); void draw_starfield( game *g, starfield *s );


+ 0
- 100
explosions.c View File

@@ -1,12 +1,10 @@


#include <stdlib.h> #include <stdlib.h>
#include <math.h>


#include "common.h" #include "common.h"


static void draw_small_explosion( int x, int y, int frame ); static void draw_small_explosion( int x, int y, int frame );
static void draw_big_explosion( int x, int y, int frame ); static void draw_big_explosion( int x, int y, int frame );
static void draw_huge_explosion( int x, int y, int frame );


void init_explosions( game *g, explosions *ex ) void init_explosions( game *g, explosions *ex )
{ {
@@ -85,9 +83,6 @@ void draw_explosions( game *g, explosions *ex )


switch( ex->type[i] ) switch( ex->type[i] )
{ {
case 2:
draw_huge_explosion( ex->x[i], ex->y[i], ex->n[i] );
break;
case 1: case 1:
draw_big_explosion( ex->x[i], ex->y[i], ex->n[i] ); draw_big_explosion( ex->x[i], ex->y[i], ex->n[i] );
break; break;
@@ -308,98 +303,3 @@ static void draw_big_explosion( int x, int y, int frame )
} }
} }


static void draw_circle( int x, int y, float r );

static void draw_huge_explosion( int x, int y, int frame )
{
float r = 1.5 * (30 - frame);

GFX_COLOR( BLUE );
draw_circle( x, y, r );

r += 0.7;

GFX_COLOR( CYAN );
draw_circle( x, y, r );

r += 0.7;

GFX_COLOR( WHITE );
draw_circle( x, y, r );
}

static void draw_circle( int x, int y, float r )
{
#if 1
float c;

for( c = 0 ; c <= 90 ; c += 1 )
{
float dx = 0.5 + r * 2.0 * sin( c * M_PI / 180.0 );
float dy = 0.5 + r * cos( c * M_PI / 180.0 );

GFX_GOTO( x + dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x + dx, y - dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y - dy );
GFX_WRITE( '#' );
}
#endif

#if 0
int dx,dy,a2,b2, S, T;
float a = r*8, b = r*2;

a2 = a*a;
b2 = b*b;
dx = 0;
dy = b;
S = a2*(1-2*b) + 2*b2;
T = b2 - 2*a2*(2*b-1);
GFX_GOTO( x + dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x + dx, y - dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y - dy );
GFX_WRITE( '#' );

do
{
if (S<0)
{
S += 2*b2*(2*x+3);
T += 4*b2*(x+1);
dx++;
}
else if (T<0)
{
S += 2*b2*(2*x+3) - 4*a2*(dy-1);
T += 4*b2*(x+1) - 2*a2*(2*dy-3);
dx++;
dy--;
}
else
{
S -= 4*a2*(dy-1);
T -= 2*a2*(2*dy-3);
dy--;
}
GFX_GOTO( x + dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y + dy );
GFX_WRITE( '#' );
GFX_GOTO( x + dx, y - dy );
GFX_WRITE( '#' );
GFX_GOTO( x - dx, y - dy );
GFX_WRITE( '#' );
}
while (dy>0);
#endif

}


+ 9
- 5
main.c View File

@@ -98,23 +98,27 @@ static void start_game (game *g)
p->dir = -3; p->dir = -3;
break; break;
case 'j': case 'j':
//if( p->y < g->h - 2 ) p->y += 1;
if( p->y < g->h - 2 ) p->y += 1;
break; break;
case 'k': case 'k':
//if( p->y > 1 ) p->y -= 1;
if( p->y > 1 ) p->y -= 1;
break; break;
case 'l': case 'l':
p->dir = 3; p->dir = 3;
break; break;
case '\r': case '\r':
add_explosion( g, ex, p->x + 2, p->y, 0, 0, 2 );
if( p->nuke == 0 )
{
p->nuke = 40;
add_weapon( g, wp, p->x + 2, p->y, 2 );
}
break; break;
case ' ': case ' ':
if( p->weapon == 0 ) if( p->weapon == 0 )
{ {
p->weapon = 4; p->weapon = 4;
add_weapon( g, wp, p->x, p->y );
add_weapon( g, wp, p->x + 5, p->y );
add_weapon( g, wp, p->x, p->y, 1 );
add_weapon( g, wp, p->x + 5, p->y, 1 );
} }
break; break;
} }


+ 6
- 0
player.c View File

@@ -12,6 +12,7 @@ player * create_player( game *g )
p->y = g->h - 3; p->y = g->h - 3;
p->dir = 0; p->dir = 0;
p->weapon = 0; p->weapon = 0;
p->nuke = 0;


return p; return p;
} }
@@ -51,6 +52,11 @@ void update_player( game *g, player *p )
p->weapon--; p->weapon--;
} }


if( p->nuke )
{
p->nuke--;
}

if( p->dir < 0 ) if( p->dir < 0 )
{ {
if( p->dir == -3 && p->x > -2 ) p->x -= 1; if( p->dir == -3 && p->x > -2 ) p->x -= 1;


+ 76
- 12
weapons.c View File

@@ -3,15 +3,20 @@


#include "common.h" #include "common.h"


static void draw_nuke( int x, int y, int frame );
static void draw_circle( int x, int y, int r );

void init_weapons( game *g, weapons *wp ) void init_weapons( game *g, weapons *wp )
{ {
int i; int i;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
wp->x[i] = -1; wp->x[i] = -1;
wp->y[i] = -1; wp->y[i] = -1;
wp->v[i] = 0; wp->v[i] = 0;
wp->n[i] = 0;
wp->type[i] = 0;
} }
} }


@@ -19,16 +24,25 @@ void draw_weapons( game *g, weapons *wp )
{ {
int i; int i;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
if( wp->x[i] >= 0 ) if( wp->x[i] >= 0 )
{ {
GFX_COLOR( WHITE );
GFX_GOTO( wp->x[i], wp->y[i] );
GFX_WRITE( '|' );
GFX_COLOR( CYAN );
GFX_GOTO( wp->x[i], wp->y[i] + 1 );
GFX_WRITE( '|' );
switch( wp->type[i] )
{
case 2:
draw_nuke( wp->x[i], wp->y[i], wp->n[i] );
break;
case 1:
default:
GFX_COLOR( WHITE );
GFX_GOTO( wp->x[i], wp->y[i] );
GFX_WRITE( '|' );
GFX_COLOR( CYAN );
GFX_GOTO( wp->x[i], wp->y[i] + 1 );
GFX_WRITE( '|' );
break;
}
} }
} }
} }
@@ -37,7 +51,7 @@ void update_weapons( game *g, weapons *wp )
{ {
int i; int i;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
if( wp->y[i] < 0 ) if( wp->y[i] < 0 )
{ {
@@ -46,26 +60,76 @@ void update_weapons( game *g, weapons *wp )
} }
else else
{ {
wp->y[i] += wp->v[i];
switch( wp->type[i] )
{
case 2:
wp->n[i]--;
if( wp->n[i]-- < 0 )
{
wp->y[i] = -1;
}
break;
case 1:
default:
wp->y[i] += wp->v[i];
break;
}


/* Check collisions */ /* Check collisions */
} }
} }
} }


void add_weapon( game *g, weapons *wp, int x, int y )
void add_weapon( game *g, weapons *wp, int x, int y, int type )
{ {
int i; int i;


for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{ {
if( wp->y[i] < 0 ) if( wp->y[i] < 0 )
{ {
wp->x[i] = x; wp->x[i] = x;
wp->y[i] = y; wp->y[i] = y;
wp->type[i] = type;
wp->v[i] = -2; wp->v[i] = -2;
wp->n[i] = 30;
break; break;
} }
} }
} }


static void draw_nuke( int x, int y, int frame )
{
int r = (34 - frame) * (34 - frame) / 10;

/* Lots of duplicate pixels, but we don't care */
GFX_COLOR( BLUE );
draw_circle( x, y, r++ );
GFX_COLOR( CYAN );
draw_circle( x, y, r++ );
GFX_COLOR( WHITE );
draw_circle( x, y, r++ );
draw_circle( x, y, r++ );
}

static void draw_circle( int x, int y, int r )
{
int test, dx, dy;

/* Optimized Bresenham. Kick ass. */
for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
{
GFX_WRITETO( x + dx, y + dy / 2, '#' );
GFX_WRITETO( x - dx, y + dy / 2, '#' );
GFX_WRITETO( x + dx, y - dy / 2, '#' );
GFX_WRITETO( x - dx, y - dy / 2, '#' );

GFX_WRITETO( x + dy, y + dx / 2, '#' );
GFX_WRITETO( x - dy, y + dx / 2, '#' );
GFX_WRITETO( x + dy, y - dx / 2, '#' );
GFX_WRITETO( x - dy, y - dx / 2, '#' );

test += test > 0 ? dx - dy-- : dx;
}
}


Loading…
Cancel
Save