This is AnimView.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "AnimView.h" #import <appkit/NXImage.h> #import <appkit/Control.h> #import <appkit/Matrix.h> #import <dpsclient/psops.h> @implementation AnimView - initFrame:(const NXRect *)frm // initialize instance { [super initFrame:frm]; cycles = 0; frameShown = 0; position.y = 0.0; position.x = 0.0; return self; } - loadPix // gameBrain calls this from appDidInit { [super loadPix]; runner = [NXImage findImageNamed:IMAGENAME]; return self; } - autoUpdate:sender // sent by timer { int direction = GODIR; int move = MOVEINC; [super autoUpdate:sender]; if (!(cycles % UPDATEFREQ)) { frameShown++; if (frameShown >= NUM_FRAMES) frameShown = 0; if (GORIGHT) { position.x = position.x + move; if (position.x > NX_WIDTH(&bounds) + move) position.x = 0.0; } else if (GOLEFT) { position.x = position.x - move; if (position.x < - (BLOCK_SIZE + move)) position.x = NX_WIDTH(&bounds); } else if (GOUP) { position.y = position.y + move; if (position.y > NX_HEIGHT(&bounds) + move) position.y = 0.0; } else if (GODOWN) { position.y = position.y - move; if (position.y < - (BLOCK_SIZE + move)) position.y = NX_HEIGHT(&bounds); } else { } [self updateSelf:&bounds :1]; } return self; } - drawSelf:(NXRect *)rects :(int)rectCount //used by internals for speed { NXRect from = {{frameShown * BLOCK_SIZE, SERIES * BLOCK_SIZE}, {BLOCK_SIZE, BLOCK_SIZE}}; [super drawSelf:rects :rectCount]; PSsetgray(0.333); NXRectFill(rects); [runner composite:NX_SOVER fromRect:&from toPoint:&position]; return self; } - updateSelf:(NXRect *)rects :(int)rectCount //used by internals for speed { int move = MOVEINC; NXRect from = {{frameShown * BLOCK_SIZE, SERIES * BLOCK_SIZE}, {BLOCK_SIZE, BLOCK_SIZE}}; NXRect old = {{position.x - move, position.y - move}, {BLOCK_SIZE + move * 2, BLOCK_SIZE + move * 2}}; [self lockFocus]; [super drawSelf:rects :rectCount]; // very inefficient (GameView will splat the // whole background!) Probably OK to comment it out. PSsetgray(0.333); NXRectFill(&old); // since there is only one object, the DirtPile is overkill and // I just use regular NEXTSTEP buffers- they'll flush to the screen the erased // area intersected with the newly composited area. Quite simple, really. The // DirtPile will do this intelligently if you have more objects than one. [runner composite:NX_SOVER fromRect:&from toPoint:&position]; [self unlockFocus]; [window flushWindow]; NXPing(); // Only one ping per frame or you'll crawl! return self; } - changeDist:sender { int val = [sender intValue]; [distText setIntValue:val]; if (sender != distSlider) [distSlider setIntValue:val]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.