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.