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.