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.