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.