This is SplatView.m in view mode; [Download] [Up]
/* * SplatView.m * Description * subclass of BoardView specific to the game "Splat" * History * 14-Feb-93 Erik Kay Created * 15-Mar-93 Erik Kay added sound */ #import "SplatView.h" #import "SplatApp.h" #import "SplatGame.h" #import "SplatDefaults.h" extern void animateMove (DPSTimedEntry te, double now, void *data); extern void animateChange (DPSTimedEntry te, double now, void *data); @implementation SplatView - initFrame:(const NXRect *)r { NXSize sz; [super initFrame:r]; /* image initialization */ obstructionImg = [[NXImage findImageNamed:"obstruction"] setScalable:YES]; one = [[NXImage findImageNamed:"one"] setScalable:YES]; two = [[NXImage findImageNamed:"two"] setScalable:YES]; numAnimationFrames = 9; currentFrame = -1; [obstructionImg getSize:&sz]; pieceSize = sz.width; squareSize = pieceSize + 4; /* sound initialization */ soundManager = [NXApp soundManager]; return self; } - drawHighlightedSquare:(NXRect *)rect at:(int)col :(int)row { NXRect r; NX_WIDTH(rect) -= 4; NX_HEIGHT(rect) -= 4; NX_X(rect) += 2; NX_Y(rect) += 2; NXSetRect(&r,(currentFrame % 3) * pieceSize, ((8-currentFrame) / 3) * pieceSize, pieceSize, pieceSize); if (currentPlayer == SQUARE_ONE) [one composite:NX_SOVER fromRect:&r toPoint:&rect->origin]; else [two composite:NX_SOVER fromRect:&r toPoint:&rect->origin]; currentFrame++; return self; } - drawObstruction:(NXRect *)r at:(int)col :(int)row { NX_WIDTH(r) -= 4; NX_HEIGHT(r) -= 4; NX_X(r) += 2; NX_Y(r) += 2; [obstructionImg composite:NX_SOVER toPoint:&r->origin]; return self; } - drawPlayerOne:(NXRect *)r at:(int)col :(int)row { NXRect rect; NX_WIDTH(r) -= 4; NX_HEIGHT(r) -= 4; NX_X(r) += 2; NX_Y(r) += 2; if ((moving && ((selectedCol == col) && (selectedRow == row))) || (changing)) { NXSetRect(&rect,((8-currentFrame) % 3) * pieceSize, ((currentFrame) / 3) * pieceSize, pieceSize, pieceSize); [one composite:NX_SOVER fromRect:&rect toPoint:&r->origin]; } else { if (!((col == currentMove.from.col) && (row == currentMove.from.row) && (selectedCol == -1) && moving)) { NXSetRect(&rect,pieceSize * 2, 0, pieceSize, pieceSize); [one composite:NX_SOVER fromRect:&rect toPoint:&r->origin]; } } return self; } - drawPlayerTwo:(NXRect *)r at:(int)col :(int)row { NXRect rect; NX_WIDTH(r) -= 4; NX_HEIGHT(r) -= 4; NX_X(r) += 2; NX_Y(r) += 2; if ((moving && ((selectedCol == col) && (selectedRow == row))) || (changing)) { NXSetRect(&rect,((8-currentFrame) % 3) * pieceSize, ((currentFrame) / 3) * pieceSize, pieceSize, pieceSize); [two composite:NX_SOVER fromRect:&rect toPoint:&r->origin]; } else { if (!((col == currentMove.from.col) && (row == currentMove.from.row) && (selectedCol == -1) && moving)) { NXSetRect(&rect, pieceSize * 2, 0, pieceSize, pieceSize); [two composite:NX_SOVER fromRect:&rect toPoint:&r->origin]; } } return self; } - drawSelf:(const NXRect *)rects :(int)count { int tmpFrame; if (resized) { tmpFrame = currentFrame; currentFrame = 0; [super drawSelf:rects :count]; resized = NO; currentFrame = tmpFrame; } else [super drawSelf:rects :count]; return self; } - doMoveAnimation:(move *)mv { if (abortGame) { if (moveEntry) { DPSRemoveTimedEntry(moveEntry); moveEntry = NULL; } abortGame = NO; } currentMove = *mv; board->currentMove = *mv; if ((abs(currentMove.from.col - currentMove.to.col) > 1) || (abs(currentMove.from.row - currentMove.to.row) > 1)) moving = YES; [self selectSquare:mv->from.col :mv->from.row]; moveEntry = DPSAddTimedEntry(0.02,animateMove,(void *)self,NX_BASETHRESHOLD); currentFrame = 0; currentPlayer = [board pieceAt:mv->from.col :mv->from.row]; [self display]; [self playSound:MOVE_SOUND atCol:mv->to.col]; return self; } - doAnimateMove { if (highlightedCol == -1) { highlightedCol = currentMove.to.col; highlightedRow = currentMove.to.row; } [boardCopy setPiece:SQUARE_ERROR at:highlightedCol :highlightedRow]; [self display]; return self; } - finishChangeAnimation { changing = NO; currentFrame = -1; [boardDiffs free]; boardDiffs = nil; [board free]; board = newBoard; newBoard = nil; [self display]; [super finishChangeAnimation]; return self; } - finishMoveAnimation { currentFrame = -1; [super finishMoveAnimation]; moving = NO; return self; } - doChangeAnimation:(Board *)orig { move *mv; int r, c, diffcount; BOOL doit = NO; boardDiffs = [board trueCopy]; [boardDiffs clearBoard]; newBoard = board; board = [orig trueCopy]; for (c = 0; c < cols; c++) { for (r = 0; r < rows; r++) { if (([board pieceAt:c :r] != [newBoard pieceAt:c :r]) && ([board pieceAt:c :r] != SQUARE_EMPTY) && ([newBoard pieceAt:c :r] != SQUARE_EMPTY)) { doit = YES; [boardDiffs setPiece:[newBoard pieceAt:c :r] at:c :r]; } } } if (doit) { changeEntry = DPSAddTimedEntry(0.001,animateChange,(void *)self,NX_BASETHRESHOLD); currentFrame = 0; changing = YES; mv = [orig currentMove]; currentPlayer = [board pieceAt:mv->from.col :mv->from.row]; diffcount = [boardDiffs numberOfPiece:SQUARE_ONE] + [boardDiffs numberOfPiece:SQUARE_TWO]; if (diffcount >= 7) [self playSound:WOWCHANGE_SOUND atCol:mv->to.col]; else if (diffcount >= 4) [self playSound:BIGCHANGE_SOUND atCol:mv->to.col]; else [self playSound:CHANGE_SOUND atCol:mv->to.col]; } else [self finishChangeAnimation]; return self; } - doAnimateChange { int r, c; NXRect rect; [self lockFocus]; for (c = 0; c < cols; c++) for (r = 0; r < rows; r++) { if ([boardDiffs pieceAt:c :r] == SQUARE_EMPTY) continue; NXSetRect(&rect,c * squareSize, r * squareSize, squareSize, squareSize); [self drawEmptySquare:&rect at:c :r]; switch ([boardDiffs pieceAt:c :r]) { case SQUARE_ONE: if (direction == -1) [self drawPlayerOne:&rect at:c :r]; else [self drawPlayerTwo:&rect at:c :r]; break; case SQUARE_TWO: if (direction == -1) [self drawPlayerTwo:&rect at:c :r]; else [self drawPlayerOne:&rect at:c :r]; break; case SQUARE_BLOCKED: case SQUARE_EMPTY: default: break; } } [self unlockFocus]; currentFrame += direction; [window flushWindow]; NXPing(); return self; } - scaleImages { NXSize sz; int c, r; if (scalable) { [obstructionImg getSize:&sz]; if (sz.width == pieceSize) return self; if (obstructionImg != [NXImage findImageNamed:"obstruction"]) { [obstructionImg free]; [one free]; [two free]; obstructionImg = [NXImage findImageNamed:"obstruction"]; one = [NXImage findImageNamed:"one"]; two = [NXImage findImageNamed:"two"]; } sz.width = sz.height = pieceSize; obstructionImg = [obstructionImg copy]; one = [one copy]; two = [two copy]; [obstructionImg setSize:&sz]; [one getSize:&sz]; c = sz.width / 48.0; r = sz.height / 48.0; sz.width = c * pieceSize; sz.height = r * pieceSize; [one setSize:&sz]; [two getSize:&sz]; c = sz.width / 48.0; r = sz.height / 48.0; sz.width = c * pieceSize; sz.height = r * pieceSize; [two setSize:&sz]; } return self; } - setBoard:(Board *)b { [window disableFlushWindow]; squareSize = (int)[[NXApp defaultsManager] squareSize]; pieceSize = squareSize - 4; [super setBoard:b]; moving = changing = NO; currentFrame = 0; if (squareSize != 52) scalable = YES; if (scalable) [self scaleImages]; if (boardCopy) { [boardCopy free]; boardCopy = nil; } [window display]; [window reenableFlushWindow]; [window flushWindow]; return self; } - windowDidResize:sender { scalable = YES; squareSize = NX_HEIGHT(&frame) / rows; // both width and height should work [[NXApp defaultsManager] setSquareSize:squareSize]; pieceSize = squareSize - 4; [self scaleImages]; [boardCopy free]; boardCopy = nil; resized = YES; [self display]; [window flushWindow]; return self; } - windowWillResize:sender toSize:(NXSize *)newSize { NXRect winR; NXSize curSize, minSize; float dx, dy, ratio; ratio = (float)rows / cols; [window getFrame:&winR]; curSize = winR.size; dx = newSize->width - curSize.width; dy = newSize->height - curSize.height; if (abs(dx) > abs(dy)) { dy = dx * ratio; } else if (abs(dy) > abs(dx)) { dx = dy / ratio; } else { if (rows > cols) dx = dy / ratio; else if (rows < cols) dy = dx / ratio; } newSize->width = curSize.width + dx; newSize->height = curSize.height + dy; [window getMinSize:&minSize]; if (newSize->width < minSize.width) { dx = minSize.width - newSize->width; dy = dx * ratio; newSize->width = minSize.width; newSize->height += dy; } if (newSize->height < minSize.height) { dy = minSize.height - newSize->height; dx = dy / ratio; newSize->height = minSize.height; newSize->width += dx; } return self; } - windowWillClose:sender { id ret = [game windowWillClose:sender]; if (ret) [game perform:@selector(free) with:nil afterDelay:100 cancelPrevious:NO]; return ret; } - gameOver { [super gameOver]; return self; } - playSound:(int)which atCol:(int)c { float l, r; if ([[NXApp defaultsManager] playSounds]) { l = 1 - ((float)(c + 1)/(float)cols); r = 1 - l; [soundManager playSound:which withGainLeft:l right:r]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.