ソースを参照

* First commit. Scrolling works, some weaponry, controls, tunnel blowing,

the nuke is still ugly, almost no collision detection. Nice demo :)


git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/ttyvaders/trunk@12 92316355-f0b4-4df1-b90c-862c8a59935f
master
sam 22年前
コミット
a97a9b5004
12個のファイルの変更1679行の追加0行の削除
  1. +35
    -0
      Makefile
  2. +176
    -0
      aliens.c
  3. +121
    -0
      collide.c
  4. +130
    -0
      common.h
  5. +405
    -0
      explosions.c
  6. +129
    -0
      graphics.c
  7. +179
    -0
      main.c
  8. +68
    -0
      player.c
  9. +135
    -0
      shapes.txt
  10. +59
    -0
      starfield.c
  11. +171
    -0
      tunnel.c
  12. +71
    -0
      weapons.c

+ 35
- 0
Makefile ファイルの表示

@@ -0,0 +1,35 @@

# Fallback to ncurses if this is set to 0
USE_SLANG = 1

CC = gcc
CFLAGS = -g -O6 -fno-strength-reduce -fomit-frame-pointer

# Code qui fait des warnings == code de porc == deux baffes dans ta gueule
CFLAGS += -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wstrict-prototypes -Wshadow -Waggregate-return -Wmissing-prototypes -Wnested-externs

ifeq (1,$(USE_SLANG))
CFLAGS += -DUSE_SLANG
EXECLIBS = -lslang -lm
else
CFLAGS += -DUSE_NCURSES
EXECLIBS = -lncurses -lm
endif

COMPILE_CMD = $(CC) -c $(ALL_CFLAGS)

PROGRAM = ttyvaders
SOURCES = main.c graphics.c tunnel.c starfield.c player.c weapons.c collide.c explosions.c aliens.c
HEADERS = common.h
OBJECTS = $(SOURCES:%.c=%.o)

all: $(PROGRAM)

ttyvaders: $(OBJECTS)
$(CC) -o $@ $(LDFLAGS) $^ $(EXECLIBS)

$(OBJECTS): Makefile $(HEADERS)

clean:
-/bin/rm -f $(PROGRAM) $(OBJECTS)


+ 176
- 0
aliens.c ファイルの表示

@@ -0,0 +1,176 @@

#include <stdlib.h>

#include "common.h"

static void draw_alien( game *g, int x, int y, int type );

void init_aliens( game *g, aliens *al )
{
int i;

for( i = 0; i < ALIENS; i++ )
{
al->x[i] = -1;
al->y[i] = -1;
al->img[i] = 0;
al->life[i] = 0;
}
}

void draw_aliens( game *g, aliens *al )
{
int i;

for( i = 0; i < ALIENS; i++ )
{
if( al->y[i] >= 0 )
{
draw_alien( g, al->x[i], al->y[i], al->img[i] % 2 );
}
}
}

void update_aliens( game *g, aliens *al )
{
int i;

for( i = 0; i < ALIENS; i++ )
{
if( al->y[i] < 0 )
{
//al->x[i] = g->w;
}
else
{
al->x[i] = ((al->x[i] + 5) % (g->w + 3)) - 3;
al->y[i] = al->y[i] + (rand() % 8) / 7 - (rand() % 8) / 7;
al->img[i] = al->img[i] + rand() % 4;

/* Check collisions */
if( al->y[i] < 0 ) al->y[i] = 0;
if( al->y[i] > g->w - 1 ) al->y[i] = g->w - 1;
}
}
}

void add_alien( game *g, aliens *al, int x, int y )
{
int i;

for( i = 0; i < ALIENS; i++ )
{
if( al->y[i] < 0 )
{
al->x[i] = x;
al->y[i] = y;
al->img[i] = 0;
al->life[i] = 2;
break;
}
}
}

static void draw_alien( game *g, int x, int y, int type )
{
switch( type )
{
case 0:
GFX_COLOR( MAGENTA );
GFX_GOTO( x, y );
GFX_WRITE( ',' );
GFX_WRITE( '-' );
GFX_WRITE( '-' );
GFX_WRITE( '-' );
GFX_WRITE( '.' );
GFX_GOTO( x, y+1 );
GFX_WRITE( '\\' );
GFX_COLOR( WHITE );
GFX_WRITE( 'o' );
GFX_WRITE( ' ' );
GFX_WRITE( 'O' );
GFX_COLOR( MAGENTA );
GFX_WRITE( '/' );
GFX_GOTO( x, y+2 );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
break;
case 1:
GFX_COLOR( MAGENTA );
GFX_GOTO( x, y );
GFX_WRITE( ',' );
GFX_WRITE( '-' );
GFX_WRITE( '-' );
GFX_WRITE( '-' );
GFX_WRITE( '.' );
GFX_GOTO( x, y+1 );
GFX_WRITE( '\\' );
GFX_COLOR( WHITE );
GFX_WRITE( 'O' );
GFX_WRITE( ' ' );
GFX_WRITE( 'o' );
GFX_COLOR( MAGENTA );
GFX_WRITE( '/' );
GFX_GOTO( x, y+2 );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
GFX_WRITE( '^' );
break;
}
}

#if 0
void draw_rock( int x, int y, int type )
{
switch( type )
{
case 0:
GFX_COLOR( RED );
GFX_GOTO( x, y );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_WRITE( '_' );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_GOTO( x, y+1 );
GFX_WRITE( '>' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( '/' );
GFX_GOTO( x, y+2 );
GFX_WRITE( '\\' );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_WRITE( '_' );
GFX_WRITE( '>' );
break;
case 1:
GFX_COLOR( RED );
GFX_GOTO( x, y );
GFX_WRITE( '_' );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_WRITE( '/' );
GFX_WRITE( '>' );
GFX_GOTO( x, y+1 );
GFX_WRITE( '\\' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( '\\' );
GFX_GOTO( x, y+2 );
GFX_WRITE( '<' );
GFX_WRITE( '_' );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_WRITE( '/' );
break;
}
}
#endif

+ 121
- 0
collide.c ファイルの表示

@@ -0,0 +1,121 @@

#include <stdlib.h>

#include "common.h"

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

for( i = 0; i < SHOTS; i++ )
{
if( wp->y[i] >= 0 )
{
if( wp->x[i] <= t->left[wp->y[i]+1]
|| wp->x[i] >= t->right[wp->y[i]+1] )
{
add_explosion( g, ex, wp->x[i], wp->y[i]+1, 0, 1, 0 );

if( wp->x[i] <= t->left[wp->y[i]+1] )
{
t->left[wp->y[i]]--;
t->left[wp->y[i]+1]-=2;
t->left[wp->y[i]+2]--;
}
else
{
t->right[wp->y[i]]++;
t->right[wp->y[i]+1]+=2;
t->right[wp->y[i]+2]++;
}

wp->y[i] = -1;
}
else if( wp->x[i] <= t->left[wp->y[i]]
|| wp->x[i] >= t->right[wp->y[i]] )
{
add_explosion( g, ex, wp->x[i], wp->y[i], 0, 1, 0 );

if( wp->x[i] <= t->left[wp->y[i]] )
{
t->left[wp->y[i]-1]--;
t->left[wp->y[i]]-=2;
t->left[wp->y[i]+1]--;
}
else
{
t->right[wp->y[i]-1]++;
t->right[wp->y[i]]+=2;
t->right[wp->y[i]+1]++;
}

wp->y[i] = -1;
}
}
}
}

void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex )
{
int i, j;

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

for( j = 0; j < ALIENS; j++ )
{
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->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;
}
}

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

void collide_player_tunnel( game *g, player *p, tunnel *t, explosions *ex )
{
if( p->x <= t->left[p->y] )
{
p->x += 3;
//add_explosion( g, ex, x+1, y-2, 0, 1, 0 );
}
else if( p->x + 5 >= t->right[p->y] )
{
p->x -= 3;
//add_explosion( g, ex, x+4, y-2, 0, 1, 0 );
}
}


+ 130
- 0
common.h ファイルの表示

@@ -0,0 +1,130 @@

#define STARS 50
#define SHOTS 50
#define ROCKS 10
#define ALIENS 10
#define EXPLOSIONS 20

#ifdef USE_SLANG
# include <slang.h>
# define GFX_COLOR(x) SLsmg_set_color(x)
# define GFX_GOTO(x,y) SLsmg_gotorc(y,x)
# define GFX_WRITE(x) SLsmg_write_char(x)
#else
# include <curses.h>
# define GFX_COLOR(x) attrset(COLOR_PAIR(x))
# define GFX_GOTO(x,y) move(y,x)
# define GFX_WRITE(x) addch(x)
#endif

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

typedef struct
{
int w, h;

} game;

typedef struct
{
int w, h, *left, *right;

} tunnel;

typedef struct
{
int x[STARS];
int y[STARS];
int z[STARS];
char ch[STARS];
int c[STARS];

} starfield;

typedef struct
{
int x[EXPLOSIONS];
int y[EXPLOSIONS];
int vx[EXPLOSIONS];
int vy[EXPLOSIONS];
int type[EXPLOSIONS];
int n[EXPLOSIONS];

} explosions;

typedef struct
{
int x[SHOTS];
int y[SHOTS];
int v[SHOTS];

} weapons;

typedef struct
{
int x, y;
int dir;
int weapon;

} player;

typedef struct
{
int x[ALIENS];
int y[ALIENS];
int life[ALIENS];
int img[ALIENS];

} aliens;

#define BLACK 1
#define GREEN 2
#define YELLOW 3
#define WHITE 4
#define RED 5
#define GRAY 6
#define LIGHTGRAY 7
#define BLUE 8
#define CYAN 9
#define MAGENTA 10

void collide_weapons_tunnel( game *g, weapons *wp, tunnel *t, explosions *ex );
void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex );
void collide_player_tunnel( game *g, player *p, tunnel *t, explosions *ex );

void init_aliens( game *g, aliens *al );
void draw_aliens( game *g, aliens *al );
void update_aliens( game *g, aliens *al );
void add_alien( game *g, aliens *al, int x, int y );

int init_graphics( void );
void init_game( game *g );
char get_key( void );
void clear_graphics( void );
void refresh_graphics( void );
void end_graphics( void );

player * create_player( game *g );
void free_player( player *p );
void draw_player( game *g, player *p );
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 init_starfield( game *g, starfield *s );
void draw_starfield( game *g, starfield *s );
void update_starfield( game *g, starfield *s );

tunnel * create_tunnel( game *g, int w, int h );
void free_tunnel( tunnel *t );
void draw_tunnel( game *g, tunnel *t );
void update_tunnel( game *g, tunnel *t );

void init_explosions( game *g, explosions *ex );
void add_explosion( game *g, explosions *ex, int x, int y, int vx, int vy, int type );
void draw_explosions( game *g, explosions *ex );
void update_explosions( game *g, explosions *ex );


+ 405
- 0
explosions.c ファイルの表示

@@ -0,0 +1,405 @@

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

for( i = 0; i < EXPLOSIONS; i++ )
{
ex->n[i] = 0;
ex->x[i] = -1;
ex->y[i] = -1;
ex->vx[i] = -1;
ex->vy[i] = -1;
ex->type[i] = 0;
}
}

void add_explosion( game *g, explosions *ex, int x, int y, int vx, int vy, int type )
{
int i;

for( i = 0; i < EXPLOSIONS; i++ )
{
if( ex->n[i] <= 0 )
{
ex->x[i] = x;
ex->y[i] = y;
ex->vx[i] = vx;
ex->vy[i] = vy;
switch( type )
{
case 1: ex->n[i] = 13; break;
case 2: ex->n[i] = 30; break;
case 0: default: ex->n[i] = 7; break;
}
ex->type[i] = type;
break;
}
}
}

void draw_explosions( game *g, explosions *ex )
{
int i;

for( i = 0; i < EXPLOSIONS; i++ )
{
if( ex->n[i] <= 0 )
{
continue;
}

#if 0
GFX_COLOR( GREEN );
GFX_GOTO( ex->x[i] + 3, ex->y[i] );
switch( GET_RAND(0,3) )
{
case 0:
GFX_WRITE( 'p' );
GFX_WRITE( 'i' );
GFX_WRITE( 'f' );
break;
case 1:
GFX_WRITE( 'p' );
GFX_WRITE( 'a' );
GFX_WRITE( 'f' );
break;
case 2:
GFX_WRITE( 'p' );
GFX_WRITE( 'o' );
GFX_WRITE( 'u' );
GFX_WRITE( 'f' );
break;
}
GFX_WRITE( '!' );
#endif

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;
case 0:
default:
draw_small_explosion( ex->x[i], ex->y[i], ex->n[i] );
break;
}

}
}

void update_explosions( game *g, explosions *ex )
{
int i;

for( i = 0; i < EXPLOSIONS; i++ )
{
if( ex->n[i] > 0 )
{
ex->x[i] += ex->vx[i];
ex->y[i] += ex->vy[i];
ex->n[i]--;
}
}
}

static void draw_small_explosion( int x, int y, int frame )
{
switch( frame )
{
default:
case 6:
GFX_COLOR( YELLOW );
GFX_GOTO( x, y );
GFX_WRITE( '+' );
break;
case 5:
GFX_COLOR( YELLOW );
GFX_GOTO( x, y );
GFX_WRITE( 'o' );
break;
case 4:
GFX_COLOR( YELLOW );
GFX_GOTO( x, y-1 );
GFX_WRITE( '_' );
GFX_GOTO( x-1, y );
GFX_WRITE( ')' );
GFX_WRITE( '_' );
GFX_WRITE( '(' );
break;
case 3:
GFX_COLOR( YELLOW );
GFX_GOTO( x-1, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( '_' );
GFX_WRITE( ',' );
GFX_GOTO( x-1, y );
GFX_WRITE( ')' );
GFX_WRITE( '_' );
GFX_WRITE( '(' );
GFX_GOTO( x-1, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( ' ' );
GFX_WRITE( '`' );
break;
case 2:
GFX_COLOR( YELLOW );
GFX_GOTO( x-1, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( 'v' );
GFX_WRITE( ',' );
GFX_GOTO( x-1, y );
GFX_WRITE( '>' );
GFX_WRITE( ' ' );
GFX_WRITE( '<' );
GFX_GOTO( x-1, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( '^' );
GFX_WRITE( '`' );
break;
case 1:
GFX_COLOR( WHITE );
GFX_GOTO( x-1, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( ' ' );
GFX_WRITE( ',' );
GFX_GOTO( x-1, y );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_GOTO( x-1, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( ' ' );
GFX_WRITE( '`' );
break;
}
}

static void draw_big_explosion( int x, int y, int frame )
{
GFX_COLOR( YELLOW );

switch( frame )
{
default:
case 12:
GFX_GOTO( x, y );
GFX_WRITE( '+' );
break;
case 11:
GFX_GOTO( x, y );
GFX_WRITE( 'o' );
break;
case 10:
GFX_GOTO( x, y-1 );
GFX_WRITE( '_' );
GFX_GOTO( x-1, y );
GFX_WRITE( ')' );
GFX_WRITE( '_' );
GFX_WRITE( '(' );
break;
case 9:
GFX_GOTO( x-1, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( '_' );
GFX_WRITE( ',' );
GFX_GOTO( x-1, y );
GFX_WRITE( ')' );
GFX_WRITE( '_' );
GFX_WRITE( '(' );
GFX_GOTO( x-1, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( ' ' );
GFX_WRITE( '`' );
break;
case 8:
GFX_GOTO( x-1, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( 'v' );
GFX_WRITE( ',' );
GFX_GOTO( x-1, y );
GFX_WRITE( '>' );
GFX_WRITE( ' ' );
GFX_WRITE( '<' );
GFX_GOTO( x-1, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( '^' );
GFX_WRITE( '`' );
break;
case 6:
GFX_COLOR( RED );
case 7:
case 5:
GFX_GOTO( x-2, y-1 );
GFX_WRITE( '_' );
GFX_WRITE( '\\' );
GFX_WRITE( '~' );
GFX_WRITE( '/' );
GFX_WRITE( '_' );
GFX_GOTO( x-2, y );
GFX_WRITE( '>' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( '<' );
GFX_GOTO( x-2, y+1 );
GFX_WRITE( '~' );
GFX_WRITE( '/' );
GFX_WRITE( '_' );
GFX_WRITE( '\\' );
GFX_WRITE( '~' );
break;
case 3:
GFX_COLOR( RED );
case 4:
case 2:
GFX_GOTO( x-2, y-1 );
GFX_WRITE( '_' );
GFX_WRITE( '\\' );
GFX_WRITE( ' ' );
GFX_WRITE( '/' );
GFX_WRITE( '_' );
GFX_GOTO( x-2, y );
GFX_WRITE( '_' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( '_' );
GFX_GOTO( x-2, y+1 );
GFX_WRITE( ' ' );
GFX_WRITE( '/' );
GFX_WRITE( ' ' );
GFX_WRITE( '\\' );
GFX_WRITE( ' ' );
break;
case 1:
GFX_COLOR( WHITE );
GFX_GOTO( x-2, y-1 );
GFX_WRITE( '.' );
GFX_WRITE( ' ' );
GFX_WRITE( '\'' );
GFX_WRITE( ' ' );
GFX_WRITE( ',' );
GFX_GOTO( x-2, y );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_WRITE( ' ' );
GFX_GOTO( x-2, y+1 );
GFX_WRITE( '\'' );
GFX_WRITE( ' ' );
GFX_WRITE( '.' );
GFX_WRITE( ' ' );
GFX_WRITE( '`' );
break;
}
}

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

}


+ 129
- 0
graphics.c ファイルの表示

@@ -0,0 +1,129 @@

#include <stdlib.h>

#include "common.h"

int init_graphics( void )
{
#ifdef USE_SLANG
/* Initialize slang library */
SLsig_block_signals();
SLtt_get_terminfo();

if( SLkp_init() == -1 )
{
SLsig_unblock_signals();
return 1;
}

SLang_init_tty (-1, 0, 1);

if( SLsmg_init_smg() == -1 )
{
SLsig_unblock_signals();
return 1;
}

SLsig_unblock_signals();

SLsmg_cls();
SLsmg_refresh();
#else
/* Initialize ncurses library */
initscr();
keypad(stdscr, TRUE);
nonl();
cbreak();
noecho();
nodelay(stdscr, TRUE);
#endif

return 0;
}

void init_game( game *g )
{
#ifdef USE_SLANG
static char * const colors[] =
{
"black", "green", "yellow", "white",
"red", "gray", "lightgray", "blue", "cyan", "magenta", NULL
};

int i;

for( i = 0; colors[i] ; i++ )
{
SLtt_set_color( i+1, NULL, colors[i], "black" );
}

g->w = SLtt_Screen_Cols;
g->h = SLtt_Screen_Rows;
#else
start_color();

init_pair( BLACK, COLOR_BLACK, COLOR_BLACK );
init_pair( GREEN, COLOR_GREEN, COLOR_BLACK );
init_pair( YELLOW, COLOR_YELLOW, COLOR_BLACK );
init_pair( WHITE, COLOR_WHITE, COLOR_BLACK );
init_pair( RED, COLOR_RED, COLOR_BLACK );
init_pair( GRAY, COLOR_WHITE, COLOR_BLACK ); // XXX
init_pair( LIGHTGRAY, COLOR_WHITE, COLOR_BLACK ); // XXX
init_pair( BLUE, COLOR_BLUE, COLOR_BLACK );
init_pair( CYAN, COLOR_CYAN, COLOR_BLACK );
init_pair( MAGENTA, COLOR_MAGENTA, COLOR_BLACK );

g->w = COLS;
g->h = LINES;
#endif
}

char get_key( void )
{
#ifdef USE_SLANG
if( SLang_input_pending (0) )
{
return SLang_getkey();
}
#else
char key;

if( ( key = getch() ) != ERR )
{
return key;
}
#endif

return 0;
}

void clear_graphics( void )
{
#ifdef USE_SLANG
SLsmg_cls();
#else
clear();
#endif
}

void refresh_graphics( void )
{
GFX_GOTO( 0, 0 );
#ifdef USE_SLANG
SLsmg_refresh();
#else
refresh();
#endif
}

void end_graphics( void )
{
#ifdef USE_SLANG
SLang_reset_tty();
SLsmg_reset_smg();
#else
endwin();
#endif
}



+ 179
- 0
main.c ファイルの表示

@@ -0,0 +1,179 @@
/*
* ttyvaders - a tty based shoot'em'up
* Copyright (C) 2002 Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <unistd.h>

#include "common.h"

static void start_game (game *);

int main (int argc, char **argv)
{
game *g = malloc(sizeof(game));

// srand(time(NULL));

if( init_graphics() )
{
return 1;
}

/* Initialize our program */
init_game(g);

/* Go ! */
start_game(g);

/* Clean up */
end_graphics();

return 0;
}

static void start_game (game *g)
{
int i;
int quit = 0;
int poz = 0;
int skip = 0;

starfield *sf = malloc(sizeof(starfield));
weapons *wp = malloc(sizeof(weapons));
explosions *ex = malloc(sizeof(explosions));
tunnel *t = create_tunnel( g, g->w, g->h );
player *p = create_player( g );
aliens *al = malloc(sizeof(aliens));

init_starfield( g, sf );
init_weapons( g, wp );
init_explosions( g, ex );
init_aliens( g, al );

/* Temporary stuff */
for( i = 0; i < 5; i++ )
{
add_alien( g, al, rand() % g->w, rand() % g->h / 2 );
}
t->w = 25;

while( !quit )
{
char key;

while( ( key = get_key() ) )
{
switch( key )
{
case 'q':
quit = 1;
break;
case 'p':
poz = !poz;
break;
case 's':
skip = 1;
break;
case 'h':
p->dir = -3;
break;
case 'j':
//if( p->y < g->h - 2 ) p->y += 1;
break;
case 'k':
//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 );
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 );
}
break;
}
}

usleep(40000);

if( GET_RAND(0,10) == 0 )
{
add_alien( g, al, 0, rand() % g->h / 2 );
}

if( poz )
{
if( skip )
{
skip = 0;
}
else
{
continue;
}
}

/* Scroll and update positions */
collide_player_tunnel( g, p, t, ex );
update_player( g, p );
collide_player_tunnel( g, p, t, ex );

update_starfield( g, sf );
update_aliens( g, al );

collide_weapons_tunnel( g, wp, t, ex );
collide_weapons_aliens( g, wp, al, ex );
update_weapons( g, wp );
collide_weapons_tunnel( g, wp, t, ex );
collide_weapons_aliens( g, wp, al, ex );

update_explosions( g, ex );
update_tunnel( g, t );

/* Clear screen */
clear_graphics();

/* Print starfield, tunnel, aliens, player and explosions */
draw_starfield( g, sf );
draw_tunnel( g, t );
draw_aliens( g, al );
draw_player( g, p );
draw_weapons( g, wp );
draw_explosions( g, ex );

/* Refresh */
refresh_graphics();
}

#if 0
free_player( p );
free_tunnel( t );
#endif
}


+ 68
- 0
player.c ファイルの表示

@@ -0,0 +1,68 @@

#include <stdlib.h>

#include "common.h"

/* Init tunnel */
player * create_player( game *g )
{
player *p = malloc(sizeof(player));

p->x = g->w / 2;
p->y = g->h - 3;
p->dir = 0;
p->weapon = 0;

return p;
}

void free_player( player *p )
{
free( p );
}

void draw_player( game *g, player *p )
{
GFX_GOTO( p->x + 2, p->y - 2 );
GFX_COLOR( GREEN );
GFX_WRITE( '/' );
GFX_WRITE( '\\' );
GFX_GOTO( p->x + 1, p->y - 1 );
GFX_WRITE( '(' );
GFX_COLOR( YELLOW );
GFX_WRITE( '(' );
GFX_WRITE( ')' );
GFX_COLOR( GREEN );
GFX_WRITE( ')' );
GFX_GOTO( p->x, p->y );
GFX_COLOR( GREEN );
GFX_WRITE( 'I' );
GFX_WRITE( '<' );
GFX_WRITE( '_' );
GFX_WRITE( '_' );
GFX_WRITE( '>' );
GFX_WRITE( 'I' );
}

void update_player( game *g, player *p )
{
if( p->weapon )
{
p->weapon--;
}

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

p->dir++;
}
else if( p->dir > 0 )
{
if( p->dir == 3 && p->x < g->w - 8 ) p->x += 1;
else if( p->x < g->w - 7 ) p->x += 1;
p->dir--;
}
}


+ 135
- 0
shapes.txt ファイルの表示

@@ -0,0 +1,135 @@

Starship
--------

/\
(())
I<__>I


Aliens
------

,---. ,---.
\O o/ \o O/
^^^^^ ^^^^^

Shots
-----

| / _, ___ \
| / ' \


| __/ \__ |
/ \


\ __ __ /
| \ / |


Explosions
----------

| .v, .v, .v, .v, .v, .v, . ,
+ o -o- >o< >o< >o< >o< > < > <
| '^` '^` '^` '^` '^` '^` ' `

.|, .v, .v, .v, .v, .v, . ,
+ o -o- --o-- > o < >( )< > < > o < >( )< - -
'|` '^` '^` '^` '^` '^` ' `

_ ._, .v, _\~/_ _\ /_ . ' ,
+ o )_( )_( > < > < _ _
' ` '^` ~/_\~ / \ ' . `

_ ._, .v, . ,
+ o )_( )_( > <
' ` '^` ' `



#######
### ###
## ##
# #
# #
# #
## ##
### ###
#######

_______
,-'_______`-.
,',-' _____ `-.`.
/ / ,' ___ `. \ \
| | / ,' _ `. \ | |
| | | | |_| | | | |
| | \ `.___,' / | |
\ \ `._____,' / /
`.`-._______,-','
`-._______,-'































































+ 59
- 0
starfield.c ファイルの表示

@@ -0,0 +1,59 @@

#include <stdlib.h>

#include "common.h"

void init_starfield( game *g, starfield *s )
{
int i;

for( i = 0; i < STARS; i++ )
{
s->x[i] = rand() % g->w;
s->y[i] = rand() % g->h;
s->z[i] = 1 + rand() % 3;
s->ch[i] = (rand() % 2) ? '.' : '\'';
s->c[i] = 6 + rand() % 2;
}
}

void draw_starfield( game *g, starfield *s )
{
int i;

for( i = 0; i < STARS; i++ )
{
if( s->x[i] >= 0 )
{
GFX_COLOR( s->c[i] );
GFX_GOTO( s->x[i], s->y[i] );
GFX_WRITE( s->ch[i] );
}
}
}

void update_starfield( game *g, starfield *s )
{
int i;

for( i = 0; i < STARS; i++ )
{
if( s->x[i] < 0 )
{
s->x[i] = rand() % g->w;
s->y[i] = 0;
s->z[i] = 1 + rand() % 2;
s->ch[i] = (rand() % 2) ? '.' : '\'';
s->c[i] = 6 + rand() % 2;
}
else if( s->y[i] < g->h-1 )
{
s->y[i] += s->z[i];
}
else
{
s->x[i] = -1;
}
}
}


+ 171
- 0
tunnel.c ファイルの表示

@@ -0,0 +1,171 @@

#include <stdlib.h>

#include "common.h"

static void draw_wall( game *g, int *wall );

/* Init tunnel */
tunnel * create_tunnel( game *g, int w, int h )
{
int i;
tunnel *t = malloc(sizeof(tunnel));

t->left = malloc(h*sizeof(int));
t->right = malloc(h*sizeof(int));
t->w = w;
t->h = h;

if( t->w >= g->w )
{
t->left[0] = -1;
t->right[0] = g->w;
for( i = 0; i < g->h; i++ )
{
t->left[i] = -1;
t->right[i] = g->w;
}
}
else
{
t->left[0] = (g->w - w) / 2;
t->right[0] = (g->w + w) / 2;
/* Yeah, sub-efficient, but less code to do :-) */
for( i = 0; i < g->h; i++ )
{
update_tunnel( g, t );
}
}

return t;
}

void free_tunnel( tunnel *t )
{
free( t->left );
free( t->right );
free( t );
}

void draw_tunnel( game *g, tunnel *t )
{
/* Print tunnel */
draw_wall( g, t->left );
draw_wall( g, t->right );
}

void update_tunnel( game *g, tunnel *t )
{
static int const delta[] = { -2, -1, 1, 2 };
int i,j,k;

/* Slide tunnel one block vertically */
for( i = t->h; i--; )
{
t->left[i+1] = t->left[i];
t->right[i+1] = t->right[i];
}

/* Generate new values */
i = delta[GET_RAND(0,4)];
j = delta[GET_RAND(0,4)];

/* Check in which direction we need to alter tunnel */
if( t->right[1] - t->left[1] < t->w )
{
/* Not wide enough */
if( i > j )
{
k = j; j = i; i = k;
}
}
else if( t->right[1] - t->left[1] - 2 > t->w )
{
/* Too wide */
if( i < j )
{
k = j; j = i; i = k;
}
}
else
{
/* No need to mess with i and j: width is OK */
}

/* If width doesn't exceed game size, update coords */
if( t->w <= g->w || t->right[1] - t->left[1] < t->w )
{
t->left[0] = t->left[1] + i;
t->right[0] = t->right[1] + j;
}
else
{
t->left[0] = -1;
t->right[0] = g->w;
}

if( t->w > g->w )
{
if( t->left[0] < 0 && t->right[0] < g->w - 2 )
{
t->left[0] = t->left[1] + 1;
}

if( t->left[0] > 1 && t->right[0] > g->w - 1 )
{
t->right[0] = t->right[1] - 1;
}
}
else
{
if( t->left[0] < 0 )
{
t->left[0] = t->left[1] + 1;
}

if( t->right[0] > g->w - 1 )
{
t->right[0] = t->right[1] - 1;
}
}
}

static void draw_wall( game *g, int *wall )
{
int i;

for( i = 0; i < g->h ; i++ )
{
char c;

if( wall[i] < 0 || wall[i] >= g->w )
{
continue;
}

if( wall[i] > wall[i+1] )
{
c = wall[i] > wall[i-1] ? '>' : '/';
}
else
{
c = wall[i] > wall[i-1] ? '\\' : '<';
}

GFX_COLOR( RED );
if( wall[i] == wall[i+1] + 2 )
{
GFX_GOTO( wall[i] - 1, i );
GFX_WRITE( '_' );
}
else
{
GFX_GOTO( wall[i], i );
}
GFX_WRITE( c );
GFX_WRITE( '#' );
GFX_WRITE( c );
if( wall[i] == wall[i+1] - 2 ) GFX_WRITE( '_' );
}
}


+ 71
- 0
weapons.c ファイルの表示

@@ -0,0 +1,71 @@

#include <stdlib.h>

#include "common.h"

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

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

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

for( i = 0; i < SHOTS; 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( '|' );
}
}
}

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

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

/* Check collisions */
}
}
}

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

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


読み込み中…
キャンセル
保存