This is Body.m in view mode; [Download] [Up]
#import "Body.h"
@implementation Body
- init
{
[super init];
bodyDelta = maskDelta = 1; //must not be < 1
maskDist = bodyDist = 1;
currentBodyListIndex = 0;
bodyFrameIndexCounter = maskFrameIndexCounter = 0;
bodyFrameRect.origin.x = 0.0;
bodyFrameRect.origin.y = 0.0;
maskFrameRect.origin.x = 0.0;
maskFrameRect.origin.y = 0.0;
firstState = YES;
return self;
}
- (BOOL)doUntilDone
{
BOOL maskDone;
maskDone = NO;
if(firstState){
currentImage = [self setBodyImage];
[self setFrameRectForBody]; //set frame size
[self setFrameRectForMask];
[self setStartPosition:centerOfScreen]; //first body and mask position
firstState = NO;
[self drawBody];
[self setImageListIndex];
currentImage = [self setBodyImage];
[self setFrameRectForBody]; //set frame size
bodyPosition = [self adjustPositionForBody: bodyPosition];
}
else {
maskDone = [self eraseBody];
[self setFrameRectForMask];
maskPosition = [self adjustPositionForMask: maskPosition];
//draw body
[self drawBody];
[self setImageListIndex];
currentImage = [self setBodyImage];
[self setFrameRectForBody]; //set frame size
bodyPosition = [self adjustPositionForBody: bodyPosition];
}
if(maskDone){
return YES; //this body done
}
else{
return NO;
}
}
- setImageListIndex
{
currentBodyListIndex = floor((bodyFrameIndexCounter * frameDelta) *
(bodyFrameIndexCounter * frameDelta) *
(bodyFrameIndexCounter * frameDelta) *
(bodyFrameIndexCounter * frameDelta));
bodyFrameIndexCounter++;
if(currentBodyListIndex >= numberOfFrames - 1)
currentBodyListIndex = numberOfFrames - 1;
return self;
}
// 4
//uses X to make expotential curve for calculating movement of object
//idea was to start slow and speed up expotentially
//the smaller the value of objectSpeed the faster the object moves
//I.E. if the number is 2 then it take 2 steps to move the whole distance
- setObjectSpeed:(float)objectSpeed
{
float radius,x,y;
x = bounds.size.width;
y = bounds.size.height;
radius = (sqrt(x*x + y*y))/2; // of screen bounds
distDelta = (sqrt(sqrt(radius)))/(1 + objectSpeed);
frameDelta = (sqrt(sqrt(numberOfFrames)))/(1 + objectSpeed);
return self;
}
- free
{
return [super free];
}
- (NXImage *)setBodyImage
{
return ([imageList objectAt:currentBodyListIndex]);
}
- setImageList:(List *)list
{
imageList = list;
return self;
}
- setMaskList:(List *)list
{
maskList = list;
return self;
}
- setNumberOfFrames
{
numberOfFrames = [imageList count];
return self;
}
- setStartPosition:(NXPoint)point //where body starts out
{
bodyPosition.x = point.x - floor((bodyFrameRect.size.width / 2));
bodyPosition.y = point.y - floor((bodyFrameRect.size.height / 2));
maskPosition.x = point.x - floor((maskFrameRect.size.width / 2));
maskPosition.y = point.y - floor((maskFrameRect.size.height / 2));
return self;
}
- setStarsOutlet: (id)starsOutlet
{
starsObject = starsOutlet;
return self;
}
- setFrameRectForBody
{
NXSize size;
[currentImage getSize: &size];
//adjust the rectangle to reflect actual image that was built
// so that you know when it actually crosses the viewscreen
bodyFrameRect.origin.x = 8.0;
bodyFrameRect.origin.y = 8.0;
bodyFrameRect.size.width = size.width-16;
bodyFrameRect.size.height = size.height-16;
return self;
}
- setFrameRectForMask
{
maskFrameRect.size.width = bodyFrameRect.size.width;
maskFrameRect.size.height = bodyFrameRect.size.height;
return self;
}
//bodyFrameRect is actual size of real image inside a black image
// 8 pixels bigger on all sides
//bodyPosition is where the actual image will be composited
- drawBody
{
NXPoint offset;
NXRect adjustedRect={0.0,0.0,bodyFrameRect.size.width+16,
bodyFrameRect.size.height+16};
if (bodyPosition.x < (bounds.size.width + bodyFrameRect.size.width) &&
bodyPosition.x > (bounds.origin.x - (bodyFrameRect.size.width + 1)) &&
bodyPosition.y < (bounds.size.height + bodyFrameRect.size.width) &&
bodyPosition.y > (bounds.origin.y-(bodyFrameRect.size.height + 1))){
[self setVoidRect:bodyIndex];
offset.x = bodyPosition.x - 8;
offset.y = bodyPosition.y - 8;
[currentImage composite:NX_COPY fromRect:&adjustedRect
toPoint:&offset];
}
return self;
}
- (BOOL)eraseBody
{
NXRect maskRect;
if (maskPosition.x < (bounds.size.width + maskFrameRect.size.width) &&
maskPosition.x > (bounds.origin.x-(maskFrameRect.size.width + 1)) &&
maskPosition.y < (bounds.size.height + maskFrameRect.size.width) &&
maskPosition.y > (bounds.origin.y -(maskFrameRect.size.height + 1))){
maskRect.origin.x = maskPosition.x;
maskRect.origin.y = maskPosition.y;
maskRect.size.width = maskFrameRect.size.width;
maskRect.size.height = maskFrameRect.size.height;
PSsetgray(0);
NXRectFill(&maskRect);
return NO;
}
else{
return YES;
}
}
//figure out new x,y position for moving object
- (NXPoint)adjustPositionForBody:(NXPoint)position
{
bodyDist = floor((distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta));
bodyDelta++;
position.x = floor((centerOfScreen.x - (bodyFrameRect.size.width / 2))
+ (bodyDist * cos(theta)));
position.y = floor((centerOfScreen.y - (bodyFrameRect.size.height / 2))
+ (bodyDist * sin(theta)));
return position;
}
- (NXPoint)adjustPositionForMask:(NXPoint)position
{
maskDist = floor((distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta));
maskDelta++;
position.x = floor((centerOfScreen.x - (maskFrameRect.size.width / 2))
+ (maskDist * cos(theta)));
position.y = floor((centerOfScreen.y - (maskFrameRect.size.height / 2))
+ (maskDist * sin(theta)));
return position;
}
//assumes position and size rects have been set for mask and body
- setVoidRect:(int)index
{
AvoidStruct avoidStruct;
const NXRect bodyRect = {bodyPosition.x,bodyPosition.y,
bodyFrameRect.size.width,bodyFrameRect.size.height};
//actual image is centered in a black rectangle 8 pixels
//bigger in each direction
//since bodyPosition and bodyFrameRect are set to the image
// that is in the oversized rect, adjust avoidance to
// real origin of black rectangle and make width and height
// actual image size plus 8 pixels - this makes the assumption
//stars are drawn from 0,0 to 8 pixels right and up.
avoidStruct.avoid.origin.x = bodyRect.origin.x-8;
avoidStruct.avoid.origin.y = bodyRect.origin.y-8;
avoidStruct.avoid.size.width = bodyRect.size.width+8;
avoidStruct.avoid.size.height = bodyRect.size.height+8;
[avoidStorage replaceElementAt:(unsigned int)bodyIndex with:&avoidStruct];
return self;
}
- setBoundsRect:(NXRect *)r
{
// screen border width is 5 pixels
// make ship bounds 1 pixel less so that
// when border shrinks by 1 it won't
// affect objects - bounds will catch up
NXSetRect(&bounds,
r->origin.x,
r->origin.y,
r->size.width,
r->size.height);
[self setCenter];
return self;
}
- setCenter
{
centerOfScreen.x = (bounds.size.width / 2) + bounds.origin.x;
centerOfScreen.y = bounds.size.height / 2 + bounds.origin.y;
return self;
}
- setAngle:(float)angle;
{
theta = angle;
return self;
}
- setAvoidStorage:(Storage *)storageObject
{
avoidStorage = storageObject;
return self;
}
- setBodyIndex:(int)index
{
bodyIndex = index;
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.