예제 #1
0
    // Recursive function to create cells.
    private bool CreateNextCell(stCell previous, int cellCount)
    {
        // Can't do any more?
        if (cellCount == m_maxCells)
            return false;

        // Create New Cell
        stCell newCell =
            new stCell
                (Vector3.zero, enCellDir.North, enCellType.Run);

        stCell prevCell	= previous;

        // Determine position of new cell
        Vector3 newCell_Position
            = prevCell.CellPosition;

        // Determine Height of new cell
        newCell_Position.y
            = (newCell.CellTheme == enCellTheme.Stone ? m_tileBaseHeightRuin : m_tileBaseHeightBridge);

        // Offset new cell from it's previous cell based on direction
        switch (prevCell.CellDirection)
        {
            case enCellDir.North:
                newCell_Position.z += m_cellSpacing;
                break;

            case enCellDir.South:
                newCell_Position.z -= m_cellSpacing;
                break;

            case enCellDir.East:
                newCell_Position.x += m_cellSpacing;
                break;

            case enCellDir.West:
                newCell_Position.x -= m_cellSpacing;
                break;
        }

        newCell.CellPosition
            = newCell_Position;

        newCell.CellDirection = prevCell.CellDirection;

        // Should we change direction?
        bool changeDirection =
            ( cellCount > 2 && (Random.Range(0.0f, 1.0f) > 0.65f ? true : false) ); // && (float)cellCount % 2.0f == 0.0f);

        if (changeDirection)
        {
            // Determine whether to turn left or right
            // Bit of a dirty trick, but we don't yet cater for T junctions or doubling back.
            // This prevents the track from ever crossing itself.

            float LR = (m_lastTurnDir < 0.0f? -0.5f : 0.5f);
            m_lastTurnDir *= -1.0f;

            switch (newCell.CellDirection)
            {
                case enCellDir.North:
                    newCell.CellDirection = LR < 0.0f ? enCellDir.West : enCellDir.East;
                    break;

                case enCellDir.South:
                    newCell.CellDirection = LR < 0.0f ? enCellDir.East : enCellDir.West;
                    break;

                case enCellDir.East:
                    newCell.CellDirection = LR < 0.0f ? enCellDir.North : enCellDir.South;
                    break;

                case enCellDir.West:
                    newCell.CellDirection = LR < 0.0f ? enCellDir.South : enCellDir.North;
                    break;
            }
        }

        //TODO: "Look ahead" to make sure we are not going to run into existing cells, and change direction if we are.
        // Maybe in the next version.

        // Link cells together using neighbour indices
        if (prevCell.CellDirection == enCellDir.North)
        {
            prevCell.NeighbourN = newCell;
            newCell .NeighbourS = previous;
        }

        if (prevCell.CellDirection == enCellDir.South)
        {
            prevCell.NeighbourS = newCell;
            newCell .NeighbourN = previous;
        }

        if (prevCell.CellDirection == enCellDir.East)
        {
            prevCell.NeighbourE = newCell;
            newCell .NeighbourW = previous;
        }

        if (prevCell.CellDirection == enCellDir.West)
        {
            prevCell.NeighbourW = newCell;
            newCell .NeighbourE = previous;
        }

        // Add new cell to list
        m_cells.Add (newCell);

        // Recursive call to create next cell
        CreateNextCell(newCell, cellCount + 1);

        return true;
    }
예제 #2
0
    // Dependant on a number of factors (neighbouring cells, randomness) change the provided cell into an obstacle.
    private void CreateObstacle(stCell cell)
    {
        int k = m_cells.IndexOf(cell);

        if (cell.CellType == enCellType.Run)
        {
            if (cell.CellDirection == enCellDir.North || cell.CellDirection == enCellDir.South)
            {
                if (cell.NeighbourN != null && cell.NeighbourS != null)
                {
                    if (cell.NeighbourN.CellDirection == cell.CellDirection  &&
                        cell.NeighbourS.CellDirection == cell.CellDirection )
                    {
                        // Decide whether or not to change this tile into something else
                        if (Random.Range(0.0f, 1.0f)>0.1f)
                        {
                            int i = Random.Range(0,4);

                            switch (i)
                            {
                                // Possibly make this a broken piece that needs to be jumped
                                case 0:

                                    cell.CellType = enCellType.JumpGap;

                                    // Maybe change cell theme
                                    if (Random.Range(0.0f, 1.0f)>0.5f)
                                    {
                                        for (int l=k+1;l<m_cells.Count;l++)
                                        {
                                            stCell c = m_cells[l];
                                            c.CellTheme = (c.CellTheme == enCellTheme.Stone ? enCellTheme.Bridge : enCellTheme.Stone);
                                            c.CellPosition.y = (c.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                            m_cells[l] = c;
                                        }
                                    }

                                    break;

                                // Possibly make this a narrow tile
                                case 1:
                                    cell.CellType = (Random.Range(0.0f, 1.0f) >= 0.5f ? enCellType.LedgeLeft : enCellType.LedgeRight);
                                    break;

                                // Possibly make this a jump obstacle
                                case 2:
                                    cell.CellType = enCellType.JumpObstacle;
                                    cell.CellPosition.y = m_tileBaseHeightRuin; //(cell.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                    break;
                                // Possibly make this a duck obstacle
                                case 3:
                                    cell.CellType = enCellType.DuckObstacle;
                                    cell.CellPosition.y = m_tileBaseHeightRuin; //(cell.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                    break;
                            }
                        }
                    }
                }
            }

            if (cell.CellDirection == enCellDir.East || cell.CellDirection == enCellDir.West)
            {
                if (cell.NeighbourE != null && cell.NeighbourW != null)
                {
                    if (cell.NeighbourE.CellDirection == cell.CellDirection &&
                        cell.NeighbourW.CellDirection == cell.CellDirection )
                    {
                        // Decide whether or not to change this tile into something else
                        if (Random.Range(0.0f, 1.0f)>0.1f)
                        {
                            int i = Random.Range(0,4);

                            switch (i)
                            {
                                // Possibly make this a broken piece that needs to be jumped
                                case 0:

                                    cell.CellType = enCellType.JumpGap;

                                    // Maybe change cell theme
                                    if (Random.Range(0.0f, 1.0f)>0.5f)
                                    {
                                        for (int l=k+1;l<m_cells.Count;l++)
                                        {
                                            stCell c = m_cells[l];
                                            c.CellTheme = (c.CellTheme == enCellTheme.Stone ? enCellTheme.Bridge : enCellTheme.Stone);
                                            c.CellPosition.y = (c.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                            m_cells[l] = c;
                                        }
                                    }

                                    break;

                                // Possibly make this a narrow tile
                                case 1:
                                    cell.CellType = (Random.Range(0.0f, 1.0f) >= 0.5f ? enCellType.LedgeLeft : enCellType.LedgeRight);
                                    break;

                                // Possibly make this a jump obstacle
                                case 2:
                                    cell.CellType = enCellType.JumpObstacle;
                                    cell.CellPosition.y = m_tileBaseHeightRuin; //(cell.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                    break;
                                // Possibly make this a duck obstacle
                                case 3:
                                    cell.CellType = enCellType.DuckObstacle;
                                    cell.CellPosition.y = m_tileBaseHeightRuin; //(cell.CellTheme == enCellTheme.Stone? m_tileBaseHeightRuin : m_tileBaseHeightBridge);
                                    break;

                            }
                        }
                    }
                }
            }
        }
    }
예제 #3
0
    // Randomly place coins on the provided cell
    private void CreateCoins(stCell cell)
    {
        // Create Coins!
        if (Random.Range(0.0f, 1.0f) > 0.25f)
        {
            float r = Random.Range(-1,1);

            // Offset placement if on a ledge, so player can get the coins.  Aren't we nice?

            if (cell.CellType == enCellType.LedgeLeft  && cell.CellDirection == enCellDir.North) r = -1;
            if (cell.CellType == enCellType.LedgeRight && cell.CellDirection == enCellDir.North) r =  1;

            if (cell.CellType == enCellType.LedgeLeft  && cell.CellDirection == enCellDir.East) r =  1;
            if (cell.CellType == enCellType.LedgeRight && cell.CellDirection == enCellDir.East) r = -1;

            Vector3 laneOffset = Vector3.zero;

            if (cell.CellDirection == enCellDir.North || cell.CellDirection == enCellDir.South)
                laneOffset.x = r * 0.3f;

            if (cell.CellDirection == enCellDir.East || cell.CellDirection == enCellDir.West)
                laneOffset.z = r * 0.3f;

            for (float k=0.5f; k<1.0f; k+=0.1f)
            {
                Vector3 pos = cell.CellPosition;
                pos.y = m_coinHeight;

                float offset =
                    (k * m_cellSpacing) - (m_cellSpacing / 2.0f);

                switch (cell.CellDirection)
                {
                    case enCellDir.North:
                        pos.z += offset;
                        break;

                    case enCellDir.South:
                        pos.z -= offset;
                        break;

                    case enCellDir.East:
                        pos.x += offset;
                        break;

                    case enCellDir.West:
                        pos.x -= offset;
                        break;
                }

                if (cell.CellType == enCellType.JumpGap || cell.CellType == enCellType.JumpObstacle)
                {
                    pos.y += 0.5f + (Mathf.Sin(k * 10.0f) * 0.1f);
                    if (cell.CellDirection == enCellDir.North) pos.z -= (m_cellSpacing / 5.0f);
                    if (cell.CellDirection == enCellDir.East)  pos.x -= (m_cellSpacing / 5.0f);
                }

                GameObject coin = (GameObject)Instantiate(m_GoldCoin, pos + laneOffset, Quaternion.Euler(0, 360.0f / (k + 0.5f),0));
                cell.m_coins.Add(coin);
            }
        }
    }
예제 #4
0
    // Add landmine to the provided cell.  Maybe.
    private void CreateLandMine(stCell cell)
    {
        // Create LandMines!!!
        if (Random.Range(0.0f, 1.0f) > 0.5f && m_cells.IndexOf(cell) > 2)
        {
            // We only create landmines on "standard" cells
            if (cell.CellType == enCellType.Run)
            {
                // And not in corners.  That wouldn't be fair.
                if (!isCornerCell(cell))
                {
                    // Create the landmine.
                    GameObject landMine = (GameObject)Instantiate(m_LandMine, cell.CellPosition + Vector3.up * (cell.CellTheme == enCellTheme.Stone? 0.8f : 0.1f), Quaternion.identity);
                    cell.m_mines.Add(landMine);

                    // Decide where to place the warning sign based on cell orientation
                    Vector3 lmPos = cell.CellPosition + Vector3.up * (cell.CellTheme == enCellTheme.Stone? 1.0f : 0.05f);
                    Quaternion lmRot = Quaternion.identity;

                    if (cell.CellDirection == enCellDir.North)
                    {
                        lmPos.x -= (m_cellSpacing * 0.085f);
                        lmPos.z -= (m_cellSpacing * 0.6f);
                    }

                    if (cell.CellDirection == enCellDir.East)
                    {
                        lmPos.z += (m_cellSpacing * 0.085f);
                        lmPos.x -= (m_cellSpacing * 0.6f);
                        lmRot = Quaternion.Euler(0,90,0);
                    }

                    if (cell.CellDirection == enCellDir.West)
                    {
                        lmPos.z += (m_cellSpacing * 0.085f);
                        lmPos.x += (m_cellSpacing * 0.6f);
                        lmRot = Quaternion.Euler(0,270,0);
                    }

                    // Create warning sign.
                    GameObject warningSign 	= (GameObject)Instantiate(m_LandMineSign, lmPos, lmRot);
                    cell.m_deco.Add(warningSign);
                }
            }
        }
    }
예제 #5
0
    // places the correct 3d model in the scene for a cell based on direction, type and neighbours
    // Simple nested switch statements and model rotations, nothing complex here.
    private void CreateCellModel(stCell cell)
    {
        GameObject prefabToInstantiate
            = null;

        Quaternion rotation = Quaternion.identity;

        switch (cell.CellType)
        {
            case enCellType.JumpObstacle:

                if (cell.CellTheme == enCellTheme.Stone ) prefabToInstantiate = m_ITile_ObstacleJump;
                if (cell.CellTheme == enCellTheme.Bridge) prefabToInstantiate = m_Bridge_ITile_ObstacleJump;

                if (cell.CellDirection == enCellDir.North || cell.CellDirection == enCellDir.South) rotation = Quaternion.Euler(0.0f,  0.0f, 0.0f);
                if (cell.CellDirection == enCellDir.East  || cell.CellDirection == enCellDir.West ) rotation = Quaternion.Euler(0.0f, 90.0f, 0.0f);

                break;

            case enCellType.DuckObstacle:

                if (cell.CellTheme == enCellTheme.Stone ) prefabToInstantiate = m_ITile_ObstacleDuck;
                if (cell.CellTheme == enCellTheme.Bridge) prefabToInstantiate = m_Bridge_ITile_ObstacleDuck;

                if (cell.CellDirection == enCellDir.North || cell.CellDirection == enCellDir.South) rotation = Quaternion.Euler(0.0f,  0.0f, 0.0f);
                if (cell.CellDirection == enCellDir.East  || cell.CellDirection == enCellDir.West)  rotation = Quaternion.Euler(0.0f, 90.0f, 0.0f);

                break;

            case enCellType.LedgeLeft:

                switch (cell.CellDirection)
                {
                    case enCellDir.North:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,0.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,0.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.South:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,180.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,180.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.East:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,90.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,90.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.West:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,270.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,270.0f,0.0f);

                                break;
                        }

                        break;
                }

                break;

            case enCellType.LedgeRight:

                switch (cell.CellDirection)
                {
                    case enCellDir.North:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,180.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,180.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.South:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,0.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,0.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.East:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,270.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,270.0f,0.0f);

                                break;
                        }

                        break;

                    case enCellDir.West:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                prefabToInstantiate = m_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,90.0f,0.0f);

                                break;

                            case enCellTheme.Bridge:

                                prefabToInstantiate = m_Bridge_ITileBrokenHalf;
                                rotation = Quaternion.Euler(0.0f,90.0f,0.0f);

                                break;
                        }

                        break;
                }

                break;

            case enCellType.JumpGap:

                switch (cell.CellDirection)
                {
                    case enCellDir.North:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                if (cell.NeighbourN.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                                }

                                if (cell.NeighbourN.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                                }

                                break;

                            case enCellTheme.Bridge:

                                if (cell.NeighbourN.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                                }

                                if (cell.NeighbourN.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,180.0f,0.0f);
                                    m_cells[m_cells.IndexOf(cell)].CellPosition.y = m_tileBaseHeightRuin;
                                }

                                break;
                        }

                        break;

                    case enCellDir.South:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                if (cell.NeighbourN.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,180.0f,0.0f);
                                }

                                if (cell.NeighbourN.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,180.0f,0.0f);
                                }

                                break;

                            case enCellTheme.Bridge:

                                if (cell.NeighbourN.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,180.0f,0.0f);
                                }

                                if (cell.NeighbourN.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                                    m_cells[m_cells.IndexOf(cell)].CellPosition.y = m_tileBaseHeightRuin;
                                }

                                break;
                        }

                        break;

                    case enCellDir.East:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                if (cell.NeighbourE.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                                }

                                if (cell.NeighbourE.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                                }

                                break;

                            case enCellTheme.Bridge:

                                if (cell.NeighbourE.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                                }

                                if (cell.NeighbourE.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                                    m_cells[m_cells.IndexOf(cell)].CellPosition.y = m_tileBaseHeightRuin;
                                }

                                break;
                        }

                        break;

                    case enCellDir.West:

                        switch (cell.CellTheme)
                        {
                            case enCellTheme.Stone:

                                if (cell.NeighbourE.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                                }

                                if (cell.NeighbourE.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                                }

                                break;

                            case enCellTheme.Bridge:

                                if (cell.NeighbourE.CellTheme == enCellTheme.Bridge)
                                {
                                    prefabToInstantiate = m_Bridge_ITileBroken;
                                    rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                                }

                                if (cell.NeighbourE.CellTheme == enCellTheme.Stone)
                                {
                                    prefabToInstantiate = m_Bridge2Stone_ITile;
                                    rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                                    m_cells[m_cells.IndexOf(cell)].CellPosition.y = m_tileBaseHeightRuin;
                                }

                                break;
                        }

                        break;
                }

                break;

            case enCellType.Run:

                switch (cell.CellDirection)
                {
                    case enCellDir.North:

                        if (cell.NeighbourS != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_ITile : m_Bridge_ITile);
                            rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                        }

                        if (cell.NeighbourW != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_LTile : m_Bridge_LTile);
                            rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                        }

                        if (cell.NeighbourE != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_LTile : m_Bridge_LTile);
                            rotation = Quaternion.Euler(0.0f,0.0f,0.0f);
                        }

                        break;

                    case enCellDir.East:

                        if (cell.NeighbourW != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_ITile : m_Bridge_ITile);
                            rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                        }

                        if (cell.NeighbourS != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_LTile : m_Bridge_LTile);
                            rotation = Quaternion.Euler(0.0f,90.0f,0.0f);
                        }

                        break;

                    case enCellDir.West:

                        if (cell.NeighbourE != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_ITile : m_Bridge_ITile);
                            rotation = Quaternion.Euler(0.0f,270.0f,0.0f);
                        }

                        if (cell.NeighbourS != null)
                        {
                            prefabToInstantiate = (cell.CellTheme == enCellTheme.Stone ? m_LTile : m_Bridge_LTile);
                            rotation = Quaternion.Euler(0.0f,180.0f,0.0f);
                        }

                        break;

                }

                break;
        }

        if (prefabToInstantiate != null)
        {
            GameObject newCellModel =
                (GameObject)Instantiate
                    (prefabToInstantiate, cell.CellPosition, rotation);

            newCellModel.transform.parent
                = this.transform;

            cell.CellModel = newCellModel;
        }
    }
예제 #6
0
    // Start cell creation process
    private void CreateCells()
    {
        // Setup Root Cell
        stCell rootCell =
            new stCell
                (Vector3.zero, enCellDir.North, enCellType.Run);

        rootCell.CellPosition.y
            = m_tileBaseHeightRuin;

        m_cells.Add(rootCell);

        GameObject newCellModel =
                (GameObject)Instantiate
                    (m_ITile, rootCell.CellPosition, Quaternion.identity);

            newCellModel.transform.parent
                = this.transform;

        rootCell.CellModel = newCellModel;

        // Create track segment ready for player to run along
        CreateNewCellsIfNeeded(true);
    }
예제 #7
0
        // CTOR
        public stCell(Vector3    cellPosition,
				 enCellDir  cellDirection,
				 enCellType cellType)
        {
            this.CellPosition  = cellPosition;
                this.CellDirection = cellDirection;
                this.CellType 	= cellType;
                this.CellTheme  = csTempleRun.enCellTheme.Stone;

                this.NeighbourN = null;
                this.NeighbourS = null;
                this.NeighbourE = null;
                this.NeighbourW = null;
        }
예제 #8
0
    // Logic for the player.
    private void UpdatePlayer()
    {
        // if the player is dead (replaced with ragdoll) then exit since none of this code should fire.
        if (m_player == null)
        {
            return;
        }

        // AUTO PLAYER FOR TESTING
        // Allows the AI to control the player.  Used for debugging mainly.

        //		m_playerNextDirection = m_playerCell.CellDirection;
        //		if (m_playerCell.CellType == enCellType.DuckObstacle && m_playerSlide <=0.0f && m_playerTimer <0.25f)
        //		{
        //			m_playerSlide = 1.0f;
        //		}
        //		else if (m_playerCell.CellType != enCellType.Run &&  m_playerCell.CellType != enCellType.DuckObstacle && m_playerJump <=-1.0f && m_playerTimer >=0.2f && m_playerSlide <=0.0f)
        //		{
        //			m_playerJump = 1.0f;
        //		}

        // Gradually increase the players' running speed, and update the animation to match.
        m_playerRunSpeed += Time.deltaTime * 0.005f;
        m_playerRunSpeed = Mathf.Clamp(m_playerRunSpeed, 0.5f, 3.0f);
        m_player.animation["run"].speed = m_playerRunSpeed * 2.0f;

        // ****************************************************************************************
        // INPUT

        // Player can only turn if they are not already sliding / jumping.
        // Equally, sliding / jumping are mutually exclusive.

        if (Input.GetKeyDown(KeyCode.LeftArrow) && m_playerJump <= -1.0f && m_playerSlide <=0.0f)
        {
            if (m_playerDirection == enCellDir.North) m_playerNextDirection = enCellDir.West;
            if (m_playerDirection == enCellDir.East ) m_playerNextDirection = enCellDir.North;
            if (m_playerDirection == enCellDir.South) m_playerNextDirection = enCellDir.East;
            if (m_playerDirection == enCellDir.West ) m_playerNextDirection = enCellDir.South;
        }

        if (Input.GetKeyDown(KeyCode.RightArrow) && m_playerJump <= -1.0f && m_playerSlide <=0.0f)
        {
            if (m_playerDirection == enCellDir.North) m_playerNextDirection = enCellDir.East;
            if (m_playerDirection == enCellDir.East ) m_playerNextDirection = enCellDir.South;
            if (m_playerDirection == enCellDir.South) m_playerNextDirection = enCellDir.West;
            if (m_playerDirection == enCellDir.West ) m_playerNextDirection = enCellDir.North;
        }

        if (Input.GetKeyDown(KeyCode.DownArrow) && m_playerJump <= -1.0f && m_playerSlide <=0.0f)
        {
            m_playerSlide = 1.0f;
            m_player.animation.Play("slide_fake");
        }

        if ((Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space)) && m_playerJump <= -1.0f && m_playerSlide <=0.0f)
        {
            AudioSource.PlayClipAtPoint(m_jumpAudio, m_player.transform.position);
            m_playerJump = 1.0f;
            m_playerYvel = 0.0f;
            m_player.animation.Play("jump");
        }

        // ****************************************************************************************

        // Reset animation if not jumping, sliding, or stumbling.
        if (m_playerJump <=-1.0f && m_playerSlide <=0.0f)
        {
            if (!m_player.animation.IsPlaying("flip"))
                m_player.animation.Play("run");
        }

        // If we are stumbling, make the camera shake a little.
        if (m_stumble > 0.0f)
        {
            m_stumble -= Time.deltaTime * 2.0f;

            Camera.mainCamera.transform.Rotate
                (Vector3.up, Random.Range(m_stumble * -5.0f, m_stumble * 5.0f));
        }

        // Increase the players progress across the current cell, taking into accound current run speed and stumbling
        m_playerTimer +=
            Time.deltaTime * (m_stumble > 0.0f ? m_playerRunSpeed / 4.0f : m_playerRunSpeed);

        // If we reach the end of a cell, we need to move to the next one (or possibly die!)
        if (m_playerTimer >= 1.0f)
        {
            m_distanceRun += 10.0f;
            m_playerTimer  = 0.0f;

            m_previousCellDirection = m_playerCell.CellDirection;

            // Determine which cell to move the player to.
            switch (m_playerCell.CellDirection)
            {
                case enCellDir.North:
                    m_playerCell = m_playerCell.NeighbourN;
                    break;

                case enCellDir.South:
                    m_playerCell = m_playerCell.NeighbourS;
                    break;

                case enCellDir.East:
                    m_playerCell = m_playerCell.NeighbourE;
                    break;

                case enCellDir.West:
                    m_playerCell = m_playerCell.NeighbourW;
                    break;
            }
        }

        // Tell the current cell it's been visited, so it can be removed later.
        m_playerCell.Visited = true;

        // If current cell is unspecified (usually on first run) then reset some stuff.
        if (m_playerCell == null)
        {
            m_playerCell            = m_cells[0];
            m_playerDirection       = enCellDir.North;
            m_playerNextDirection   = enCellDir.North;
            m_previousCellDirection = enCellDir.North;
        }

        #region Obstacles

        // here, we check for the various ways in which the player can screw up, and die.

        // Is the current cell an obstacle that should be ducked under?
        if (m_playerCell.CellType == enCellType.DuckObstacle)
        {
            if (m_playerTimer >= 0.4f && m_playerTimer <= 0.6f)
            {
                if (m_playerJump >-1.0f || m_playerSlide <=0.0f)
                {
                    if (m_playerSlide <=0.0f && m_playerJump <=-1.0f)
                    {
                        m_player.transform.Translate(Vector3.up * 0.1f);
                    }

                    DoRagDoll(true, false, m_splatAudio);
                    m_dieReason = "Ouch!  Migraine.  Duck next time!";
                }
            }
        }

        // Is the current cell an obstacle that should be jumped (boxes in this case)?
        if (m_playerCell.CellType == enCellType.JumpObstacle &&
            m_playerJump  <= -1.0f &&
            m_playerTimer >= 0.45f &&
            m_playerTimer <= 0.55f &&
            m_stumble     <=0.0f)
        {
            DoRagDoll(true, false, m_splatAudio);
            m_dieReason = "Don't forget to jump.  Boxes hurt.";
        }

        // Are we on a narrow ledge, and not leaning towards the opposite side?
        if (m_playerCell.CellType == enCellType.LedgeLeft)
        {
            if (m_tilt >=-0.05f && m_playerTimer >=0.3f && m_playerTimer <=0.6f && m_playerJump <=-1.0f)
            {
                DoRagDoll(false, false, m_playerCell.CellTheme == enCellTheme.Stone ? m_splatAudio : m_fallAudio);
                m_dieReason = "Watch your footing!  Use the mouse to slide to the side.";
            }
        }

        // Are we on a narrow ledge, and not leaning towards the opposite side?
        if (m_playerCell.CellType == enCellType.LedgeRight)
        {
            if (m_tilt <=0.05f && m_playerTimer >=0.3f && m_playerTimer <=0.6f && m_playerJump <=-1.0f)
            {
                DoRagDoll(false, false, m_playerCell.CellTheme == enCellTheme.Stone ? m_splatAudio : m_fallAudio);
                m_dieReason = "Watch your footing!  Use the mouse to slide to the side.";
            }
        }

        // Should we be jumping over a gap?
        if (m_playerCell.CellType == enCellType.JumpGap && m_playerJump <=-1.0f)
        {
            if (m_playerTimer > 0.3f && m_playerTimer < 0.7f)
            {
                if (m_playerTimer <  0.4f) DoRagDoll(false, false, m_fallAudio);
                if (m_playerTimer >= 0.4f) DoRagDoll(false, false, m_splatAudio);

                m_dieReason = "Swan dive with triple bone-crunch!  (don't forget to jump at the right time...)";
            }
        }

        //If we are on a straight, and the player has changed direction, we should "stumble"
        if ( (m_previousCellDirection    == m_playerCell.CellDirection) &&
             (m_playerCell.CellDirection != m_playerNextDirection) && m_stumble <=0.0f)
        {
            m_stumble = 1.0f;
            m_playerNextDirection = m_playerDirection;
            AudioSource.PlayClipAtPoint(m_stumbleAudio, m_player.transform.position);
            m_player.animation.Blend("flip");
        }

        // Change Player Direction if we are on a turn cell
        if (m_playerTimer >= 0.5f && m_previousCellDirection != m_playerCell.CellDirection)
        {
            // If we haven't already
            if (m_playerDirection != m_playerNextDirection)
            {
                // Set player direction to player next direction (from input)
                m_playerDirection = m_playerNextDirection;
                AudioSource.PlayClipAtPoint(m_turnAudio, m_player.transform.position);
            }

            // If player is not travelling in the correct direction, then we destroy player and create ragdoll
            if (m_playerDirection !=  m_playerCell.CellDirection)
            {
                if (m_playerJump > -1.0f)
                {
                    DoRagDoll(true, false, m_fallAudio);
                    m_dieReason = "Wheeeeeeeee!";
                }
                else
                {
                    DoRagDoll(false, false, m_splatAudio);
                    m_dieReason = "Good job your face was there to take the brunt of the impact.";
                }
            }
        }

        #endregion

        // This is a cheap trick as we didn't have a slide animation.  Simply put the character on his back and play a mini-jump animation.
        // Hey, if it works...
        float xRot = m_playerSlide >0.0f ? -70.0f : 0.0f;

        // Change Player Rotation
        if (m_playerDirection == enCellDir.North) m_player.transform.rotation = Quaternion.Euler(xRot,000,0);
        if (m_playerDirection == enCellDir.South) m_player.transform.rotation = Quaternion.Euler(xRot,180,0);
        if (m_playerDirection == enCellDir.East ) m_player.transform.rotation = Quaternion.Euler(xRot,090,0);
        if (m_playerDirection == enCellDir.West ) m_player.transform.rotation = Quaternion.Euler(xRot,270,0);

        // Update player position
        Vector3 pos =
            m_playerCell.CellPosition;

        float offset =
            (m_playerTimer * m_cellSpacing) - (m_cellSpacing / 2.0f);

        switch (m_playerDirection)
        {
            case enCellDir.North:
                pos.z += offset;
                break;

            case enCellDir.South:
                pos.z -= offset;
                break;

            case enCellDir.East:
                pos.x += offset;
                break;

            case enCellDir.West:
                pos.x -= offset;
                break;
        }

        pos.y = m_playerBaseHeight;

        // Do Jumping
        if (m_playerJump > -1.0f)
        {
            // This controls how fast the jump happens
            // Tweak at your peril.  Too long, jumps are easy, too short, you'll never make it.
            m_playerJump -= Time.deltaTime * (m_playerRunSpeed * 3.5f);
            m_playerYvel += m_playerJump;

            // This controls how high the player jumps.  Has no effect on gameplay.
            pos.y += m_playerYvel * 0.05f;
        }

        // Do Sliding
        if (m_playerSlide >0.0f)
        {
            m_playerSlide -= Time.deltaTime* (m_playerRunSpeed * 1.5f);
        }

        // Set the player's position taking everything above into account.
        m_player.transform.position = pos;

        // Strafing, based on mouse input (to simulate tilting the phone, ala Temple Run).
        m_tilt += Input.GetAxis("Mouse X") * 0.035f;
        m_tilt = Mathf.Clamp(m_tilt, -0.35f, 0.35f);
        m_tilt = Mathf.Lerp(m_tilt, 0.0f, Time.deltaTime * 2.0f);
        m_player.transform.Translate(Vector3.right * m_tilt);
    }
예제 #9
0
    // Is the provided cell a corner?
    private bool isCornerCell(stCell cell)
    {
        if (cell.CellDirection == enCellDir.North)
        {
            if (cell.NeighbourE != null || cell.NeighbourW != null) return true;
        }

        if (cell.CellDirection == enCellDir.East)
        {
            if (cell.NeighbourN != null || cell.NeighbourS != null) return true;
        }

        if (cell.CellDirection == enCellDir.West)
        {
            if (cell.NeighbourN != null || cell.NeighbourS != null) return true;
        }

        return false;
    }
예제 #10
0
    // Add some stuff in the water around the current cell to make the game more interesting (rocks, trees, ruins, etc).
    private void CreateScenery(stCell cell)
    {
        // We never decorate the "last" cell, since we might end up blocking off the route when new track get's created.
        // And yes I could have cleaned up existing decorations when this happens but couldn't be arsed.
        if (m_cells.IndexOf(cell) == m_cells.Count-1) return;

        // Randomly place archways over the track (as long as we're not on a corner).
        if (Random.Range(0.0f, 1.0f) > 0.25f)
        {
            Quaternion archRot = Quaternion.identity;

            if (cell.CellDirection == enCellDir.North || cell.CellDirection == enCellDir.South) archRot = Quaternion.Euler(0,0,0);
            if (cell.CellDirection == enCellDir.East  || cell.CellDirection == enCellDir.West)  archRot = Quaternion.Euler(0,90,0);

            bool bOkArch = true;

            switch (cell.CellDirection)
            {
                case enCellDir.North:

                    if (cell.NeighbourS != null)
                    {
                        bOkArch = true;
                    }

                    if (cell.NeighbourW != null)
                    {
                        bOkArch = false;
                    }

                    if (cell.NeighbourE != null)
                    {
                        bOkArch = false;
                    }

                    break;

                case enCellDir.East:

                    if (cell.NeighbourW != null)
                    {
                        bOkArch = true;
                    }

                    if (cell.NeighbourS != null)
                    {
                        bOkArch = false;
                    }

                    break;

                case enCellDir.West:

                    if (cell.NeighbourE != null)
                    {
                        bOkArch = true;
                    }

                    if (cell.NeighbourS != null)
                    {
                        bOkArch = false;
                    }

                    if (cell.NeighbourN != null)
                    {
                        bOkArch = false;
                    }

                    break;

            }

            Vector3 pos = cell.CellPosition;
            if (cell.CellTheme == enCellTheme.Bridge) pos.y = m_tileBaseHeightRuin;

            if (bOkArch)
            {
                GameObject arch = (GameObject)Instantiate(m_Arch, pos, archRot);
                cell.m_deco.Add(arch);
            }
        }

        // Create Scenery
        if (cell.NeighbourW == null && Random.Range(0.0f, 1.0f) > 0.25f)
        {
            int sceneryID = Random.Range(0,8);
            GameObject sceneryPrefab = null;

            switch (sceneryID)
            {
                case 0: sceneryPrefab = m_Rock1;  break;
                case 1: sceneryPrefab = m_Rock2;  break;
                case 2: sceneryPrefab = m_Rock3;  break;
                case 3: sceneryPrefab = m_Rock4;  break;
                case 4: sceneryPrefab = m_Column; break;
                case 5: sceneryPrefab = m_Tree;   break;
                case 6: sceneryPrefab = m_Ruin1;  break;
                case 7: sceneryPrefab = m_Ruin2;  break;
            }

            Vector3 pos = cell.CellPosition + Vector3.left * m_cellSpacing / 3.0f;
            pos.y = -0.5f;

            GameObject sceneryObject = (GameObject)Instantiate(sceneryPrefab, pos, Quaternion.Euler(0.0f, Random.Range(0,3) * 90, 0.0f));
            sceneryObject.transform.parent = this.transform;
            cell.m_deco.Add(sceneryObject);
        }

        // Create Scenery
        if (cell.NeighbourE == null && Random.Range(0.0f, 1.0f) > 0.25f)
        {
            int sceneryID = Random.Range(0,8);
            GameObject sceneryPrefab = null;

            switch (sceneryID)
            {
                case 0: sceneryPrefab = m_Rock1;  break;
                case 1: sceneryPrefab = m_Rock2;  break;
                case 2: sceneryPrefab = m_Rock3;  break;
                case 3: sceneryPrefab = m_Rock4;  break;
                case 4: sceneryPrefab = m_Column; break;
                case 5: sceneryPrefab = m_Tree;   break;
                case 6: sceneryPrefab = m_Ruin1;  break;
                case 7: sceneryPrefab = m_Ruin2;  break;
            }

            Vector3 pos = cell.CellPosition + Vector3.right * m_cellSpacing * 0.5f;
            pos.y = -0.5f;

            GameObject sceneryObject = (GameObject)Instantiate(sceneryPrefab, pos, Quaternion.Euler(0.0f, Random.Range(0,3) * 90, 0.0f));
            sceneryObject.transform.parent = this.transform;
            cell.m_deco.Add(sceneryObject);
        }

        // Create Scenery
        if (cell.NeighbourN == null && Random.Range(0.0f, 1.0f) > 0.25f)
        {
            int sceneryID = Random.Range(0,8);
            GameObject sceneryPrefab = null;

            switch (sceneryID)
            {
                case 0: sceneryPrefab = m_Rock1;  break;
                case 1: sceneryPrefab = m_Rock2;  break;
                case 2: sceneryPrefab = m_Rock3;  break;
                case 3: sceneryPrefab = m_Rock4;  break;
                case 4: sceneryPrefab = m_Column; break;
                case 5: sceneryPrefab = m_Tree;   break;
                case 6: sceneryPrefab = m_Ruin1;  break;
                case 7: sceneryPrefab = m_Ruin2;  break;
            }

            Vector3 pos = cell.CellPosition + Vector3.forward * m_cellSpacing * 0.5f;
            pos.y = -0.5f;

            GameObject sceneryObject = (GameObject)Instantiate(sceneryPrefab, pos, Quaternion.Euler(0.0f, Random.Range(0,3) * 90, 0.0f));
            sceneryObject.transform.parent = this.transform;
            cell.m_deco.Add(sceneryObject);
        }

        // Create Scenery
        if (cell.NeighbourS == null && Random.Range(0.0f, 1.0f) > 0.25f)
        {
            int sceneryID = Random.Range(0,8);
            GameObject sceneryPrefab = null;

            switch (sceneryID)
            {
                case 0: sceneryPrefab = m_Rock1;  break;
                case 1: sceneryPrefab = m_Rock2;  break;
                case 2: sceneryPrefab = m_Rock3;  break;
                case 3: sceneryPrefab = m_Rock4;  break;
                case 4: sceneryPrefab = m_Column; break;
                case 5: sceneryPrefab = m_Tree;   break;
                case 6: sceneryPrefab = m_Ruin1;  break;
                case 7: sceneryPrefab = m_Ruin2;  break;
            }

            Vector3 pos = cell.CellPosition + Vector3.back * m_cellSpacing * 0.5f;
            pos.y = -0.5f;

            GameObject sceneryObject = (GameObject)Instantiate(sceneryPrefab, pos, Quaternion.Euler(0.0f, Random.Range(0,3) * 90, 0.0f));
            sceneryObject.transform.parent = this.transform;
            cell.m_deco.Add(sceneryObject);
        }
    }
예제 #11
0
    // Set / reset the player at the start of each run.
    private void CreatePlayer()
    {
        m_player = (GameObject)Instantiate(m_playerPrefab);

        m_playerRunSpeed = m_playerRunSpeedStart;

        m_player.animation["run" ].speed = m_playerRunSpeed * 2.0f;
        m_player.animation["jump"].speed = 1.5f;

        m_playerCell            = m_cells[0];
        m_playerDirection       = enCellDir.North;
        m_playerNextDirection   = enCellDir.North;
        m_previousCellDirection = enCellDir.North;

        m_playerJump = -1.0f;
        m_playerYvel =  0.0f;
        m_playerSlide = 0.0f;

        if (m_distanceRun > m_distanceRunBest)
            m_distanceRunBest = m_distanceRun;

        m_distanceRun = 0.0f;

        if (m_coinsCollected > m_coinsCollectedBest)
            m_coinsCollectedBest = m_coinsCollected;

        m_coinsCollected = 0;

        if (m_playerRagDoll != null) Destroy(m_playerRagDoll);
    }