Ejemplo n.º 1
0
    /**
     * Generate a world using the given .JSON file in 'levelDescriptionJson'
     */
    public void CreateWorldFromLevelDescription()
    {
        LevelEntitiesJSON level = JsonUtility.FromJson <LevelEntitiesJSON>(levelDescriptionJsonFiles[levelFileIndex].text);

        gameController.winCondition = GetWinConditionFromString(level.winCondition);
        // list of link blocks we are creating
        levelLinks = new List <LinkBehavior>();
        Debug.Log("Loading blocks");
        // while generating the level, add things to levelEntities list so it can be destroyed for the next level generated.
        for (int i = 0; i < level.blocks.Length; i++)
        {
            Vector2 blockPos = new Vector2((float)(level.blocks[i].x + (level.blocks[i].width / 2f)),
                                           (float)(level.blocks[i].y - (level.blocks[i].height / 2f)));
            Transform objToInstances = GetAssocInstanceFromType(level.blocks[i].type);
            if (objToInstances != null)
            {
                if (objToInstances == groundPreFab && level.blocks[i].height == 1)
                {
                    objToInstances = groundTopPreFab; // render it with details on top of the block.
                }
                Transform obj         = Instantiate(objToInstances, blockPos, Quaternion.identity);
                Vector2   sizeOfBlock = new Vector3((int)level.blocks[i].width, (int)level.blocks[i].height);
                obj.GetComponent <SpriteRenderer>().size = sizeOfBlock;
                obj.GetComponent <BoxCollider2D>().size  = sizeOfBlock;
                obj.GetComponent <LoggableBehavior>().setLogID(level.blocks[i].logId); // ground block
                levelEntities.Add(obj);
            }
        }
        Debug.Log("Loading player");
        // create the player
        if (level.player != null)
        {
            Vector2 loc = new Vector2((float)(level.player.x + (1 / 2f)), (float)(level.player.y - (1 / 2f)));
            gameController.playerRef = Instantiate(playerPreFab, loc, Quaternion.identity);
            gameController.playerRef.GetComponent <PlayerBehavior>().gameController = gameController;
            gameController.playerRef.GetComponent <LoggableBehavior>().setLogID(level.player.logId);
            levelEntities.Add(gameController.playerRef);
            // move the backdrop right behind the player initially.
            backgroundRef.position = gameController.playerRef.position + new Vector3(0, 0, -10);
        }
        Debug.Log("Loading goal");
        if (level.goalPortal != null)
        {
            Vector2   loc  = new Vector2((float)(level.goalPortal.x + (1 / 2f)), (float)(level.goalPortal.y - (1 / 2f)));
            Transform goal = Instantiate(goalPortalPreFab, loc, Quaternion.identity);
            goal.GetComponent <LoggableBehavior>().setLogID(level.goalPortal.logId);
            levelEntities.Add(goal);
        }
        Debug.Log("Loading helicopter robot");
        if (level.helicopterRobot != null)
        {
            Vector2   loc   = new Vector2((float)(level.helicopterRobot.x + (1 / 2f)), (float)(level.helicopterRobot.y - (1 / 2f)));
            Transform robot = Instantiate(helicopterRobotPreFab, loc, Quaternion.identity);
            HelicopterRobotBehavior robotBehavior = robot.GetComponent <HelicopterRobotBehavior>();
            robotBehavior.gameController = gameController;
            robotBehavior.targetLocation = robot.position;
            robotBehavior.GetComponent <LoggableBehavior>().setLogID(level.helicopterRobot.logId);

            gameController.helicopterRobotRef = robot;
            robotBehavior.GetComponent <ContainerEntityBehavior>().refreshChildList();
            robotBehavior.getChildLink().GetComponent <LoggableBehavior>().setLogID("helicopter");
            robotBehavior.getChildLink().type = LinkBehavior.Type.HELICOPTER;
            robotBehavior.getChildLink().setVariableName("temp");
            robotBehavior.getChildLink().setContainerEntity(robot.GetComponent <ContainerEntityBehavior>());
            levelEntities.Add(robot);
            levelLinks.Add(robotBehavior.GetComponent <ContainerEntityBehavior>().GetChildComponent <LinkBehavior>());
        }

        // corresponding list of IDs telling the link blocks what they should point to when the level is generated
        List <string>                 levelLinksConnIds     = new List <string>();
        List <LinkBehavior>           levelLinkComps        = new List <LinkBehavior>();
        List <ObjectiveBlockBehavior> levelObjectiveBlocks  = new List <ObjectiveBlockBehavior>();
        List <PlatformBehavior>       levelPlatformEntities = new List <PlatformBehavior>();

        gameController.platformsToAdd = new List <PlatformBehavior>();
        // create the start link
        Debug.Log("Loading start link");
        if (level.startLink != null)
        {
            Vector2      loc               = new Vector2((float)(level.startLink.x + (1 / 2f)), (float)(level.startLink.y - (1 / 2f)));
            Transform    startLinkTran     = Instantiate(linkBlockPreFab, loc, Quaternion.identity);
            LinkBehavior startLinkBehavior = startLinkTran.GetComponent <LinkBehavior>();
            startLinkTran.position          = startLinkTran.position + (new Vector3(0, 0, -5));
            startLinkBehavior.type          = LinkBehavior.Type.START;
            startLinkBehavior.defaultSprite = startLinkBlockSprite;
            startLinkBehavior.nullSprite    = nullStartLinkBlockSprite;
            startLinkBehavior.GetComponent <LoggableBehavior>().setLogID(level.startLink.logId);

            startLinkBehavior.GetComponent <SpriteRenderer>().sprite = startLinkBlockSprite;
            gameController.startingLink = startLinkBehavior; // set start link reference
            levelLinks.Add(startLinkBehavior);
            levelEntities.Add(startLinkTran);

            levelLinksConnIds.Add(level.startLink.objIDConnectingTo);
            levelLinkComps.Add(startLinkBehavior);
        }

        Debug.Log("Loading external link blocks");
        // create the indiv link blocks.
        for (int i = 0; i < level.linkBlocks.Length; i++)
        {
            Vector2   loc     = new Vector2((float)(level.linkBlocks[i].x + (1 / 2f)), (float)(level.linkBlocks[i].y - (1 / 2f)));
            Transform newLink = Instantiate(linkBlockPreFab, loc, Quaternion.identity);
            newLink.position = newLink.position + (new Vector3(0, 0, -5));
            LinkBehavior lb = newLink.GetComponent <LinkBehavior>();
            lb.GetComponent <LoggableBehavior>().setLogID(level.linkBlocks[i].logId);
            levelLinks.Add(lb);
            levelEntities.Add(newLink);

            levelLinksConnIds.Add(level.linkBlocks[i].objIDConnectingTo);
            levelLinkComps.Add(lb);
        }

        Debug.Log("Loading objective blocks");
        // create the objective blocks (fire)
        for (int i = 0; i < level.objectiveBlocks.Length; i++)
        {
            Vector2   loc       = new Vector2((float)(level.objectiveBlocks[i].x + (1 / 2f)), (float)(level.objectiveBlocks[i].y - (1 / 2f)));
            Transform newOBlock = Instantiate(objectiveBlockPreFab, loc, Quaternion.identity);
            newOBlock.GetComponent <LoggableBehavior>().setLogID(level.objectiveBlocks[i].logId);
            levelObjectiveBlocks.Add(newOBlock.GetComponent <ObjectiveBlockBehavior>());
            levelEntities.Add(newOBlock);
        }

        Debug.Log("Loading instruction blocks");
        // create the instruction blocks (question marks)
        for (int i = 0; i < level.instructionBlocks.Length; i++)
        {
            Vector2   loc = new Vector2((float)(level.instructionBlocks[i].x + (1 / 2f)), (float)(level.instructionBlocks[i].y - 1));
            Transform newInstructBlock = Instantiate(instructionViewBlockPreFab, loc, Quaternion.identity);
            newInstructBlock.GetComponent <InstructionViewBlockBehavior>().screenId = level.instructionBlocks[i].screenId;
            levelEntities.Add(newInstructBlock);
        }

        Debug.Log("Loading the platforms");
        // create the platforms.
        Dictionary <string, PlatformBehavior> listPlatformMap = new Dictionary <string, PlatformBehavior>();

        for (int i = 0; i < level.singleLinkedListPlatforms.Length; i++)
        {
            Vector2          loc           = new Vector2((float)(level.singleLinkedListPlatforms[i].x + (3 / 2f)), (float)(level.singleLinkedListPlatforms[i].y - (1 / 2f)));
            Transform        newLLPlatform = Instantiate(singleLinkedListPreFab, loc, Quaternion.identity);
            PlatformBehavior newPlat       = newLLPlatform.GetComponent <PlatformBehavior>();
            newPlat.GetComponent <ConnectableEntityBehavior>().incomingConnectionLinks = new List <LinkBehavior>();
            newPlat.gameController = gameController;

            newPlat.GetComponent <ContainerEntityBehavior>().refreshChildList();
            newPlat.setValue(level.singleLinkedListPlatforms[i].value);
            newPlat.GetComponent <LoggableBehavior>().setLogID(level.singleLinkedListPlatforms[i].logId);
            newPlat.GetComponent <ConnectableEntityBehavior>().incomingConnectionLinks = new List <LinkBehavior>();
            listPlatformMap.Add(level.singleLinkedListPlatforms[i].objId, newPlat);
            newPlat.getChildLink().state = LinkBehavior.State.NORMAL;
            newPlat.getChildLink().GetComponent <LoggableBehavior>().setLogID("child" + level.singleLinkedListPlatforms[i].logId);
            newPlat.getChildLink().setContainerEntity(newPlat.GetComponent <ContainerEntityBehavior>());
            levelLinks.Add(newPlat.GetComponent <ContainerEntityBehavior>().GetChildComponent <LinkBehavior>()); // add it to the list of blocks for references
            levelEntities.Add(newLLPlatform);

            levelLinksConnIds.Add(level.singleLinkedListPlatforms[i].childLinkBlockConnectId);
            levelLinkComps.Add(newPlat.getChildLink());
            levelPlatformEntities.Add(newPlat);

            newPlat.isInLevel = !level.singleLinkedListPlatforms[i].toAdd;
            if (level.singleLinkedListPlatforms[i].toAdd == true)
            {
                newLLPlatform.gameObject.SetActive(false);
                gameController.platformsToAdd.Add(newPlat);
            }
        }
        gameController.hudBehavior.setPlatformsToAddText(gameController.platformsToAdd.Count);
        Debug.Log("Completed loading " + listPlatformMap.Count + " platforms");

        Debug.Log("Establishing links ");
        // establishing links for the link blocks with the platforms
        for (int i = 0; i < levelLinksConnIds.Count; i++)
        {
            if (levelLinksConnIds[i] != null && levelLinksConnIds[i].Length > 0) // if this link has a connection.
            {
                string platformId = levelLinksConnIds[i];
                if (listPlatformMap[platformId].isInLevel == true)
                {
                    // establish the connection
                    levelLinkComps[i].ensureReferences();
                    levelLinkComps[i].setConnectionTo(listPlatformMap[platformId].GetComponent <ConnectableEntityBehavior>());
                }
            }
        }

        Debug.Log("Assigning variable names");
        string[] varNames = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "p", "q", "r", "z", "y" };
        int      varIndex = 0;

        // verify that no link blocks are being displayed
        foreach (LinkBehavior lb in levelLinks)
        {
            if (lb.type == LinkBehavior.Type.HELICOPTER)
            {
                lb.setVariableName("temp");
            }
            else if (lb.type == LinkBehavior.Type.START)
            {
                lb.setVariableName("list.head");
            }
            else
            {
                lb.setVariableName(varNames[varIndex++]);
            }
            lb.ensureReferences();
            lb.UpdateRendering();
        }

        Debug.Log("Updating everything");
        // update the win conditions for the objective blocks
        gameController.setLevelObjectiveBlocksList(levelObjectiveBlocks);
        gameController.setLevelPlatformEntitiesList(levelPlatformEntities);
        gameController.updateObjectiveHUDAndBlocks();
        gameController.updatePlatformEntities();
        gameController.codePanelBehavior.clearCodeText();
        gameController.hudBehavior.setLevelOnText(levelFileIndex + 1);
        gameController.hudBehavior.setPlatformsToAddText(gameController.platformsToAdd.Count);
        Debug.Log("Done loading world");
    }
    void Update()
    {
        debugFrameCount++;

        // don't process the game if the world is still being instantiated.
        if (worldGenerator.isBusy())
        {
            return;
        }

        if (playerRef != null)
        {
            // always set the camera on top of the player.
            cameraRef.transform.position = new Vector3(playerRef.position.x, playerRef.position.y, transform.position.z - 50);
        }

        // if you are adding a platform...
        // cancels when you click on nothing or when you right click.

        Vector3 mousePointInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        mousePointInWorld.z = 0;
        // add platform system
        if (addingPlatforms && platformsToAdd.Count > 0)
        {
            PlatformBehavior platformToPreviewForAdd = platformsToAdd[0];  // show a preview of the platform.
            platformToPreviewForAdd.GetComponent <ContainerEntityBehavior>().refreshChildList();
            platformToPreviewForAdd.renderAsFadedPreview();
            platformToPreviewForAdd.setValueBlockText("" + platformToPreviewForAdd.getValue());
            platformToPreviewForAdd.transform.position = mousePointInWorld;
            platformToPreviewForAdd.gameObject.SetActive(true);
            platformToPreviewForAdd.GetComponent <BoxCollider2D>().isTrigger = true;

            if ((Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) && hoverLink == null) // deselecting with right click?
            {
                addingPlatforms = false;
                platformToPreviewForAdd.gameObject.SetActive(false);
                if (selectedLink != null)  // deselect on canceling placement.
                {
                    selectedLink.setPreviewConnection(null);
                    selectedLink.setState(LinkBehavior.State.NORMAL);
                    selectedLink = null;
                }
            }
            else if (selectedLink != null && Input.GetMouseButton(0)) // dragging from a link.
            {
                selectedLink.setPreviewConnection(platformToPreviewForAdd.GetComponent <ConnectableEntityBehavior>());
                selectedLink.UpdateRendering();
            }
            else if (selectedLink != null && Input.GetMouseButtonUp(0)) // release to finish adding platform,
            {
                platformsToAdd.Remove(platformToPreviewForAdd);
                platformToPreviewForAdd.transform.position = mousePointInWorld;
                platformToPreviewForAdd.gameObject.SetActive(true);
                platformToPreviewForAdd.GetComponent <BoxCollider2D>().isTrigger = false;
                platformToPreviewForAdd.isInLevel = true;                                                         // set as being added to the level.
                platformToPreviewForAdd.GetComponent <ContainerEntityBehavior>().refreshChildList();
                selectedLink.setConnectionTo(platformToPreviewForAdd.GetComponent <ConnectableEntityBehavior>()); // connect the selected link to the new platform
                platformToPreviewForAdd.updateRenderAndState();                                                   // force rendering update.
                addingPlatforms = false;
                codePanelBehavior.appendCodeText(selectedLink.getVariableName() + " = new Node();");              // append code to the generated code window.

                string actMsg = "Platform is added from link " + selectedLink.GetComponent <LoggableBehavior>().getLogID() + " at (" + mousePointInWorld.x + ", " + mousePointInWorld.y + ")";
                loggingManager.sendLogToServer(actMsg);

                selectedLink.setPreviewConnection(null);
                selectedLink.setState(LinkBehavior.State.NORMAL);
                selectedLink = null;                                     // deselect.

                hudBehavior.setPlatformsToAddText(platformsToAdd.Count); // update UI
                updateObjectiveHUDAndBlocks();
                updatePlatformEntities();
            }
        } // end addingPlatforms block


        if (!Input.GetMouseButtonDown(0) && !Input.GetMouseButtonDown(0)) // the state of clicking has not changed this frame.
        {
            hoverLink = null;                                             // to make sure it is properly updated this next frame.
        }
        // if it is a hover link and the mouse is released, then check to establish a connection.
        mousePointInWorld.z = 0;
        for (int i = 0; i < worldGenerator.levelLinks.Count; i++)
        {
            LinkBehavior lb = worldGenerator.levelLinks[i];
            if (lb.selectable)
            {
                if (lb.isPointInside(mousePointInWorld))
                {
                    if (lb.state == LinkBehavior.State.NORMAL)
                    {
                        hoverLink = lb;
                        lb.setState(LinkBehavior.State.HOVER);
                        if (selectedLink != null && hoverLink.connectableEntity != null)
                        {
                            selectedLink.setPreviewConnection(hoverLink.connectableEntity); // preview the connection if there is a select link.
                            selectedLink.UpdateRendering();
                        }
                    }

                    if (Input.GetMouseButtonDown(0)) // if the link is just being clicked.
                    {
                        if (lb.state == LinkBehavior.State.SELECTED)
                        {
                            // if the link being clicked is selected
                            if (getMsSinceLastClick() < doubleClickDelay)
                            {
                                lb.setConnectionTo(null); // remove connection on double click
                                lb.setPreviewConnection(null);
                                lb.UpdateRendering();
                                codePanelBehavior.appendCodeText(lb.getVariableName() + " = null;");
                                updatePlatformEntities(); // changing links - update platforms
                                updateObjectiveHUDAndBlocks();
                            }
                        }
                        else // clicking on a link that is NOT selected
                        {
                            selectedLink = lb;
                            lb.setState(LinkBehavior.State.SELECTED);
                            if (hoverLink == selectedLink)
                            {
                                hoverLink.setPreviewConnection(null);
                                hoverLink.UpdateRendering();
                                hoverLink = null; // hover link can't be the same as selected link.
                            }
                        }
                    }
                    else if (Input.GetMouseButtonUp(0))                                                         // if the mouse is being released over this link
                    {
                        if (lb.state == LinkBehavior.State.HOVER && selectedLink != null && selectedLink != lb) // if there IS a selected link. establish link.
                        {
                            selectedLink.setConnectionEqualTo(ref lb);
                            codePanelBehavior.appendCodeText(selectedLink.getVariableName() + " = " + lb.getVariableName() + ";");
                            selectedLink.setPreviewConnection(null);
                            selectedLink.setState(LinkBehavior.State.NORMAL);
                            lb.UpdateRendering();
                            updatePlatformEntities(); // changing links - update platforms
                            updateObjectiveHUDAndBlocks();
                        }
                    }
                }
                else
                { // mouse is NOT over link block
                    if (lb.state == LinkBehavior.State.HOVER)
                    {
                        lb.setState(LinkBehavior.State.NORMAL); // no longer a hover block.
                    }
                    else if (lb.state == LinkBehavior.State.SELECTED && !Input.GetMouseButton(0))
                    {
                        lb.setState(LinkBehavior.State.NORMAL); // no longer the selected block
                        lb.setPreviewConnection(null);          // no preview
                        lb.UpdateRendering();
                    }
                }
            }
            else
            {
                if (lb.state != LinkBehavior.State.NORMAL)
                {
                    lb.setState(LinkBehavior.State.NORMAL);
                }
            }
        } // end iterating through links.

        // validate the selected link
        if (selectedLink != null && selectedLink.state != LinkBehavior.State.SELECTED)
        {
            selectedLink = null;
        }
        // validate the hover link
        if (hoverLink != null && hoverLink.state != LinkBehavior.State.HOVER)
        {
            hoverLink = null;
        }


        // record the last time that the mouse clicked for double clicking
        if (Input.GetMouseButton(0))
        {
            lastTimeClickedMillis = System.DateTime.Now;
        }
    }