This is Ship.m in view mode; [Download] [Up]
#import "Ship.h"
#import "ActorMgr.h"
#import "SoundMgr.h"
#import "Bullet.h"
#import "Xoxeroids.h"
#import "Thinker.h"
#define ROT_SPEED (37.0)
#define ACCEL (3.0)
#define MAXV (70)
extern float gx, gy;
@implementation Ship
- activate:sender :(int)tag
{
NXSize t20 = {20,20};
NXSize t10 = {10,10};
int oldFrame = frame;
[super activate:sender :tag];
[self reinitWithImage:"ship"
frameSize:&t20
numFrames:24
shape: RECTCIRC
alliance: GOOD
radius: 10.0
buffered: YES
x: 0.0
y: 0.0
theta: theta
vel: 0.0
interval: 50
distToCorner: &t10];
noflame = image;
frame = oldFrame;
[self setThrusting:NO time:0];
xv = yv = gx = gy = 0;
shieldStrength = 100;
shields = NULL;
return self;
}
+ initialize
{
[super initialize];
[[NXApp delegate] addImageResource:"ship" for: [Ship class]];
[[NXApp delegate] addImageResource:"flame1" for: [Ship class]];
[[NXApp delegate] addImageResource:"flame2" for: [Ship class]];
return self;
}
- init
{
[super init];
flame1 = [self findImageNamed:"flame1"];
flame2 = [self findImageNamed:"flame2"];
theta = 0.0;
thrustVal = [[KeyTimer allocFromZone:[self zone]] init];
leftVal = [[KeyTimer allocFromZone:[self zone]] init];
rightVal = [[KeyTimer allocFromZone:[self zone]] init];
[leftVal setDelegate:rightVal];
[rightVal setDelegate:leftVal];
return self;
}
- free
{
[thrustVal free];
[leftVal free];
[rightVal free];
return [super free];
}
- _flameOn
{
NXSize t30 = {30,30};
NXSize t15 = {15,15};
frameSize = t30;
distToCorner = t15;
image = flame1;
return self;
}
- _flameOff
{
NXSize t20 = {20,20};
NXSize t10 = {10,10};
frameSize = t20;
distToCorner = t10;
image = noflame;
return self;
}
- setThrusting:(BOOL)val time:(long)time
{
thrusting = val;
if (thrusting)
{
changeTime = timeInMS + interval;
[self _flameOn];
[thrustVal keyDownAt:time];
}
else
{
[self _flameOff];
if (time) [thrustVal keyUpAt:time];
}
return self;
}
- setTurning:(ROTATION)dir down:(BOOL)keyDn time:(long)time
{
if (dir == LEFT)
{
if (keyDn) [leftVal keyDownAt:time];
else [leftVal keyUpAt:time];
}
else if (dir == RIGHT)
{
if (keyDn) [rightVal keyDownAt:time];
else [rightVal keyUpAt:time];
}
return self;
}
- tweakGxGy
{
gx = x;
gy = y;
return self;
}
- positionChanged
{
float t_theta, rotVal;
[self tweakGxGy];
[self calcDrawRect];
if (thrusting && (timeInMS > changeTime))
{
changeTime = timeInMS + interval;
if (++thrustState & 1) image = flame1;
else image = flame2;
}
if (shields && (timeInMS > shieldTime))
{
shieldStrength -= 3.125;
if (shieldStrength < 0) shieldStrength = 0;
shieldTime = timeInMS + 650;
}
rotVal = [leftVal val] - [rightVal val];
if (rotVal != 0) theta += rotVal * (ROT_SPEED * PI / 180.0);
while (theta < 0) theta += (2*PI);
while (theta >= (2*PI)) theta -= (2*PI);
t_theta = theta + (7.5 * PI / 180.0);
if (t_theta >= 2.0*PI) t_theta -= 2.0*PI;
frame = (t_theta/(15.0 * PI / 180.0));
return self;
}
- calcDxDy:(NXPoint *)dp
{
float thrust = [thrustVal val];
if (thrust > 0)
{
xv += thrust * ACCEL * -sin(theta);
yv += thrust * ACCEL * cos(theta);
}
if (xv > MAXV) xv = MAXV;
else if (xv < -MAXV) xv = -MAXV;
if (yv > MAXV) yv = MAXV;
else if (yv < -MAXV) yv = -MAXV;
dp->x = timeScale * xv;
dp->y = timeScale * yv;
didFire = NO;
return self;
}
- fire
{
int i;
float oldTheta = theta;
if ((!employed) || shields || didFire) return self;
if (bigGuns)
{
theta -= 9.0 * PI/180.0;
for (i=0; i<3; i++)
{
[actorMgr newActor:xx_bullet for:self tag:
(i != 1) ? (BUL_SLOW|BUL_IMAGE) : 0];
theta += 9.0 * PI/180.0;
}
theta = oldTheta;
}
else
{
[actorMgr newActor:xx_bullet for:self tag:BUL_IMAGE];
}
didFire = YES;
return self;
}
- performCollisionWith:(Actor *) dude
{
int i;
float t_theta;
id ret = self;
if (shields)
shieldStrength -= 12.5;
else
shieldStrength = -1;
if (shieldStrength < 0)
{
shieldStrength = 0;
bigGuns = NO;
// How is he, Bones?
[soundMgr playSound: SHIPSND at:0.5];
t_theta = theta;
#define ZXPLOSIONS (7)
for (i=0; i<ZXPLOSIONS; i++)
{
vel = randBetween(1.5,3.1);
xv = vel * -sin(theta);
yv = vel * cos(theta);
t_theta += ((360./ZXPLOSIONS) * PI/180.0);
theta = t_theta + randBetween(-6.*PI/180.,6.*PI/180.);
[actorMgr newActor:xx_explosion for:self tag:i&1];
}
theta = 0.0;
frame = 0;
ret = [super performCollisionWith: dude];
}
return ret;
}
- setShields:(int)state;
{
if ((state) && (shieldStrength > 0))
{
if (!shields)
{
shields = [actorMgr newActor:xx_shield for:self tag:0];
shieldTime = timeInMS + 650;
}
}
else
{
[actorMgr destroyActor:shields];
shields = NULL;
}
return self;
}
- scenarioSelected
{
[keyTimerList addObject:thrustVal];
[keyTimerList addObject:leftVal];
[keyTimerList addObject:rightVal];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.