/** * Called after an ExpressionPiece is created for the first time (all * arguments are empty) to set up the piece. I.e. called when an * ExpressionPiece is created by a Spawner, Controller or something that isn't OnDrop(). */ public void Initialize(Expression expr) { gameController = GameObject.Find("GameController").GetComponent <GameController>(); this.expression = expr; this.arguments = new ExpressionPiece[expr.GetNumArgs()]; this.gameObject.transform.position = GetStartingPosition(); GameObject tabletop = GameObject.Find("Workspace"); this.gameObject.transform.SetParent(this.transform.parent.transform); if (arguments.Length > 0) { this.heightInUnits = 2; this.widthInUnits = expr.GetNumArgs() + 1; } int counter = 0; int currentX = 1; float calculatedWidth = PIXELS_PER_UNIT * this.widthInUnits; float calculatedHeight = PIXELS_PER_UNIT * this.heightInUnits; // build empty arguments for (int i = 0; i < arguments.Length; i++) { // Expression argExpression = expr.GetArg(i); if (DRAW_OPEN_ARGUMENT_TYPE) { GameObject argumentPiece = Resources.Load("Piece") as GameObject; argumentPiece.name = "Argument"; GameObject argumentPieceInstance = Instantiate(argumentPiece, this.transform.position, Quaternion.identity) as GameObject; ExpressionPiece argumentPieceScript = argumentPieceInstance.GetComponent <ExpressionPiece>(); argumentPieceScript.gameController = gameController; argumentPieceScript.expression = new Word(expr.GetInputType(counter), "_"); argumentPieceScript.arguments = new ExpressionPiece[0]; //NOTE: arg positions are set relative to the center of their container expressions, by the center of the arg float overallPieceHeight = calculatedHeight; float overallPieceWidth = calculatedWidth; float overallPieceTopLeftX = this.transform.position.x - calculatedWidth / 2.0f; float overallPieceTopLeftY = this.transform.position.y + calculatedHeight / 2.0f; float argTopLeftX = overallPieceTopLeftX + PIXELS_PER_UNIT * currentX; float argTopLeftY = overallPieceTopLeftY - 1 * PIXELS_PER_UNIT; float argCenterX = argTopLeftX + (PIXELS_PER_UNIT * .5f) - BUFFER_IN_PIXELS; //.5f b/c center of arg w/ width & height 1 float argCenterY = argTopLeftY - (PIXELS_PER_UNIT * .5f) + BUFFER_IN_PIXELS; argumentPieceInstance.transform.SetParent(this.gameObject.transform); argumentPieceInstance.transform.position = new Vector3(argCenterX, argCenterY); argumentPieceScript.id = "_"; argumentPieceScript.index = counter; argumentPieceScript.SetParentExpressionPiece(this); this.arguments[i] = argumentPieceScript; counter++; } currentX++; } }
/** * returns false if 2 expressions shouldn't combine with each other */ public bool CombineWith(ExpressionPiece inputExpression, int index) { Expression expr = null; //try to create new Expression try { expr = new Phrase(this.expression, inputExpression.expression, index); } catch (Exception e) { Debug.LogException(e); this.gameController.failure.Play(); return(false); } // generate new Piece GameObject exprPiece = Resources.Load("Piece") as GameObject; GameObject exprPieceInstance = Instantiate(exprPiece, GetSpawnPosition(), Quaternion.identity) as GameObject; ExpressionPiece exprPieceScript = exprPieceInstance.GetComponent <ExpressionPiece>(); exprPieceScript.expression = expr; exprPieceScript.arguments = new ExpressionPiece[expr.GetNumArgs()]; if (exprPieceScript.arguments.Length > 0) { exprPieceScript.heightInUnits = 2; } float originalPieceX = this.transform.position.x; float originalPieceY = this.transform.position.y; // exprPieceInstance.transform.position = new Vector3(originalPieceX, originalPieceY, 0); exprPieceScript.gameController = gameController; exprPieceScript.id = expr.ToString(); exprPieceScript.index = this.index; if (this.parentExpressionPiece != null) { exprPieceScript.SetParentExpressionPiece(this.parentExpressionPiece.DeepCopy()); // DeepCopy here bc 'this' will get destroyed } // int noArgInputWidth = 1; // int noArgInputHeight = 1; // for (int i = 0; i < inputExpression.arguments.Legth; i++) { // if (!inputExpression[i].id.Equals("_")) { // noArgInputWidth += inputExpression[i].widthInUnits; // noArgInputHeight = Max(noArgInputHeight, inputExpression.heightInUnits + 1); // } // } exprPieceScript.widthInUnits = 1; exprPieceScript.widthInUnits += inputExpression.widthInUnits; exprPieceScript.heightInUnits = Max(exprPieceScript.heightInUnits, inputExpression.heightInUnits + 1); //Add the arguments to the new piece int counter = -1; for (int i = 0; i < arguments.Length; i++) { if (this.arguments[i] == null) { counter++; exprPieceScript.widthInUnits++; } else { // this happens to every argument, whether blank or filled float originalArgLocalX = this.arguments[i].transform.localPosition.x; float originalArgLocalY = this.arguments[i].transform.localPosition.y; // place a copy of the old argument in the same position in the new expression. exprPieceScript.arguments[i] = this.arguments[i].DeepCopy(); exprPieceScript.arguments[i].transform.SetParent(exprPieceInstance.transform); exprPieceScript.arguments[i].gameObject.transform.localPosition = new Vector3(originalArgLocalX, originalArgLocalY, 0); // changing the width and height of the new expression exprPieceScript.widthInUnits += exprPieceScript.arguments[i].widthInUnits; exprPieceScript.heightInUnits = Max(exprPieceScript.heightInUnits, exprPieceScript.arguments[i].heightInUnits + 1); // if it's an empty argument slot, then move forward in the // argument index, and decrement the argument slot's index by 1 if // the argument has already been placed to preserve the new indexing. if (this.arguments[i].id.Equals("_")) { if (counter > index) { exprPieceScript.arguments[i].index--; } counter++; } } // place the input expression in the appropriate argument position. if (counter == index) { float originalArgLocalX = this.arguments[i].transform.localPosition.x; float originalArgLocalY = this.arguments[i].transform.localPosition.y; //need to destroy the empty arg that this piece is replacing Destroy(exprPieceScript.arguments[i].gameObject, 0.0f); exprPieceScript.arguments[i] = inputExpression.DeepCopy(); exprPieceScript.arguments[i].gameObject.transform.localPosition = new Vector3(originalArgLocalX, originalArgLocalY, 0); exprPieceScript.arguments[i].transform.SetParent(exprPieceInstance.transform); counter++; exprPieceScript.widthInUnits--; } } int xPositionInUnits = 1; // this is setting the parentexpressionpiece and parent of all of the new // expression's arguments as the new expression. This doesn't happen in // deepcopy because deepcopy makes a new copy of the expression to set. for (int i = 0; i < arguments.Length; i++) { float argLocalX = exprPieceScript.arguments[i].transform.localPosition.x; float argLocalY = exprPieceScript.arguments[i].transform.localPosition.y; float changeY = ((exprPieceScript.heightInUnits - 2) / 2f) * PIXELS_PER_UNIT; if (exprPieceScript.arguments[i].id.Equals("_")) { exprPieceScript.arguments[i].gameObject.transform.localPosition = new Vector3( ((-0.5f * exprPieceScript.widthInUnits) + xPositionInUnits + 0.5f - BUFFER_IN_UNITS) * PIXELS_PER_UNIT, argLocalY + changeY); } exprPieceScript.arguments[i].SetParentExpressionPiece(exprPieceScript); exprPieceInstance.transform.SetParent(this.transform.parent.transform); // Debug.Log(exprPieceScript.expression + "'s width is " + exprPieceScript.widthInUnits); // Debug.Log(exprPieceScript.expression + "[" + i + "]'s width is " + arguments[i].widthInUnits); xPositionInUnits += exprPieceScript.arguments[i].widthInUnits; } exprPieceInstance.transform.SetParent(this.transform.parent.transform); exprPieceScript.SetVisual(exprPieceScript.GenerateVisual()); int indexToOccupy = this.gameObject.transform.GetSiblingIndex(); // foreach (ExpressionPiece arg in this.arguments) { // Destroy(arg.gameObject, 0.0f); // } Destroy(this.gameObject, 0.0f); // the arguments to the input expression aren't being destroyed properly. They're just floating around Destroy(inputExpression.gameObject, 0.0f); exprPiece.transform.SetSiblingIndex(indexToOccupy); return(true); }