예제 #1
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            kCurrentState = Keyboard.GetState();
            mCurrentState = Mouse.GetState();

            //controlla l'input solo se la finestra ha il focus per evitare input non desiderati mentre si utilizza un altra applicazione
            //(ad esempio il client di controllo)
            if (GetForegroundWindow() == this.Window.Handle)
            {

                #region Telecamera
                //matrice di traslazione per passare dal sistema di riferimento della finestra a quello del mondo, traslato a causa della telecamera
                matrice = Matrix.CreateTranslation(new Vector3(camera.Pos, 0) - new Vector3(GraphicsDevice.Viewport.Width * 0.5f, GraphicsDevice.Viewport.Height * 0.5f, 0));
                //posizione del mouse nelle coordinate traslate tenendo conto della telecamera
                mousePos = Vector2.Transform(new Vector2(mCurrentState.X, mCurrentState.Y), matrice);

                //varia lo zoom
                if (kCurrentState.IsKeyDown(Keys.H))
                    Const.Zoom = Const.Zoom + 1;
                if (kCurrentState.IsKeyDown(Keys.L))
                {
                    if ((Const.Zoom - 1) > 0)
                        Const.Zoom = Const.Zoom - 1;
                }

                //movimento telecamera
                if (kCurrentState.IsKeyDown(Keys.W))
                    camera.Muovi(new Vector2(0, -3));
                if (kCurrentState.IsKeyDown(Keys.A))
                    camera.Muovi(new Vector2(-3, 0));
                if (kCurrentState.IsKeyDown(Keys.S))
                    camera.Muovi(new Vector2(0, 3));
                if (kCurrentState.IsKeyDown(Keys.D))
                    camera.Muovi(new Vector2(3, 0));
                #endregion

                //blocca/muove le parti
                if (kCurrentState.IsKeyDown(Keys.P) && kPreviousState.IsKeyUp(Keys.P))
                {
                    moving = !moving;
                    if (moving)
                        foreach (FParte part in partList)
                            part.BodyType = BodyType.Dynamic;
                    else
                        foreach (FParte part in partList)
                            part.BodyType = BodyType.Static;
                }

                #region Selezione parte
                //controlla se si tenta di selezionare una parte
                if (!drawingPart && (mCurrentState.LeftButton == ButtonState.Pressed) && (mPreviousState.LeftButton == ButtonState.Released))
                    foreach (FParte parte in partList)
                    {
                        /*
                        Vector2 partRelativeMousePos = Coord.InvTranslateAndRotate(mousePos, Coord.ToGraphics(parte.Position, Const.Zoom), parte.Rotation);
                        if ((Math.Abs(partRelativeMousePos.X) <= Coord.ToGraphics(parte.BodySize).X) && (Math.Abs(partRelativeMousePos.Y) <= Coord.ToGraphics(parte.BodySize).Y))
                            selectedPart = parte;
                         * */
                        if (parte.TestPoint(Utils.ToPhysics(mousePos)))
                            selectedPart = parte;
                    }
                if (selectedPart != null) //se è stata selezionata una parte tenta di calcolare partRelativeMouseProjection
                {
                    //coordinate del mouse rispetto al sistema di riferimento della parte
                    partRelativeMouseProjection = Utils.InvTranslateAndRotate(mousePos, Utils.ToGraphics(selectedPart.Position, Const.Zoom), selectedPart.Rotation);
                    //passa in coordinate fisiche (per evitare di effettuare molte più conversioni in coordinate grafiche
                    partRelativeMouseProjection = Utils.ToPhysics(partRelativeMouseProjection, Const.Zoom);
                    //verifica se il mouse è in corrispondenza di uno dei lati della parte e, in caso affermativo, aggiorna il vettore
                    //con la proiezione della posizione del mouse sul bordo della creatura (altrimenti non la modifica)
                    if ((partRelativeMouseProjection.X < 0) && (Math.Abs(partRelativeMouseProjection.Y) <= (selectedPart.BodySize.Y / 2)))
                    {
                        partRelativeMouseProjection.X = -selectedPart.BodySize.X / 2;
                        onSide = true;
                        projectionSide = Side.Left;
                    }
                    else if ((partRelativeMouseProjection.X >= 0) && (Math.Abs(partRelativeMouseProjection.Y) <= (selectedPart.BodySize.Y / 2)))
                    {
                        partRelativeMouseProjection.X = selectedPart.BodySize.X / 2;
                        onSide = true;
                        projectionSide = Side.Right;
                    }
                    else if ((partRelativeMouseProjection.Y < 0) && (Math.Abs(partRelativeMouseProjection.X) <= (selectedPart.BodySize.X / 2)))
                    {
                        partRelativeMouseProjection.Y = -selectedPart.BodySize.Y / 2;
                        onSide = true;
                        projectionSide = Side.Top;
                    }
                    else if ((partRelativeMouseProjection.Y >= 0) && (Math.Abs(partRelativeMouseProjection.X) <= (selectedPart.BodySize.X / 2)))
                    {
                        partRelativeMouseProjection.Y = selectedPart.BodySize.Y / 2;
                        onSide = true;
                        projectionSide = Side.Bottom;
                    }
                    else
                        onSide = false;
                    //torna in coordinate grafiche
                    partRelativeMouseProjection = Utils.ToGraphics(partRelativeMouseProjection, Const.Zoom);
                }
                //verifica se il mouse si trova o meno all'interno di una parte e aggiorna noCollision
                noCollision = true;
                foreach (FParte parte in partList)
                {
                    Vector2 partRelativeMousePos = Utils.InvTranslateAndRotate(mousePos, Utils.ToGraphics(parte.Position, Const.Zoom), parte.Rotation);
                    if ((Math.Abs(partRelativeMousePos.X) <= (Utils.ToGraphics(parte.BodySize, Const.Zoom).X / 2)) && (Math.Abs(partRelativeMousePos.Y) <= (Utils.ToGraphics(parte.BodySize, Const.Zoom).Y) / 2))
                    {
                        noCollision = false;
                        break;
                    }
                }
                #endregion

                //switch (list.SelectedIndex)
                switch (comando)
                {
                    case 0: //creazione blocchi
                        #region Creazione blocchi
                        if (kCurrentState.IsKeyDown(Keys.Space) && kPreviousState.IsKeyUp(Keys.Space) && (mCurrentState.Y <= (Const.ScreenHeigh - Const.ControlsAreaHeigh)))
                        {
                            //creazione di un blocco inizialmente fermo nella posizione attuale del mouse, premendo spazio
                            Fixture newBlock = FixtureFactory.CreateRectangle(world, rectangleSize.X, rectangleSize.Y, 0.01f, Utils.ToPhysics(mousePos, Const.Zoom));
                            newBlock.Body.BodyType = BodyType.Dynamic;
                            newBlock.Restitution = 0.4f;
                            newBlock.Friction = 0.3f;
                            blocks.Add(newBlock);
                        }
                        if ((mCurrentState.LeftButton == ButtonState.Pressed) && (mPreviousState.LeftButton == ButtonState.Released) && (mCurrentState.Y <= (Const.ScreenHeigh - Const.ControlsAreaHeigh)))
                        {
                            //punto di rilascio del blocco con velocità iniziale non nulla e punto d'inizio del vettore immaginario che ne definisce il vettore velocità
                            start = Utils.ToPhysics(mousePos, Const.Zoom);
                            started = true;
                        }
                        else if ((mCurrentState.LeftButton == ButtonState.Released) && (mPreviousState.LeftButton == ButtonState.Pressed) && started)
                        {
                            //ho rilasciato il mouse sx -> crea il blocco
                            started = false;
                            end = Utils.ToPhysics(mousePos, Const.Zoom);
                            Fixture newBlock = FixtureFactory.CreateRectangle(world, rectangleSize.X, rectangleSize.Y, Const.PartDensity, new Vector2(start.X, start.Y));
                            newBlock.Body.BodyType = BodyType.Dynamic;
                            newBlock.Restitution = 0.4f;
                            newBlock.Friction = 0.3f;
                            newBlock.Body.IsBullet = true;
                            newBlock.Body.LinearVelocity = (end - start);
                            blocks.Add(newBlock);
                        }
                        if ((mCurrentState.RightButton == ButtonState.Released) && (mPreviousState.RightButton == ButtonState.Pressed) && (mCurrentState.Y < (Const.ScreenHeigh - Const.ControlsAreaHeigh)))
                            createExplosion(mousePos / Const.Zoom, blocks);
                        #endregion
                        break;
                    case 1: //manipolazione creatura
                        #region Creazione nuova parte
                        if ((mCurrentState.LeftButton == ButtonState.Pressed) && (mCurrentState.Y < (Const.ScreenHeigh - Const.ControlsAreaHeigh)))
                            if ((mPreviousState.LeftButton == ButtonState.Released) && noCollision)
                            {
                                //ho appena premuto il tasto sx del mouse e non sono in area controlli
                                //-> se il mouse non si trova all'interno di una parte inizia a disegnarne una nuova
                                partWhileDrawed = new Rectangle(Convert.ToInt32(mousePos.X), Convert.ToInt32(mousePos.Y), 1, 1);
                                drawingPart = true;
                            }
                            else
                            {
                                //sto tenendo premuto il tasto sx -> aggiorna partWhileDrawed
                                if (mousePos.X > partWhileDrawed.X)
                                    partWhileDrawed.Width = Convert.ToInt32(mousePos.X - partWhileDrawed.X);
                                else
                                {
                                    int temp = partWhileDrawed.X;
                                    partWhileDrawed.X = Convert.ToInt32(mousePos.X);
                                    partWhileDrawed.Width = Convert.ToInt32(mousePos.X) - temp;
                                }
                                if (mousePos.Y > partWhileDrawed.Y)
                                    partWhileDrawed.Height = Convert.ToInt32(mousePos.Y) - partWhileDrawed.Y;
                                else
                                {
                                    int temp = partWhileDrawed.Y;
                                    partWhileDrawed.Y = Convert.ToInt32(mousePos.Y);
                                    partWhileDrawed.Height = Convert.ToInt32(mousePos.Y) - temp;
                                }
                            }
                        else if (drawingPart) //else di if(mCurrentState.LeftButton == Pressed) ecc.
                        {
                            //ho appena rilasciato il tasto sx e stavo creando una nuova parte -> la crea
                            drawingPart = false;
                            Vector2 partSize = Utils.ToPhysics(new Vector2(partWhileDrawed.Width, partWhileDrawed.Height), Const.Zoom);
                            Vector2 partPosition = Utils.ToPhysics(new Vector2(partWhileDrawed.Center.X, partWhileDrawed.Center.Y), Const.Zoom);
                            if ((partSize.X >= 0.05f) && (partSize.Y >= 0.05f)) //crea la parte solo se è sufficientemente grande, per evitare di causare blocchi del programma
                            {
                                FParte newPart = new FParte(partSize, partPosition, Const.PartDensity, world, Color.Blue, Color.White);
                                if (moving)
                                    newPart.BodyType = BodyType.Dynamic;
                                else
                                    newPart.BodyType = BodyType.Static;
                                partList.Add(newPart);
                            }
                        }
                        #endregion

                        #region Creazione giunti
                        if (!pendingJoint) //se devo ancora iniziare a creare il giunto
                        {
                            if ((mCurrentState.RightButton == ButtonState.Pressed) && (mCurrentState.Y <= (Const.ScreenHeigh - Const.ControlsAreaHeigh)) && !moving)
                            {
                                if ((mPreviousState.RightButton == ButtonState.Released) && onSide && !creatingJoint)
                                {   //ho appena cliccato col tasto dx e sono correttamente aggangiato sul bordo della parte selezionata
                                    //-> inizio a creare il giunto
                                    creatingJoint = true;
                                    part1 = selectedPart;
                                    part1JointPos = new Vector2(partRelativeMouseProjection.X, partRelativeMouseProjection.Y);
                                    //(in coordinate grafiche e riferito alla posizione di part1)
                                }
                                else if (noCollision && creatingJoint)
                                {
                                    //il mouse è ancora premuto, quindi sto trascinando per determinare la dimensione del giunto
                                    Vector2 relMousePos = Utils.InvTranslateAndRotate(mousePos, Utils.ToGraphics(part1.Position, Const.Zoom), part1.Rotation);
                                    Vector2 relMousePosPhysics = Utils.ToPhysics(relMousePos, Const.Zoom);
                                    Vector2 part1JointPosPhysics = Utils.ToPhysics(part1JointPos, Const.Zoom);
                                    if ((projectionSide == Side.Right) && (relMousePosPhysics.X > (part1.BodySize.X / 2)))
                                    {   //bordo destro della parte
                                        jointRadius = relMousePos.X - part1JointPos.X;
                                        if (jointRadius < 0.05f) //per evitare dimensioni nulle o negative
                                            jointRadius = 0.05f;
                                        //centro del giunto in coordinate grafiche e assolute
                                        jointCenter = Utils.TranslateAndRotate(part1JointPos + new Vector2(jointRadius, 0), Utils.ToGraphics(part1.Position, Const.Zoom), part1.Rotation);
                                    }
                                    else if ((projectionSide == Side.Left) && (relMousePosPhysics.X < -(part1.BodySize.X / 2)))
                                    {   //bordo sinistro della parte
                                        jointRadius = part1JointPos.X - relMousePos.X;
                                        if (jointRadius < 0.05f)
                                            jointRadius = 0.05f;
                                        jointCenter = Utils.TranslateAndRotate(part1JointPos - new Vector2(jointRadius, 0), Utils.ToGraphics(part1.Position, Const.Zoom), part1.Rotation);
                                    }
                                    else if ((projectionSide == Side.Bottom) && (relMousePosPhysics.Y > (part1.BodySize.Y / 2)))
                                    {   //bordo inferiore della parte
                                        jointRadius = relMousePos.Y - part1JointPos.Y;
                                        if (jointRadius < 0.05f)
                                            jointRadius = 0.05f;
                                        jointCenter = Utils.TranslateAndRotate(part1JointPos + new Vector2(0, jointRadius), Utils.ToGraphics(part1.Position, Const.Zoom), part1.Rotation);
                                    }
                                    else if ((projectionSide == Side.Top) && (relMousePosPhysics.Y < -(part1.BodySize.Y / 2)))
                                    {   //bordo superiore della parte
                                        jointRadius = part1JointPos.Y - relMousePos.Y;
                                        if (jointRadius < 0.05f)
                                            jointRadius = 0.05f;
                                        jointCenter = Utils.TranslateAndRotate(part1JointPos - new Vector2(0, jointRadius), Utils.ToGraphics(part1.Position, Const.Zoom), part1.Rotation);
                                    }
                                }
                            }
                            else if (creatingJoint)
                            {
                                //ho appena rilasciato il tasto dx -> il giunto ha le dimensioni definitive
                                creatingJoint = false;
                                pendingJoint = true;
                            }
                        }   //-> pendingJoint è true -> il giunto è già stato creato, occorre scegliere la seconda parte
                        else if ((mCurrentState.RightButton == ButtonState.Pressed) && (mCurrentState.Y <= (Const.ScreenHeigh - Const.ControlsAreaHeigh)) && !moving && (mPreviousState.RightButton == ButtonState.Released) && onSide && (selectedPart != part1))
                        {
                            Vector2 part2JointPosPhysics = Utils.ToPhysics(partRelativeMouseProjection, Const.Zoom);
                            Vector2 part1JointPosPhysics = Utils.ToPhysics(part1JointPos, Const.Zoom);
                            selectedPart.Join(part1, part2JointPosPhysics, part1JointPosPhysics, Color.Aqua, jointRadius / Const.Zoom);
                            pendingJoint = false;
                        }
                        #endregion
                        break;
                }

                //applica le forze ai muscoli della parte selezionata, se possiede un Actuator (cioè se è una parte figlia)
                if ((selectedPart != null) && moving && (selectedPart.PartActuator != null))
                {
                    if (muscoli)
                        selectedPart.PartMotionSystem = MotionSystem.Actuator;
                    else
                        selectedPart.PartMotionSystem = MotionSystem.Motor;
                    if (kCurrentState.IsKeyDown(Keys.M))
                        selectedPart.ApplyMotion(1.0f);
                    else if (kCurrentState.IsKeyDown(Keys.N))
                        selectedPart.ApplyMotion(-1.0f);
                    else
                        selectedPart.ApplyMotion(0.0f);
                }

                foreach (FParte part in partList)
                    part.UpdateCollisionPoints();
            }

            world.Step((float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000);
            kPreviousState = kCurrentState;
            mPreviousState = mCurrentState;
            base.Update(gameTime);
        }
예제 #2
0
        /* VERSIONE OBSOLETA DA AGGIORNARE
        /// <summary>
        /// Posiziona la parte vicino a quella a cui deve unirsi e crea il giunto.
        /// </summary>
        /// <param name="otherPart">Altra parte a cui unire questa</param>
        /// <param name="thisPartPosition">Posizione del centro del giunto rispetto al baricentro di questa parte</param>
        /// <param name="otherPartPosition">Posizione del centro del giunto rispetto al baricentro dell'altra parte</param>
        /// <param name="jointColor">Colore del giunto</param>
        /// <returns>false se thisPartPosizion è all'interno della parte, true altrimenti</returns>
        public bool Join(FParte otherPart, Vector2 thisPartPosition, Vector2 otherPartPosition, Color jointColor)
        {
            Body.Position = Utils.TranslateAndRotate((otherPartPosition - thisPartPosition), otherPart.Body.Position, otherPart.Body.Rotation);
            Body.Rotation = otherPart.Body.Rotation;
            Joint = JointFactory.CreateRevoluteJoint(World, otherPart.Body, this.Body, thisPartPosition);
            JointOffset = new Vector2(thisPartPosition.X, thisPartPosition.Y);
            Joint.MotorEnabled = true;
            Joint.MaxMotorTorque = Const.MaxMotorTorquePerAreaUnit * this.BodySize.X * this.BodySize.Y;

            //determina la dimensione del giunto in base alla posizione rispetto al centro del corpo e alla dimensione del corpo stesso
            if ((thisPartPosition.X > BodySize.X / 2) && (Math.Abs(thisPartPosition.Y) <= BodySize.Y / 2))
            {
                JointRadius = thisPartPosition.X - BodySize.X / 2;
                ConnectionSide = Side.Right;
            }
            else if ((thisPartPosition.X < -BodySize.X / 2) && (Math.Abs(thisPartPosition.Y) <= BodySize.Y / 2))
            {
                JointRadius = -thisPartPosition.X - BodySize.X / 2;
                ConnectionSide = Side.Left;
            }
            else if ((thisPartPosition.Y > BodySize.Y / 2) && (Math.Abs(thisPartPosition.X) <= BodySize.X / 2))
            {
                JointRadius = thisPartPosition.Y - BodySize.Y / 2;
                ConnectionSide = Side.Bottom;
            }
            else if ((thisPartPosition.Y < -BodySize.Y / 2) && (Math.Abs(thisPartPosition.X) <= BodySize.X / 2))
            {
                JointRadius = -thisPartPosition.Y - BodySize.Y / 2;
                ConnectionSide = Side.Top;
            }
            else
                return false;

            JointFixture = FixtureFactory.CreateCircle(JointRadius, Density, Body, JointOffset);
            if(JointColor != null)
                JointColor = jointColor;
            Joint.CollideConnected = true;      //abilita la collisione dei due body connessi dal giunto
            PartActuator = new Actuator(this, otherPart, Const.MaxForcePerAreaUnit * BodyArea);
            return true;
        }
        */
        /// <summary>
        /// Posiziona la parte vicino a quella a cui deve unirsi e crea il giunto.
        /// </summary>
        /// <param name="otherPart">Altra parte a cui unire questa</param>
        /// <param name="thisPartSidePosition">Posizione del punto di contatto del giunto con il bordo di questa parte rispetto al centro di questa parte</param>
        /// <param name="otherPartSidePosition">Posizione del punto di contatto del giunto con il bordo dell'altra parte rispetto al centro dell'altra parte</param>
        /// <param name="jointColor">Colore del giunto</param>
        /// <param name="jointRadius">Raggio del giunto</param>
        /// <returns>false se thisPartSidePosition non è sul bordo della parte, true altrimenti</returns>
        public bool Join(FParte otherPart, Vector2 thisPartSidePosition, Vector2 otherPartSidePosition, Color jointColor, float jointRadius)
        {
            Vector2 jointOffset;
            if (thisPartSidePosition.X == -(BodySize.X / 2))
            {
                jointOffset = new Vector2(-jointRadius * 2, 0);
                ConnectionSide = Side.Left;
            }
            else if (thisPartSidePosition.X == (BodySize.X / 2))
            {
                jointOffset = new Vector2(jointRadius * 2, 0);
                ConnectionSide = Side.Right;
            }
            else if (thisPartSidePosition.Y == -(BodySize.Y / 2))
            {
                jointOffset = new Vector2(0, -jointRadius * 2);
                ConnectionSide = Side.Top;
            }
            else if (thisPartSidePosition.Y == (BodySize.Y / 2))
            {
                jointOffset = new Vector2(0, jointRadius * 2);
                ConnectionSide = Side.Bottom;
            }
            else
                return false;

            Body.Position = Utils.TranslateAndRotate(otherPartSidePosition - thisPartSidePosition - jointOffset, otherPart.Body.Position, otherPart.Body.Rotation);
            Body.Rotation = otherPart.Body.Rotation;
            if (Joint != null)
                World.RemoveJoint(Joint);
            Joint = JointFactory.CreateRevoluteJoint(World, otherPart.Body, this.Body, thisPartSidePosition + jointOffset/2);
            Joint.MotorEnabled = true;
            Joint.MaxMotorTorque = Const.MaxMotorTorquePerAreaUnit * this.BodySize.X * this.BodySize.Y;

            JointRadius = jointRadius;
            JointFixture = FixtureFactory.CreateCircle(JointRadius, Density, Body, thisPartSidePosition + jointOffset/2);
            if (JointColor != null)
                JointColor = jointColor;
            JointOffset = thisPartSidePosition + jointOffset / 2;
            Joint.CollideConnected = true;
            PartActuator = new Actuator(this, otherPart, Const.MaxForcePerAreaUnit * BodyArea);
            otherPart.AddChild(this);
            return true;
        }
예제 #3
0
        /// <summary>
        /// Costruttore che calcola automaticamente la posizione dei punti di contatto
        /// </summary>
        /// <param name="parteFiglio">Parte figlia (parte che possiede questo Actuator)</param>
        /// <param name="partePadre">Parte padre (parte a cui è attaccata la parte figlia attraverso questo Actuator)</param>
        /// <param name="maxForce">Forza massima da applicare a ciascun muscolo</param>
        public Actuator(FParte parteFiglio, FParte partePadre, float maxForce)
        {
            MaxForce = maxForce;
            PartePadre = partePadre;
            ParteFiglia = parteFiglio;
            Vector2 jointSideOffset = parteFiglio.JointSideOffset;
            LocalFigliaDir = new Vector2();
            LocalFigliaInv = new Vector2();
            LocalPadreDir = new Vector2();
            LocalPadreInv = new Vector2();
            /*
             * noto il lato attraverso cui le due parti sono collegate e dove quindi dovranno essere posizionati i muscoli, questi
             * saranno collocati in corrispondenza dell'estremo più interno tra quelli delle due parti. Occorre quindi calcolare le
             * posizioni degli angoli delle due parti rispetto ad un unico sistema di riferimento locale (in questo caso quello della
             * parte figlia), in modo da poter determinare subito quale dei due sia il più interno.
             */
            switch (ParteFiglia.ConnectionSide)
            {
                case Side.Right:
                    Vector2 figlioRelativePadreUpperCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-PartePadre.BodySize.X / 2, PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    Vector2 figlioRelativePadreLowerCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-PartePadre.BodySize.X / 2, -PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    LocalFigliaDir.X = ParteFiglia.BodySize.X / 2;
                    LocalFigliaInv.X = ParteFiglia.BodySize.X / 2;
                    Vector2 padreRelativeFiglioUpperCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(ParteFiglia.BodySize.X / 2, ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    Vector2 padreRelativeFiglioLowerCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(ParteFiglia.BodySize.X / 2, -ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    LocalPadreDir.X = -PartePadre.BodySize.X / 2;
                    LocalPadreInv.X = -PartePadre.BodySize.X / 2;
                    if (figlioRelativePadreUpperCorner.Y < (ParteFiglia.BodySize.Y / 2)) //l'angolo superiore più interno è quello della parte padre (ha la coordinata Y minore)
                    {
                        LocalFigliaDir.Y = figlioRelativePadreUpperCorner.Y;
                        LocalPadreDir.Y = PartePadre.BodySize.Y / 2;
                    }
                    else  //l'angolo superiore più interno è quello della parte figlia
                    {
                        LocalFigliaDir.Y = ParteFiglia.BodySize.Y / 2;
                        LocalPadreDir.Y = padreRelativeFiglioUpperCorner.Y;
                    }

                    if (figlioRelativePadreLowerCorner.Y > (-ParteFiglia.BodySize.Y / 2)) //stessa cosa per gli angoli inferiori (ora però il più interno ha la coordinata Y maggiore)
                    {
                        LocalFigliaInv.Y = figlioRelativePadreLowerCorner.Y;
                        LocalPadreInv.Y = -PartePadre.BodySize.Y / 2;
                    }
                    else
                    {
                        LocalFigliaInv.Y = -ParteFiglia.BodySize.Y / 2;
                        LocalPadreInv.Y = padreRelativeFiglioLowerCorner.Y;
                    }
                    break;
                case Side.Left:
                    //simmetrico al caso precedente, con PartePadre e ParteFiglia invertiti
                    figlioRelativePadreUpperCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(PartePadre.BodySize.X / 2, PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    figlioRelativePadreLowerCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(PartePadre.BodySize.X / 2, -PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    LocalFigliaDir.X = -ParteFiglia.BodySize.X / 2;
                    LocalFigliaInv.X = -ParteFiglia.BodySize.X / 2;
                    padreRelativeFiglioUpperCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-ParteFiglia.BodySize.X / 2, ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    padreRelativeFiglioLowerCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-ParteFiglia.BodySize.X / 2, -ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    LocalPadreDir.X = PartePadre.BodySize.X / 2;
                    LocalPadreInv.X = PartePadre.BodySize.X / 2;
                    if (figlioRelativePadreUpperCorner.Y < (ParteFiglia.BodySize.Y / 2))
                    {
                        LocalFigliaDir.Y = figlioRelativePadreUpperCorner.Y;
                        LocalPadreDir.Y = PartePadre.BodySize.Y / 2;
                    }
                    else
                    {
                        LocalFigliaDir.Y = ParteFiglia.BodySize.Y / 2;
                        LocalPadreDir.Y = padreRelativeFiglioUpperCorner.Y;
                    }

                    if (figlioRelativePadreLowerCorner.Y > (-ParteFiglia.BodySize.Y / 2))
                    {
                        LocalFigliaInv.Y = figlioRelativePadreLowerCorner.Y;
                        LocalPadreInv.Y = -PartePadre.BodySize.Y / 2;
                    }
                    else
                    {
                        LocalFigliaInv.Y = -ParteFiglia.BodySize.Y / 2;
                        LocalPadreInv.Y = padreRelativeFiglioLowerCorner.Y;
                    }
                    break;
                case Side.Top:
                    //simmetrico rispetto al case Side.Right, con X <-> Y, Right <-> Upper, Left <-> Lower
                    Vector2 figlioRelativePadreRightCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(PartePadre.BodySize.X / 2, PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    Vector2 figlioRelativePadreLeftCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-PartePadre.BodySize.X / 2, PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    LocalFigliaDir.Y = -ParteFiglia.BodySize.Y / 2;
                    LocalFigliaInv.Y = -ParteFiglia.BodySize.Y / 2;
                    Vector2 padreRelativeFiglioRightCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(ParteFiglia.BodySize.X / 2, -ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    Vector2 padreRelativeFiglioLeftCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-ParteFiglia.BodySize.X / 2, -ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    LocalPadreDir.Y = PartePadre.BodySize.Y / 2;
                    LocalPadreInv.Y = PartePadre.BodySize.Y / 2;
                    if (figlioRelativePadreRightCorner.X < (ParteFiglia.BodySize.X / 2))
                    {
                        LocalFigliaDir.X = figlioRelativePadreRightCorner.X;
                        LocalPadreDir.X = PartePadre.BodySize.X / 2;
                    }
                    else
                    {
                        LocalFigliaDir.X = ParteFiglia.BodySize.X / 2;
                        LocalPadreDir.X = padreRelativeFiglioRightCorner.X;
                    }

                    if (figlioRelativePadreLeftCorner.X > (-ParteFiglia.BodySize.X / 2))
                    {
                        LocalFigliaInv.X = figlioRelativePadreLeftCorner.X;
                        LocalPadreInv.X = -PartePadre.BodySize.X / 2;
                    }
                    else
                    {
                        LocalFigliaInv.X = -ParteFiglia.BodySize.X / 2;
                        LocalPadreInv.X = padreRelativeFiglioLeftCorner.X;
                    }
                    break;
                case Side.Bottom:
                    //simmetrico rispetto al caso Top, con PartePadre <-> ParteFiglia
                    figlioRelativePadreRightCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(PartePadre.BodySize.X / 2, -PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    figlioRelativePadreLeftCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-PartePadre.BodySize.X / 2, -PartePadre.BodySize.Y / 2), PartePadre.Position, PartePadre.Rotation), ParteFiglia.Position, ParteFiglia.Rotation);
                    LocalFigliaDir.Y = ParteFiglia.BodySize.Y / 2;
                    LocalFigliaInv.Y = ParteFiglia.BodySize.Y / 2;
                    padreRelativeFiglioRightCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(ParteFiglia.BodySize.X / 2, ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    padreRelativeFiglioLeftCorner = Utils.InvTranslateAndRotate(Utils.TranslateAndRotate(new Vector2(-ParteFiglia.BodySize.X / 2, ParteFiglia.BodySize.Y / 2), ParteFiglia.Position, ParteFiglia.Rotation), PartePadre.Position, PartePadre.Rotation);
                    LocalPadreDir.Y = -PartePadre.BodySize.Y / 2;
                    LocalPadreInv.Y = -PartePadre.BodySize.Y / 2;
                    if (figlioRelativePadreRightCorner.X < (ParteFiglia.BodySize.X / 2))
                    {
                        LocalFigliaDir.X = figlioRelativePadreRightCorner.X;
                        LocalPadreDir.X = PartePadre.BodySize.X / 2;
                    }
                    else
                    {
                        LocalFigliaDir.X = ParteFiglia.BodySize.X / 2;
                        LocalPadreDir.X = padreRelativeFiglioRightCorner.X;
                    }

                    if (figlioRelativePadreLeftCorner.X > (-ParteFiglia.BodySize.X / 2))
                    {
                        LocalFigliaInv.X = figlioRelativePadreLeftCorner.X;
                        LocalPadreInv.X = -PartePadre.BodySize.X / 2;
                    }
                    else
                    {
                        LocalFigliaInv.X = -ParteFiglia.BodySize.X / 2;
                        LocalPadreInv.X = padreRelativeFiglioLeftCorner.X;
                    }
                    break;
            }
        }
예제 #4
0
 public void AddChild(FParte part)
 {
     ChildParts.Add(part);
 }