This is GKTextActor.m in view mode; [Download] [Up]
// Handles putting temporary text in the game field. #import <gamekit/gamekit.h> #import <daymisckit/daymisckit.h> #import <dpsclient/psops.h> static BOOL classInitialized = NO; @implementation GKTextActor + initialize { id ret = [super initialize]; // we want to make sure that the text pswraps have been initialized. if ((self == [GKTextActor class]) && (!classInitialized)) { GKTextSetUp(); classInitialized = YES; } return ret; } - init { NXPoint zero = { 0.0, 0.0 }; return [self initAtPoint:&zero pointSize:GK_DEFAULTPOINTSIZE]; } - initAtPoint:(const NXPoint *)aPoint pointSize:(float)points { // shouldn't ever really use this, but then again, might as well // have it set up a useful text string! return [self initWithString:GK_DEFAULTTEXT atPoint:aPoint pointSize:points]; } - initWithInt:(int)aNumber atPoint:(const NXPoint *)aPoint pointSize:(float)points { char tempString[32]; sprintf(tempString, "%d", aNumber); return [self initWithString:tempString atPoint:aPoint pointSize:points]; } - initWithString:(const char *)aString atPoint:(const NXPoint *)aPoint pointSize:(float)points { NXRect tempRect; id ret = [super init]; doDraw = YES; visible = YES; blinking = NO; doErase = NO; timeLeftOnScreen = 48; blinkPeriod = 4; pointSize = points; if (!text) text = [[DAYString alloc] init]; if (!fontName) fontName = [[DAYString alloc] init]; [fontName setStringValue:"Helvetica"]; [text setStringValue:aString]; GK_COPY_VECTORS(&(boundingBox.origin), aPoint); // calculate the text size (our bounding box) [self getBoundingBox:&tempRect]; return ret; } - (int)timeLeftOnScreen { return timeLeftOnScreen; } - (int)blinkPeriod { return blinkPeriod; } - (BOOL)blinking { return blinking; } - (const char *)fontName { return [fontName stringValue]; } - getBoundingBox:(NXRect *)box // obtain the true bounding box { // we have to do it this way 'cause descenders in the text can shift // the box down from the drawing origin... NXRect tempRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; float x, y, width, height; GKborderedTextBoundingBox((char *)[text stringValue], &x, &y, &width, &height); NXSetRect(&tempRect, x + NX_X(&boundingBox), y + NX_Y(&boundingBox), width, height); NX_WIDTH(&boundingBox) = width; NX_HEIGHT(&boundingBox) = height; GK_COPY_RECT(box, &tempRect); return self; } - setFontName:(const char *)name { [fontName setStringValue:name]; return self; } - setTimeLeftOnScreen:(int)anInt { timeLeftOnScreen = anInt; return self; } - setBlinkPeriod:(int)anInt { blinkPeriod = anInt; [self setBlinking:(anInt != 0)]; return self; } - setBlinking:(BOOL)anInt { blinking = anInt; visible = YES; doDraw = YES; return self; } - eraseInDirtPile:dirtPile { // no need to erase us yet. if (timeLeftOnScreen < 1) { // tell the stage to remove us after this cycle; we're going away [self leaveTheStage]; doErase = YES; } if (doErase) { // do the erase if we're blinking float x, y, width, height; GKborderedTextBoundingBox((char *)[text stringValue], &x, &y, &width, &height); doErase = NO; [dirtPile addRegion:(x + GK_VECTOR_X(&lastDrawnLocation)) :(y + GK_VECTOR_Y(&lastDrawnLocation)) :width :height]; return self; } return self; } - markInDirtPile:dirtPile { // only need to mark the firt time we draw since we are effectively static if (doDraw) { float x, y, width, height; GKborderedTextBoundingBox((char *)[text stringValue], &x, &y, &width, &height); doErase = NO; [dirtPile addRegion:(x + GK_VECTOR_X(&lastDrawnLocation)) :(y + GK_VECTOR_Y(&lastDrawnLocation)) :width :height]; return self; } return self; } - moveOneFrame { // Decrease the time left on screen every time we "move". [super moveOneFrame]; timeLeftOnScreen--; if (!(timeLeftOnScreen % blinkPeriod)) { visible = !visible; // turn it on or off doDraw = YES; // make sure the new state is redrawn if (!visible) doErase = YES; } return self; } - drawActorWithOffset:(NXPoint *)offset // draw the actor { if (timeLeftOnScreen < 1) return self; // don't draw; we're gone doDraw = NO; if (!visible) return self; // We always render, even though we don't always mark the DirtPile, // because some other actor may have overwritten us... // render the text; white text with a black outline around it. PSselectfont([fontName stringValue], pointSize); GKdrawBorderedText((offset->x + NX_X(&boundingBox)), (offset->y + NX_Y(&boundingBox)), (char *)[text stringValue]); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.