Browse Source

* moved nuke from explosions to weapons.

* used a cool Bresenham algorithm to draw the nuke circles.
  * nuke collides with aliens.


git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/ttyvaders/trunk@16 92316355-f0b4-4df1-b90c-862c8a59935f
master
sam 22 years ago
parent
commit
ba323654cb
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;

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

for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{
if( wp->y[i] >= 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->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 SHOTS 50
#define WEAPONS 50
#define ROCKS 10
#define ALIENS 10
#define EXPLOSIONS 20
@@ -17,6 +17,8 @@
# define GFX_WRITE(x) addch(x)
#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)))

typedef struct
@@ -54,9 +56,11 @@ 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;

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

} player;

@@ -112,7 +116,7 @@ void update_player( game *g, player *p );
void init_weapons( game *g, weapons *wp );
void draw_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 draw_starfield( game *g, starfield *s );


+ 0
- 100
explosions.c View File

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

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

#include "common.h"

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_huge_explosion( int x, int y, int frame );

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

switch( ex->type[i] )
{
case 2:
draw_huge_explosion( ex->x[i], ex->y[i], ex->n[i] );
break;
case 1:
draw_big_explosion( ex->x[i], ex->y[i], ex->n[i] );
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;
break;
case 'j':
//if( p->y < g->h - 2 ) p->y += 1;
if( p->y < g->h - 2 ) p->y += 1;
break;
case 'k':
//if( p->y > 1 ) p->y -= 1;
if( p->y > 1 ) p->y -= 1;
break;
case 'l':
p->dir = 3;
break;
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;
case ' ':
if( p->weapon == 0 )
{
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;
}


+ 6
- 0
player.c View File

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

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

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

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


+ 76
- 12
weapons.c View File

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

#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 )
{
int i;

for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{
wp->x[i] = -1;
wp->y[i] = -1;
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;

for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{
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;

for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{
if( wp->y[i] < 0 )
{
@@ -46,26 +60,76 @@ void update_weapons( game *g, weapons *wp )
}
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 */
}
}
}

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;

for( i = 0; i < SHOTS; i++ )
for( i = 0; i < WEAPONS; i++ )
{
if( wp->y[i] < 0 )
{
wp->x[i] = x;
wp->y[i] = y;
wp->type[i] = type;
wp->v[i] = -2;
wp->n[i] = 30;
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