#import "MazeController.h" #include #import "Maze.h" #import "Camera.h" #define degreesToRadians(degrees) (((degrees) * M_PI) / 180.0f) @implementation MazeController #define LEVEL_BASE_SIZE 2 - (id) init { self = [super init]; if (self == nil) { return nil; } camera = [[Camera alloc] init]; maze = [[Maze alloc] init]; levelIndex = 0; [maze generateNewMazeWithSizeX: (LEVEL_BASE_SIZE + ((levelIndex + 2) / 3)) sizeY: (LEVEL_BASE_SIZE + ((levelIndex + 1) / 3)) sizeZ: (LEVEL_BASE_SIZE + (levelIndex / 3))]; position = [maze gridPositionForCellIndex: [maze firstCellIndex]]; [camera setPositionImmediate: [maze spatialPositionForCellIndex: [maze cellIndexForGridPositionX: position.x Y: position.y Z: position.z]]]; facing.x = 1; facing.y = 0; facing.z = 0; [camera setOrientationImmediate: Quaternion_fromAxisAngle(Vector_withValues(0.0f, 1.0f, 0.0f), degreesToRadians(-90.0f))]; return self; } - (void) dealloc { [camera release]; [maze release]; [super dealloc]; } - (void) run { [camera run]; } - (void) draw { [camera apply]; [maze draw]; } - (void) rotateLeft { Quaternion cameraOrientation; Vector newFacing = {0.0f, 0.0f, -1.0f}; [camera rotate: Quaternion_fromAxisAngle(Vector_withValues(0.0f, 1.0f, 0.0f), degreesToRadians(90.0f))]; cameraOrientation = [camera orientation]; newFacing = Quaternion_multiplyVector(cameraOrientation, newFacing); facing.x = (newFacing.x * 1.1f); facing.y = (newFacing.y * 1.1f); facing.z = (newFacing.z * 1.1f); } - (void) rotateRight { Quaternion cameraOrientation; Vector newFacing = {0.0f, 0.0f, -1.0f}; [camera rotate: Quaternion_fromAxisAngle(Vector_withValues(0.0f, 1.0f, 0.0f), degreesToRadians(-90.0f))]; cameraOrientation = [camera orientation]; newFacing = Quaternion_multiplyVector(cameraOrientation, newFacing); facing.x = (newFacing.x * 1.1f); facing.y = (newFacing.y * 1.1f); facing.z = (newFacing.z * 1.1f); } - (void) rotateUp { Quaternion cameraOrientation; Vector newFacing = {0.0f, 0.0f, -1.0f}; [camera rotate: Quaternion_fromAxisAngle(Vector_withValues(1.0f, 0.0f, 0.0f), degreesToRadians(90.0f))]; cameraOrientation = [camera orientation]; newFacing = Quaternion_multiplyVector(cameraOrientation, newFacing); facing.x = (newFacing.x * 1.1f); facing.y = (newFacing.y * 1.1f); facing.z = (newFacing.z * 1.1f); } - (void) rotateDown { Quaternion cameraOrientation; Vector newFacing = {0.0f, 0.0f, -1.0f}; [camera rotate: Quaternion_fromAxisAngle(Vector_withValues(1.0f, 0.0f, 0.0f), degreesToRadians(-90.0f))]; cameraOrientation = [camera orientation]; newFacing = Quaternion_multiplyVector(cameraOrientation, newFacing); facing.x = (newFacing.x * 1.1f); facing.y = (newFacing.y * 1.1f); facing.z = (newFacing.z * 1.1f); } - (void) moveForward { MazeCell * currentCell; currentCell = [maze cellAtIndex: [maze cellIndexForGridPositionX: position.x Y: position.y Z: position.z]]; if ((facing.x == -1 && !currentCell->leftWall) || (facing.x == 1 && !currentCell->rightWall)) { position.x += facing.x; } else if ((facing.y == -1 && !currentCell->bottomWall) || (facing.y == 1 && !currentCell->topWall)) { position.y += facing.y; } else if ((facing.z == -1 && !currentCell->backWall) || (facing.z == 1 && !currentCell->frontWall)) { position.z += facing.z; } if (position.x < 0 || position.x >= (LEVEL_BASE_SIZE + ((levelIndex + 2) / 3)) || position.y < 0 || position.y >= (LEVEL_BASE_SIZE + ((levelIndex + 1) / 3)) || position.z < 0 || position.z >= (LEVEL_BASE_SIZE + (levelIndex / 3))) { levelIndex++; [maze generateNewMazeWithSizeX: (LEVEL_BASE_SIZE + ((levelIndex + 2) / 3)) sizeY: (LEVEL_BASE_SIZE + ((levelIndex + 1) / 3)) sizeZ: (LEVEL_BASE_SIZE + (levelIndex / 3))]; position = [maze gridPositionForCellIndex: [maze firstCellIndex]]; [camera setPositionImmediate: [maze spatialPositionForCellIndex: [maze cellIndexForGridPositionX: position.x Y: position.y Z: position.z]]]; facing.x = 1; facing.y = 0; facing.z = 0; [camera setOrientationImmediate: Quaternion_fromAxisAngle(Vector_withValues(0.0f, 1.0f, 0.0f), degreesToRadians(-90.0f))]; } [camera setPosition: [maze spatialPositionForCellIndex: [maze cellIndexForGridPositionX: position.x Y: position.y Z: position.z]]]; } @end