This is Fish.m in view mode; [Download] [Up]
#import "Thinker.h" #import "Fish.h" #import "FishBrain.h" #import "DuoImage.h" #import <appkit/appkit.h> #import <dpsclient/wraps.h> #import <stdio.h> #import <libc.h> #import <math.h> #include <sys/stat.h> #define FISHPICTS 20 // Maximum number without recompile #define NUMBER_OF_FRAMES 1 // Need more frames eventually @implementation Fish - init:sender { NXRect bufferRect; NXRect rect; struct stat statbuf; const char *ptr; float r = .000, g = .000, b = .000; char fishfile[MAXPATHLEN]; char fishType[10] = "salt"; aquarium = sender; [aquarium getFrame:&rect]; sizeOfAquar = rect.size; srandom(currentTimeInMs()); fxType = 0; ptr = NXGetDefaultValue([NXApp appName], "AquariumFxType"); if (ptr) sscanf (ptr, "%d", &fxType); dissolveFactor = 3; ptr = NXGetDefaultValue([NXApp appName], "AquariumDissolveFactor"); if (ptr) sscanf (ptr, "%d", &dissolveFactor); ptr = NXGetDefaultValue([NXApp appName], "AquariumColor"); if (ptr) sscanf (ptr, "%f %f %f", &r, &g, &b ); fishBufferColor = NXConvertRGBToColor(r,g,b); ptr = NXGetDefaultValue([NXApp appName], "AquariumFishType"); if (ptr) sscanf (ptr, "%s", fishType ); do { sprintf(fishfile,"%s/%s/fish.%d.tiff",[BSThinker() moduleDirectory:"Aquarium"],fishType, (int)(random() % FISHPICTS + 1)); } while(stat(fishfile,&statbuf) == -1); fish = [DuoImage allocFromZone:[self zone]]; [fish initFromFile:fishfile]; [fish getSize:&bufferRect.size]; // bufferRect.size.width /= (NUMBER_OF_FRAMES); WIDTH=bufferRect.size.width; HEIGHT=bufferRect.size.height; brain = [[FishBrain allocFromZone:[self zone]] init:&sizeOfAquar fishSize:&bufferRect.size owner:fish]; clear_buffer = [[NXImage alloc] initSize:&bufferRect.size]; fish_buffer = [[NXImage alloc] initSize:&bufferRect.size]; [clear_buffer lockFocus]; NXSetColor(fishBufferColor); NXRectFill(&bufferRect); [clear_buffer unlockFocus]; return self; } - erase { [clear_buffer composite:NX_COPY toPoint:&old.origin]; return self; } - move { float factor; float speed; NXRect new, tmpRect, myRect = {0,0,0,0}; new.origin.x = [brain getXPos]; new.origin.y = [brain getYPos]; new.size.width = WIDTH; new.size.height = HEIGHT; switch(fxType) { case(0): [fish composite:NX_SOVER toPoint:&new.origin]; break; case(1): speed = sqrt( pow([brain getXSpeed],2 ) + pow([brain getYSpeed],2) ); tmpRect.origin.x = (random() % 5) / speed * (old.origin.x - new.origin.x); tmpRect.origin.y = (random() % 5) / speed * (old.origin.y - new.origin.y); factor = 0.02 * dissolveFactor ; [fish_buffer getSize:&myRect.size]; [fish_buffer lockFocus]; [fish composite:NX_COPY toPoint:&myRect.origin]; [fish dissolve:factor toPoint:&tmpRect.origin]; [fish_buffer unlockFocus]; [fish_buffer composite:NX_SOVER toPoint:&new.origin]; break; case(2): [fish composite:NX_DOUT toPoint:&new.origin]; break; } old = new; return self; } - viewDidResize; { NXRect rect; [aquarium getFrame:&rect]; sizeOfAquar = rect.size; [brain viewDidResize:&sizeOfAquar]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.