예제 #1
0
        /// <summary>
        /// Computa el area donde se proyecta el rayo.
        /// </summary>
        /// <returns></returns>
        private Rectangle ComputeRayArea()
        {
            Vector2 a = this.Source;
            Vector2 b = MathTools.Move(this.Source, this.Radius, Math.Abs(this.Direction)); this.Hit = b;

            if (a.X > b.X)
            {
                Helper.Swap <float>(ref a.X, ref b.X);
            }
            if (a.Y > b.Y)
            {
                Helper.Swap <float>(ref a.Y, ref b.Y);
            }

            /* En caso de que la direccion sea perpendicular, para evitar que el area de interseccion sea plana (sin volumen)
             * segun la direccion incrementamos o decrementamos en 1 la altura o anchura del area: */
            switch ((int)this.Direction)
            {
            case 0:
            case 180: a.Y--; b.Y++; break;

            case 90:
            case 270: a.X--; b.X++; break;
            }

            return(new Rectangle((int)a.X, (int)a.Y, (int)(b.X - a.X), (int)(b.Y - a.Y)));
        }
예제 #2
0
        /// <summary>
        /// Dibuja la representacion grafica del cuerpo.
        /// </summary>
        public void Draw()
        {
            // Si se definio el metodo de pre dibujado lo ejecutamos:
            if (this.PreDraw != null)
            {
                PreDraw(this);
            }

            // Dibujamos el area del cuerpo:
            Helper.DrawBox(Rectangle, Color);

            // Escribimos el angulo:
            if (Debug)
            {
                string directions = (Left ? "Left\n" : "") + (Up ? "Up\n" : "") + (Right ? "Right\n" : "") + (Down ? "Down" : "");
                if (!Fixed)
                {
                    Helper.DrawText(Direction.ToString() + "º\n" + directions, new Vector2(Rectangle.X + 1, Rectangle.Y + 1), Color.White);
                }
            }

            // Si no es un cuerpo fijo y este se ha movido en la ultima iteracion dibujamos una linea que represente la direccion:
            if (!Fixed && Direction > -1)
            {
                // Obtenemos el extremo de la linea desplazando las coordenadas xy 32 pixeles en la direccion recorrida:
                Vector2 endPoint = MathTools.Move(Center, 32, Direction);

                // Dibujamos la linea:
                Helper.DrawLine(Center, endPoint, Color.Blue);
            }

            // Si se definio el metodo de post dibujado lo ejecutamos:
            if (this.PostDraw != null)
            {
                PostDraw(this);
            }
        }
예제 #3
0
        /// <summary>
        /// Actualiza el estado de la escena.
        /// </summary>
        public void Update()
        {
            // Actualizamos los estados de todos los cuerpos de la escena que no sean fijos y esten activos:
            foreach (Body body in bodies)
            {
                // Si se definio, ejecutamos el metodo de pre actualizacion del cuerpo:
                if (body.PreUpdate != null) body.PreUpdate(body);
                body.Update();
            }

            // Recorremos la lista de cuerpos de la escena y calculamos sus colisiones y su respuesta en caso de haber colision:
            foreach (Body currentBody in bodies)
            {
                // Buscamos colisiones con el resto de cuerpos de la escena:
                collisions.Clear();
                foreach (Body body in bodies)
                {
                    // Descartamos al cuerpo actual en la busqueda:
                    if (currentBody != body && currentBody.Enabled)
                        if (currentBody.Rectangle.Intersects(body.Rectangle))
                            collisions.Add(body);
                }

                // Evaluamos la respuesta a la colision:
                if (collisions.Count > 0)
                {
                    // Si hay colisiones con el cuerpo actual lanzamos el evento y enviamos la lista de cuerpos que colisionan:
                    if (currentBody.OnCollision != null)
                        currentBody.OnCollision(collisions.ToArray());

                    // Descartamos primero cualquier cuerpo que no sea solido para no calcular respuesta con el:
                    List<Body> collisionsToResponse = new List<Body>();
                    foreach (Body body in collisions)
                        if (body.Solid && body.Fixed) collisionsToResponse.Add(body);

                    if (collisionsToResponse.Count > 0)
                    {
                        // Invertimos el angulo de direccion que tenia el cuerpo:
                        float dir = currentBody.Direction + (currentBody.Direction > 180 ? -180 : 180);

                        // Si hay colisiones obtenemos la respuesta a la colision para recolocar el cuerpo:
                        int count; do
                        {
                            // Retrocediendo un pixel en la direccion opuesta que recorria el cuerpo:
                            currentBody.Location = MathTools.Move(currentBody.Location, 1, dir);

                            // Comprobamos las colisiones restantes:
                            count = collisionsToResponse.Count;
                            foreach (Body b in collisionsToResponse)
                                if (!currentBody.Rectangle.Intersects(b.Rectangle)) count--;
                        }
                        while (count > 0);

                        // Igualamos la ultima posicion con la actual de la correccion para anular la direccion tomada en el proximo Update() del cuerpo:
                        currentBody.lastPoint = currentBody.Location; 
                    }
                }
            }

            // Si se definio, ejecutamos el metodo de post actualizacion del cuerpo:
            foreach (Body body in bodies)
                if (body.PostUpdate != null) body.PostUpdate(body);
        }