This is Explosion.m in view mode; [Download] [Up]
#import "Explosion.h"
#define DO_ROCKET 1
#define DO_EXPLOSION 2
/*
arrays for precalculated rotation
*/
float points0[] = { 4.0, 0.0, -6, 3.5, 0.0, -7, 6.0, 3.5 };
float points20[] = { 3.8, 1.4, -6.9, 1.2, 2.4, -6.5, 4.5, 5.3 };
float points40[] = { 3.0, 2.6, -6.8, -1.2, 4.5, -5.4, 2.3, 6.6 };
float points60[] = { 2.0, 3.4, -6.0, -3.4, 6.0, -3.5, 0.0, 7.0 };
float points80[] = { 0.7, 3.9, -4.5, -5.3, 6.8, -1.2, -2.3, 6.5 };
float points100[] = { -0.7, 4.0, -2.4, -6.5, 7.0, 1.1, -3.1, 5.4 };
float qpoints0[] = { 6.0, 0.0, -6.0, 6.0, -6.0, -6.0, 6.0, -6.0, 6.0, 6.0 };
float qpoints30[] = { 5.2, 3.0, -8.2, 2.2, -2.2, -8.2, 8.2, -2.2, 2.2, 8.2 };
float qpoints60[] = { 3.0, 5.2, -8.2, -2.2, 2.2, -8.2, 8.2, 2.2, -2.2, 8.2 };
float colorTab[ 7 ][ 3 ] = { { 1.0, 1.0, 1.0 },
{ 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 },
{ 1.0, 1.0, 0.0 },
{ 0.0, 1.0, 1.0 },
{ 1.0, 0.0, 1.0 } };
int sequences[ 6 ][ 6 ] = { { 0, 1, 2, 3, 4, 5 },
{ 5, 4, 3, 2, 1, 0 },
{ 0, 2, 4, 0, 2, 4 },
{ 4, 2, 0, 4, 2, 0 },
{ 0, 3, 0, 3, 0, 3 },
{ 3, 0, 3, 0, 3, 0 } };
@implementation Explosion
- init
{
int loop,
to;
[ super init ];
to = time( 0 ) % 16;
for( loop = 0; loop < to; loop++ )
rand();
qani = qdelay = 0;
colorMode = NO;
return self;
}
- initStart:( NXRect *)aRect withPlots:( int )Plots mode:( BOOL )aMode
{
maxPlot = Plots;
colorMode = aMode;
cArray0 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
cArray20 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
cArray40 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
cArray60 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
cArray80 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
cArray100 = ( float * )malloc( 10 * maxPlot * sizeof( float ) );
oArray = ( char * )malloc( 2 + 5 * maxPlot * sizeof( char ) );
theRect.size.width = aRect -> size.width;
theRect.size.height = aRect -> size.height;
theRect.origin.x = aRect -> origin.x;
theRect.origin.y = aRect -> origin.y;
[ self initPlots ];
[ self initRocket ];
simMode = DO_ROCKET;
return self;
}
- free
{
free( cArray0 );
free( cArray20 );
free( cArray40 );
free( cArray60 );
free( cArray80 );
free( cArray100 );
free( oArray );
return( [ super free ] );
}
- doSim
{
if( simMode == DO_ROCKET )
[ self moveRocket ];
else if( simMode == DO_EXPLOSION )
[ self moveExplosion ];
return self;
}
- clearSim
{
PSsetgray( 0 );
if( simMode == DO_ROCKET )
[ self showRocket ];
else if( simMode == DO_EXPLOSION )
[ self showExplosion ];
return self;
}
- showSim
{
if( colorMode == NO )
PSsetgray( 1 );
else
PSsetrgbcolor( colorTab[ color ][ 0 ], colorTab[ color ][ 1 ],
colorTab[ color ][ 2 ] );
if( simMode == DO_ROCKET )
[ self showRocket ];
else if( simMode == DO_EXPLOSION )
[ self showExplosion ];
return self;
}
- initExplosion
{
int loop,
first,
toggle;
float dx,
dy,
trand,
check,
destx,
desty,
randtab[] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
deadCount = toggle = 0;
for( loop = 0; loop < maxPlot; loop++ )
{
plots[ loop ].currx = explosionx;
plots[ loop ].curry = explosiony;
/*
set virtual destination point for 'explosionpart'
*/
destx = rand() % 300 - rand() % 300 + explosionx;
desty = rand() % ( int )( theRect.size.height ) + explosiony -150;
if( desty < 50 )
desty = 50;
if( desty == explosiony )
desty += 50;
if( destx == explosionx )
destx += 50;
/*
delay for first movement of 'explosionpart'
*/
plots[ loop ].delay = rand() % 5;
/*
calculate x/y speed
*/
dx = abs( plots[ loop ].currx - destx );
dy = abs( plots[ loop ].curry - desty );
if( dx > dy )
{
plots[ loop ].mx = 1.0;
plots[ loop ].my = dy / dx;
check = plots[ loop ].mx / plots[ loop ].my;
plots[ loop ].count = ( int )( dx / ( int )( plots[ loop ].mx ) + 1 );
}
else
{
plots[ loop ].mx = dx / dy;
plots[ loop ].my = 1.0;
check = plots[ loop ].my / plots[ loop ].mx;
plots[ loop ].count = ( int )( dy / ( int )( plots[ loop ].my ) + 1 );
}
if( plots[ loop ].curry > desty )
plots[ loop ].my *= -1;
if( plots[ loop ].currx > destx )
plots[ loop ].mx *= -1;
/*
speedup 'explosionparts'
*/
trand = randtab[ rand() % 10 ] * ( rand() % 7 ) +2;
plots[ loop ].mx *= trand;
plots[ loop ].my *= trand;
/*
slowdown parts with diagonal direction
*/
if( check < 1.5 )
{
plots[ loop ].mx *= .8;
plots[ loop ].my *= .8;
}
/*
generate 'explosionpart' lifetime
*/
plots[ loop ].count = rand() % 30 + 30;
/*
set rotation direction
*/
if( rand() % 100 > 50 )
plots[ loop ].sequence = 0;
else
plots[ loop ].sequence = 1;
plots[ loop ].sequencecount = 0 ;
}
[ self preparePlots ];
first = 0;
scount = 0;
return self;
}
- moveExplosion
{
if( deadCount < maxPlot )
{
[ self toPos ];
[ self preparePlots ];
}
else
{
[ self initRocket ];
simMode = DO_ROCKET;
}
return self;
}
- showExplosion
{
switch( scount )
{
case 0:
case 5:
if( ci0 > 0 )
DPSDoUserPath( cArray0, ci0, dps_float, oArray, ( ci0 /2 +2 ),
bbox, dps_ustroke );
if( ci100 > 0 )
DPSDoUserPath( cArray100, ci100, dps_float, oArray, ( ci100 /2 +2 ),
bbox, dps_ustroke );
break;
case 1:
case 4:
if( ci20 > 0 )
DPSDoUserPath( cArray20, ci20, dps_float, oArray, ( ci20 /2 +2 ),
bbox, dps_ustroke );
if( ci80 > 0 )
DPSDoUserPath( cArray80, ci80, dps_float, oArray, ( ci80 /2 +2 ),
bbox, dps_ustroke );
break;
case 2:
case 3:
if( ci40 > 0 )
DPSDoUserPath( cArray40, ci40, dps_float, oArray, ( ci40 /2 +2 ),
bbox, dps_ustroke );
if( ci60 > 0 )
DPSDoUserPath( cArray60, ci60, dps_float, oArray, ( ci60 /2 +2 ),
bbox, dps_ustroke );
break;
}
return self;
}
/*
explosion simulation
*/
- toPos
{
int loop;
float tmpcurrx,
tmpcurry,
tmpmx,
tmpmy;
scount++;
if( scount > 5 )
scount = 0;
for( loop = 0; loop < maxPlot; loop++ )
{
if( plots[ loop ].delay > 0 )
plots[ loop ].delay--;
if( plots[ loop ].count != 0 && plots[ loop ].delay == 0 )
{
tmpmx = plots[ loop ].mx;
tmpmy = plots[ loop ].my;
tmpcurrx = plots[ loop ].currx;
tmpcurry = plots[ loop ].curry;
tmpcurrx += tmpmx;
tmpcurry += tmpmy;
plots[ loop ].count--;
if( abs( tmpmx ) > 1 )
tmpmx *= 0.97;
if( tmpmy > -3 )
tmpmy -= 0.2;
if( tmpcurrx >= theRect.size.width -6 || tmpcurrx <= 0 ||
tmpcurry >= theRect.size.height -6 || tmpcurry <= 0 )
{
tmpcurrx = -5;
tmpcurry = -5;
plots[ loop ].count = 0;
deadCount++;
}
else if( plots[ loop ].count <= 0 )
{
deadCount++;
tmpcurrx = -5;
tmpcurry = -5;
}
plots[ loop ].mx = tmpmx;
plots[ loop ].my = tmpmy;
plots[ loop ].currx = tmpcurrx;
plots[ loop ].curry = tmpcurry;
}
}
return self;
}
- preparePlots
{
int loop;
ci0 = ci20 = ci40 = ci60 = ci80 = ci100 = 0;
for( loop = 0; loop < maxPlot; loop++ )
{
switch( sequences[ plots[ loop ].sequence ][ scount ] )
{
case 0:
*( cArray0 + ci0++ ) = plots[ loop ].currx + *( points0 );
*( cArray0 + ci0++ ) = plots[ loop ].curry + *( points0 +1 );
ci0 += 6;
break;
case 1:
*( cArray20 + ci20++ ) = plots[ loop ].currx + *( points20 );
*( cArray20 + ci20++ ) = plots[ loop ].curry + *( points20 +1 );
ci20 += 6;
break;
case 2:
*( cArray40 + ci40++ ) = plots[ loop ].currx + *( points40 );
*( cArray40 + ci40++ ) = plots[ loop ].curry + *( points40 +1 );
ci40 += 6;
break;
case 3:
*( cArray60 + ci60++ ) = plots[ loop ].currx + *( points60 );
*( cArray60 + ci60++ ) = plots[ loop ].curry + *( points60 +1 );
ci60 += 6;
break;
case 4:
*( cArray80 + ci80++ ) = plots[ loop ].currx + *( points80 );
*( cArray80 + ci80++ ) = plots[ loop ].curry + *( points80 +1 );
ci80 += 6;
break;
case 5:
*( cArray100 + ci100++ ) = plots[ loop ].currx + *( points100 );
*( cArray100 + ci100++ ) = plots[ loop ].curry + *( points100 +1 );
ci100 += 6;
break;
}
}
return self;
}
- initRocket
{
speedf = theRect.size.height / 70;
gravsim = speedf / 90;
gravdelay = rand() % 20;
startx = ( rand() % ( int )( theRect.size.width -100 ) ) + 50;
starty = -10;
rdestx = ( rand() % ( int )( theRect.size.width -150 ) ) + 75;
rdesty = rand() % ( int )( theRect.size.height / 3.0 ) + theRect.size.height / 3.0 * 2 -100;
if( rdestx < 90 )
rdestx = 90;
vx = abs( startx - rdestx );
vy = rdesty;
if( vx / vy > 1 )
{
vy = vy / vx * speedf - rand() % 2;
steps = abs( startx - rdestx ) / vx + rand() % 100 + 10;
}
else
{
vy = speedf - rand() % 2;;
steps = rdesty / vy + rand() % 100 + 10;
}
vx = rand() %4 +1;
if( vy > speedf )
vy = speedf;
if( rdestx < startx )
vx *= -1;
if( colorMode == YES )
color = rand() %7;
startx += qpoints0[ 0 ];
starty += qpoints0[ 1 ];
qcArray0[ 0 ] = qcArray30[ 0 ] = qcArray60[ 0 ] = startx;
qcArray0[ 1 ] = qcArray30[ 1 ] = qcArray60[ 1 ] = starty;
return self;
}
- showRocket
{
switch( qani )
{
case 0:
DPSDoUserPath( qcArray0, 10, dps_float, roArray, 7, bbox, dps_ustroke );
break;
case 1:
DPSDoUserPath( qcArray30, 10, dps_float, roArray, 7, bbox, dps_ustroke );
break;
case 2:
DPSDoUserPath( qcArray60, 10, dps_float, roArray, 7, bbox, dps_ustroke );
break;
}
return self;
}
- moveRocket
{
startx += vx;
starty += vy;
steps--;
if( gravdelay > 0 )
gravdelay--;
else
vy -= gravsim;
/*
animation delay
*/
qdelay++;
if( qdelay > 1 )
{
qdelay = 0;
qani++;
if( qani > 2 )
qani = 0;
}
switch( qani )
{
case 0:
qcArray0[ 0 ] = startx + qpoints0[ 0 ];
qcArray0[ 1 ] = starty + qpoints0[ 1 ];
break;
case 1:
qcArray30[ 0 ] = startx + qpoints30[ 0 ];
qcArray30[ 1 ] = starty + qpoints30[ 1 ];
break;
case 2:
qcArray60[ 0 ] = startx + qpoints60[ 0 ];
qcArray60[ 1 ] = starty + qpoints60[ 1 ];
break;
}
if( startx > theRect.size.width -50 || startx < 50 ||
starty > theRect.size.height - 50 || ( starty < 50 && vy < 0 ) )
{
qani = 4;
steps = 0;
}
if( steps == 0 )
{
explosionx = startx;
explosiony = starty;
[ self initExplosion ];
simMode = DO_EXPLOSION;
}
return self;
}
- initPlots
{
int loop,
oi = 0,
ci = 0;
/*
setup 'explosion array' for userpath
*/
oArray[oi++] = dps_ucache;
oArray[oi++] = dps_setbbox;
for( loop = 0; loop < maxPlot; loop++ )
{
cArray0[ ci ] = plots[ loop ].currx;
cArray0[ ci +1 ] = plots[ loop ].curry;
cArray20[ ci ] = plots[ loop ].currx;
cArray20[ ci +1 ] = plots[ loop ].curry;
cArray40[ ci ] = plots[ loop ].currx;
cArray40[ ci +1 ] = plots[ loop ].curry;
cArray60[ ci ] = plots[ loop ].currx;
cArray60[ ci +1 ] = plots[ loop ].curry;
cArray80[ ci ] = plots[ loop ].currx;
cArray80[ ci +1 ] = plots[ loop ].curry;
cArray100[ ci++ ] = plots[ loop ].currx;
cArray100[ ci++ ] = plots[ loop ].curry;
oArray[ oi++ ] = dps_moveto;
cArray0[ ci ] = points0[ 2 ];
cArray0[ ci +1 ] = points0[ 3 ];
cArray20[ ci ] = points20[ 2 ];
cArray20[ ci +1 ] = points20[ 3 ];
cArray40[ ci ] = points40[ 2 ];
cArray40[ ci +1 ] = points40[ 3 ];
cArray60[ ci ] = points60[ 2 ];
cArray60[ ci +1 ] = points60[ 3 ];
cArray80[ ci ] = points80[ 2 ];
cArray80[ ci +1 ] = points80[ 3 ];
cArray100[ ci++ ] = points100[ 2 ];
cArray100[ ci++ ] = points100[ 3 ];
oArray[ oi++ ] = dps_rlineto;
cArray0[ ci ] = points0[ 4 ];
cArray0[ ci +1 ] = points0[ 5 ];
cArray20[ ci ] = points20[ 4 ];
cArray20[ ci +1 ] = points20[ 5 ];
cArray40[ ci ] = points40[ 4 ];
cArray40[ ci +1 ] = points40[ 5 ];
cArray60[ ci ] = points60[ 4 ];
cArray60[ ci +1 ] = points60[ 5 ];
cArray80[ ci ] = points80[ 4 ];
cArray80[ ci +1 ] = points80[ 5 ];
cArray100[ ci++ ] = points100[ 4 ];
cArray100[ ci++ ] = points100[ 5 ];
oArray[ oi++ ] = dps_rlineto;
cArray0[ ci ] = points0[ 6 ];
cArray0[ ci +1 ] = points0[ 7 ];
cArray20[ ci ] = points20[ 6 ];
cArray20[ ci +1 ] = points20[ 7 ];
cArray40[ ci ] = points40[ 6 ];
cArray40[ ci +1 ] = points40[ 7 ];
cArray60[ ci ] = points60[ 6 ];
cArray60[ ci +1 ] = points60[ 7 ];
cArray80[ ci ] = points80[ 6 ];
cArray80[ ci +1 ] = points80[ 7 ];
cArray100[ ci++ ] = points100[ 6 ];
cArray100[ ci++ ] = points100[ 7 ];
oArray[ oi++ ] = dps_rlineto;
}
/*
setup 'rocket array' for userpath
*/
roArray[ 0 ] = dps_ucache;
roArray[ 1 ] = dps_setbbox;
roArray[ 2 ] = dps_moveto;
roArray[ 3 ] = dps_rlineto;
roArray[ 4 ] = dps_rlineto;
roArray[ 5 ] = dps_rlineto;
roArray[ 6 ] = dps_rlineto;
for( loop = 2; loop < 10; loop++ )
{
qcArray0[ loop ] = qpoints0[ loop ];
qcArray30[ loop ] = qpoints30[ loop ];
qcArray60[ loop ] = qpoints60[ loop ];
}
bbox[ 0 ] = -50.0;
bbox[ 1 ] = -50.0;
bbox[ 2 ] = theRect.size.width +100;
bbox[ 3 ] = theRect.size.height +100;
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.