Online Book Reader

Home Category

iPhone Game Development - Chris Craft [41]

By Root 1511 0
into place:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [touches anyObject];

for (int i=0 ; i<(currentLevel.gridSize*currentLevel.gridSize)-1; i++) {

if ([touch view] == tiles[i]) {

if ([self tileCanMoveToIndexFromIndex:tiles[i].location]) {

int oldLocation = tiles[i].location;

int newLocation = emptyTile;

// only move to the new location if the center of the moving tile is

// inside the empty tile

CGRect emptyTileRect = [TileView getRectForLocation:emptyTile

withDimension:currentLevel.gridSize

withSize:currentLevel.tileSize];

if (CGRectContainsPoint(emptyTileRect, tiles[i].center)) {

[self moveTile:tiles[i] toLocation:newLocation];

emptyTile = oldLocation;

}

else {

[self moveTile:tiles[i] toLocation:oldLocation];

}

}

break;

}

}

[self testDidWin];

}

After reviewing these two methods that handle touch, play around with the example on the iPhone. We believe you will find that this treatment of the touch events creates a realistic experience for players.

Reviewing the utility methods

The moveTile method is used to snap a tile into place. First, it begins the animation. Next, we set the location of the tile. By setting the location index of the tile view, we will internally update its frame. Finally, we commit the animation. This produces our nice little effect of snapping the tile into place:

- (void)moveTile:(TileView*)tileView toLocation:(int)aLocation {

[UIView beginAnimations:nil context:nil];

[UIView setAnimationDuration:0.25];

tileView.location = aLocation;

[UIView commitAnimations];

[tileView updateArrowPoint];

}

You will see the method tileCanMoveToIndexFromIndex used a lot. As expected, this method returns true if a tile can make a legal move from its current index to the empty tile index. This is calculated by checking to see if the tile in question is adjacent to the empty tile:

- (bool)tileCanMoveToIndexFromIndex:(int)index {

int fromX = [TileView getXForLocation:index

withDimension:currentLevel.gridSize];

int fromY = [TileView getYForLocation:index

withDimension:currentLevel.gridSize];

int toX = [TileView getXForLocation:emptyTile

withDimension:currentLevel.gridSize];

int toY = [TileView getYForLocation:emptyTile

withDimension:currentLevel.gridSize];

if (fromX == toX && (fromY+1 == toY || fromY-1 == toY) )

return true;

if (fromY == toY && (fromX+1 == toX || fromX-1 == toX) )

return true;

return false;

}

The method tilesInCorrectLocation checks to see if all arrow tiles are currently seated in their correct location. We can determine this by comparing the tile's index to the tile's location. If this is the case for every arrow tile, this method returns true:

- (bool)tilesInCorrectLocation {

for (int i=0 ; i<(currentLevel.gridSize*currentLevel.gridSize)-1; i++) {

TileView *tileView = tiles[i];

if (tileView.tileType == arrow && tileView.location != i)

return false;

}

return true;

}

The last method we will review in this example is testDidWin. This method is called at the completion of each move (look at the earlier method touchesEnded). If the method tilesInCorrectLocation returns true, we know that the player has completed the level.

If we pass this condition, we see an alert view that proclaims the player's success. Finally, we call loadLevel to automatically load the next level in the sequence. When the player dismisses the alert, he can begin playing the next level:

- (void)testDidWin {

if (![self tilesInCorrectLocation]) return;

NSString *message = [NSString stringWithFormat:

@”You have just completed level %d on to the next level”,

currentLevelIndex+1];

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:

@”Level Complete!” message:message delegate:nil cancelButtonTitle:

@”OK” otherButtonTitles:nil];

[alertView show];

[alertView release];

[Helper setUserValue:[NSString stringWithFormat:

Return Main Page Previous Page Next Page

®Online Book Reader