This is SnakesView.m in view mode; [Download] [Up]
//
// SnakesView.m
//
// Matt Pharr- pharr@cs.yale.edu
//
#import "SnakesView.h"
#import <dpsclient/wraps.h>
#import <libc.h>
#define MAX_SNAKES 11
#define BEFORE_REDRAW 1000
#define max(x,y) ((x) > (y) ? (x) : (y))
#define MIN_X (bounds.origin.x)
#define MAX_X (bounds.size.width)
#define MIN_Y (bounds.origin.y)
#define MAX_Y (bounds.size.height)
typedef struct {
NXPoint position;
NXPoint move_vector;
int radius;
float color;
float d_color;
float r,g,b;
} SNAKE;
SNAKE snakes[MAX_SNAKES];
@implementation SnakesView
- oneStep
{
int i;
if (++nSteps >= BEFORE_REDRAW) {
usleep(500000);
nSteps= 0;
aliveSnakes= 0;
}
if (aliveSnakes == 0) {
PSsetgray(0.0);
NXRectFill(&bounds);
}
if (((aliveSnakes < nSnakes) && (random() % 30 == 1)) ||
(aliveSnakes == 0)) {
snakes[aliveSnakes].position.x= random() % (int)MAX_X;
snakes[aliveSnakes].position.y= MAX_Y;
if (random() % 2 == 1)
snakes[aliveSnakes].move_vector.x= (5 + random () % 10) * (MAX_X / 1100);
else
snakes[aliveSnakes].move_vector.x= (-5 - random () % 10) * (MAX_X / 1100);
if (random() % 2 == 1)
snakes[aliveSnakes].d_color= randBetween(0.0,0.04);
else
snakes[aliveSnakes].d_color= -1 * randBetween(0.0,0.04);
snakes[aliveSnakes].move_vector.y= -1 * random() % 15;
snakes[aliveSnakes].radius= 10 + random() % 30;
snakes[aliveSnakes].color= randBetween(0.0,1.0);
snakes[aliveSnakes].r= randBetween(0.0,1.0);
snakes[aliveSnakes].g= randBetween(0.0,1.0);
snakes[aliveSnakes].b= randBetween(0.0,1.0);
++aliveSnakes;
}
[self lockFocus];
for (i= 0; i < aliveSnakes; ++i) {
PSsetgray(0.0);
PSarc(snakes[i].position.x, max(snakes[i].position.y, snakes[i].radius+1),
snakes[i].radius+1, 0, 360);
PSstroke();
snakes[i].color += snakes[i].d_color;
if (snakes[i].color > 1 || snakes[i].color < 0)
snakes[i].d_color *= -1;
if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
PSsetgray(snakes[i].color);
}
else {
PSsetrgbcolor(snakes[i].r, snakes[i].g, snakes[i].b);
}
PSarc(snakes[i].position.x, max(snakes[i].position.y, snakes[i].radius),
snakes[i].radius, 0, 360);
PSfill();
}
[self unlockFocus];
for (i= 0; i < aliveSnakes; ++i) {
snakes[i].position.x += snakes[i].move_vector.x;
snakes[i].position.y += snakes[i].move_vector.y;
snakes[i].move_vector.y -= 2;
/* snakes[i].move_vector.y *= randBetween(.975,.996); */
/* a little air resistance... */
if (snakes[i].position.x - snakes[i].radius < MIN_X) {
snakes[i].move_vector.x= random() % 15;
}
if (snakes[i].position.x + snakes[i].radius > MAX_X) {
snakes[i].move_vector.x= -1 * random() % 15;
}
if (snakes[i].position.y < MIN_Y) {
snakes[i].position.y= MIN_Y;
snakes[i].move_vector.y *= -.9;
}
}
return self;
}
- initFrame:(const NXRect *)frameRect
{
[super initFrame:frameRect];
[self inspector:self];
if (NXGetDefaultValue([NXApp appName], "snakesNumber") == NULL) {
NXWriteDefault([NXApp appName], "snakesNumber", "6");
nSnakes= 6;
}
else {
nSnakes= atoi(NXGetDefaultValue([NXApp appName], "snakesNumber"));
}
if (nSnakes < 1) nSnakes= 1;
[nSnakesSlider setIntValue:nSnakes];
return self;
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
if (!rects || !rectCount) {
return self;
}
PSsetgray(0.0);
NXRectFill(rects);
return self;
}
- (const char *)windowTitle
{
return "Snakes";
}
- (BOOL)useBufferedWindow
{
return YES;
}
- inspector:sender
{
char buf[MAXPATHLEN];
if (!inspectorPanel) {
sprintf(buf,"%s/%s",[(BSThinker()) moduleDirectory:"Snakes"],"Snakes.nib");
[NXApp loadNibFile:buf owner:self withNames:NO];
}
return inspectorPanel;
}
-setNSnakes:sender
{
char temp[40];
nSnakes= [sender intValue];
aliveSnakes= 0;
sprintf(temp, "%d", nSnakes);
NXWriteDefault([NXApp appName], "snakesNumber", temp);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.