This is NGameView.m in view mode; [Download] [Up]
/*----------------------------------------------------------------------*/
/* (C) Copyright 1994 Stefanos Kiakas */
/* All rights reserved. */
/*----------------------------------------------------------------------*/
/* Generated by Interface Builder */
#import "NGameView.h"
#import "NQueueView.h"
#import "NPipeCell.h"
/*----------------------------------------------------------------------*/
/* Purpose : This is wrapper function to call the step method. It */
/* is invoked DPSTimedEntryat a constant interval to */
/* update the flow. */
/* */
/* Parameters : As defined for a DPSTimedEntry(). */
/* */
/* Return value : none */
/*----------------------------------------------------------------------*/
void stepFun (DPSTimedEntry timedE, double timeN, void *data)
{
[(id)data step ];
}
@implementation NGameView
/*----------------------------------------------------------------------*/
/* Purpose : Method to initialize ( create matrix and associated */
/* cells ) game view. */
/* */
/* Parameters : none */
/* */
/* Return value : none */
/*----------------------------------------------------------------------*/
- initializeGame
{
NXRect matrixRect;
NXSize interCellSpacing = {0.0, 0.0};
NXSize cellSize = { 50.0, 50.0 };
struct timeval tp;
struct timezone tzp;
gettimeofday( &tp, &tzp );
srandom( (int ) tp.tv_sec );
[self getBounds:&matrixRect]; /* determine the matrix bounds */
/* prepare a matrix to go inside our scrollView */
gameMatrix = [[Matrix alloc] initFrame:&matrixRect
mode:NX_RADIOMODE
cellClass:[NPipeCell class]
numRows:NP_GAME_ROWS
numCols:NP_GAME_COLUMNS];
/* we don't want any space between the matrix's cells */
[gameMatrix setIntercell:&interCellSpacing];
/* resize the matrix's cells and size the matrix to contain them */
[gameMatrix setCellSize:&cellSize];
[gameMatrix sizeToCells];
[gameMatrix setTarget:self];
[gameMatrix setAction:@selector(singleClick:)];
/* stick the matrix in our View */
[self addSubview:gameMatrix];
gameStatus = STOPPED;
[queue initializePipeQueue];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- newLevel
{
int i; // general purpose index
int r; // row counter
int c; // column counter
id currentCell;
int startFlowRow;
int startFlowColumn;
gameLevel++;
levelPiecesRemaining = ( gameLevel * 2 ) + 5;
[theScore setIntValue: gameScore];
[theLevel setIntValue: gameLevel];
[theBonus setIntValue: levelBonus];
[theRest setIntValue: levelPiecesRemaining];
//----------------------------------------------------------------------
// Set up all cells for new game.
//----------------------------------------------------------------------
for( c = 0; c < NP_GAME_COLUMNS; c++ )
{
for( r = 0; r < NP_GAME_ROWS; r++ )
{
currentCell = [gameMatrix cellAt:r :c ];
[currentCell assignPipe: PIPE_UNASSIGNED ];
}
}
[gameMatrix display];
//----------------------------------------------------------------------
// Calculate new (random) position of water source.
//----------------------------------------------------------------------
startFlowRow = random() % NP_GAME_ROWS;
startFlowColumn = random() % ( NP_GAME_COLUMNS - 1 ); // source must not be againt the right edge
currentCell = [gameMatrix cellAt:startFlowRow :startFlowColumn ];
[currentCell assignPipe: PIPE_SOURCE];
flowCell = currentCell;
[flowCell setFlowEntryDirection: SOUTH ];
//----------------------------------------------------------------------
// Add obstacles to game matrix.
//----------------------------------------------------------------------
for( i = 1; i < ( gameLevel < MAX_OBSTACLES ? gameLevel: MAX_OBSTACLES) ; i++ )
{
//----------------------------------------------------------------------
// Make sure we don't put any obstacles on top or directly to the right
// of the source pipe .
//----------------------------------------------------------------------
do
{
r = random() % NP_GAME_ROWS;
c = random() % NP_GAME_COLUMNS;
}
while( r == startFlowRow && ( c == startFlowColumn || c == (startFlowColumn + 1) ) );
//----------------------------------------------------------------------
// Get cell at selected position ( row r and collumn c ) assign is as
// an obstacle and draw it.
//----------------------------------------------------------------------
currentCell = [gameMatrix cellAt:r :c ];
[currentCell assignPipe: PIPE_OBSTACLE ];
}
flowTimer = DPSAddTimedEntry(TIMEINTERVAL,&stepFun,self,NX_BASETHRESHOLD);
gameStatus = STARTED;
if( gameLevel == 1 )
[queue useMinimumPipeSet];
else if( gameLevel == 6 )
[queue useMediumPipeSet];
else if( gameLevel == 11 )
[queue useMaximumPipeSet ];
[queue randomizePipeQueue];
[gameMatrix display];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- endLevel
{
DPSRemoveTimedEntry( flowTimer );
gameStatus = PAUSED;
if( continuePanel == nil )
{
if( ![ NXApp loadNibSection:"NContinue.nib" owner: self withNames: NO ] )
return nil;
}
//[continuePanel setFloatingPanel: YES ];
[continuePanel setBecomeKeyOnlyIfNeeded: YES];
[continuePanel makeKeyAndOrderFront: nil ];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- newGame
{
printf("newGame\n");
if( gameStatus == STARTED || gameStatus == FASTFORWARD )
DPSRemoveTimedEntry( flowTimer );
if( endGamePanel != nil )
[endGamePanel close];
gameScore = 0;
gameLevel = 0;
levelBonus = 0;
levelPiecesRemaining = 0;
[self newLevel];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- pauseGame
{
if( gameStatus == STARTED )
{
gameStatus = PAUSED;
DPSRemoveTimedEntry( flowTimer );
}
else if( gameStatus == PAUSED )
{
gameStatus = STARTED;
flowTimer = DPSAddTimedEntry(TIMEINTERVAL,&stepFun,self,NX_BASETHRESHOLD);
}
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- endGame
{
DPSRemoveTimedEntry( flowTimer );
gameStatus = STOPPED;
if( endGamePanel == nil )
{
if( ![ NXApp loadNibSection:"NEnd.nib" owner: self withNames: NO ] )
return nil;
}
// [endGamePanel setFloatingPanel: YES ];
[endGamePanel setBecomeKeyOnlyIfNeeded: YES];
[endGamePanel makeKeyAndOrderFront: nil ];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- continueGame:sender
{
[continuePanel close];
gameScore += levelBonus;
gameScore -= unusedPieces * UNUSED_PIECE_PENALTY_POINTS;
levelBonus = 0;
[self newLevel];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- (int) newCellPosition: (int *) newRow : (int *) newColumn
{
switch( (int) [flowCell exitDirection ] )
{
case EAST:
(*newColumn)++;
break;
case NORTH:
(*newRow)--;
break;
case WEST:
(*newColumn)--;
break;
case SOUTH:
(*newRow)++;
break;
default:
fprintf(stderr,"Invalid exit direction from cell. [ %s, %d]\n", __FILE__, __LINE__ );
exit(1);
break;
}
if( (*newColumn) < 0 || (*newColumn) >= NP_GAME_COLUMNS )
return FALSE;
if( (*newRow) < 0 || (*newRow) >= NP_GAME_ROWS )
return FALSE;
return TRUE;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- singleClick:sender
{
int pipe;
id currentCell;
if( gameStatus == STARTED )
{
currentCell = [gameMatrix selectedCell];
if( [currentCell isPipeReplaceable] )
{
pipe = [ queue getPipePiece ];
[queue selectPipePiece];
[currentCell assignPipe: pipe];
unusedPieces++;
[self lockFocus];
[gameMatrix drawCellInside: currentCell ];
[self unlockFocus];
}
}
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- step
{
id prevFlowCell = 0;
int newFlowRow;
int newFlowColumn;
[flowCell continueFlow];
if( [flowCell isOverFlow] )
{
prevFlowCell = flowCell;
//----------------------------------------------------------------------
// Get next cell flow coordinates (row and column).
//----------------------------------------------------------------------
[gameMatrix getRow: (int *) &newFlowRow andCol: (int *) &newFlowColumn ofCell: flowCell ];
if( ![self newCellPosition: &newFlowRow : &newFlowColumn] )
{
[self endLevel];
return self;
}
flowCell = [gameMatrix cellAt:newFlowRow :newFlowColumn ];
[flowCell setFlowEntryDirection: exit2entry( [ prevFlowCell exitDirection] ) ];
if( ![flowCell isFlowPossible] )
{
if( levelPiecesRemaining > 0 )
[self endGame];
else
[self endLevel];
return self;
}
[flowCell continueFlow];
unusedPieces--;
if( levelPiecesRemaining > 0 )
{
levelPiecesRemaining--;
[theRest setIntValue: levelPiecesRemaining];
}
}
[self lockFocus];
if( prevFlowCell )
[gameMatrix drawCellInside:prevFlowCell];
[gameMatrix drawCellInside: flowCell ];
[self unlockFocus];
gameScore += [flowCell getScorePoints];
levelBonus += [flowCell getBonusPoints];
[theScore setIntValue: gameScore];
[theBonus setIntValue: levelBonus];
return self;
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- free
{
if( gameStatus == STARTED || gameStatus == FASTFORWARD )
{
gameStatus = PAUSED;
DPSRemoveTimedEntry( flowTimer );
}
[gameMatrix free];
return [super free];
}
/*----------------------------------------------------------------------*/
/* Purpose : */
/* Parameters : */
/* Return value : */
/*----------------------------------------------------------------------*/
- speedUpFlow
{
if( gameStatus == STARTED )
{
gameStatus = FASTFORWARD;
DPSRemoveTimedEntry( flowTimer );
flowTimer = DPSAddTimedEntry(FASTINTERVAL,&stepFun,self,NX_BASETHRESHOLD);
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.