Efecto Onda o Salto al Hiperespacio – XNA


No sé si sea el título adecuado, pero haciendo algunas modificaciones al código, se pueden sacar diferentes efectos, como un efecto del salto al hiperespacio, al estilo las películas de naves espaciales, donde la nave viaja casi a la velocidad de la luz y las estrellas y planetas se ven muy rápido y como si se estuvieran alargando. Algo como la siguiente imagen y el siguiente vídeo:

blast effect

Salto al hiperespacio

En XNA, podemos usar muchos efectos visuales o efectos post-processing, usando pixel shader o el método que voy a mostrarles.

El efecto usa la clase RenderTarget2D, para copiar una textura y luego manipularla, también hacemos uso de la clase BlendState para crear diferentes resultados.

El primer efecto, es muy parecido al video del espacio, sencillamente lo que se hace es tomar una textura de fondo, y luego dibujarla varias veces, pero modificando el tamaño (aunque muy poco) y el color alfa (para dar transparencias).

Para empezar a codificar, creamos una clase llamada Blast, que será la que tendrá las propiedades de la explosión o de la onda, tendrá un centro o posición inicial de la explosión, una magnitud, y un método Update que aumentará con el tiempo una variable:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace EfectoOnda
{
 public class Blast
 {
  private float valor;
  private float magnitud;

  public Vector2 Centro;

  public void Update(GameTime gameTime)
  {
   if (valor >= 0f)
   {
    valor -= (float)gameTime.ElapsedGameTime.TotalSeconds * 0.9f;
   }
   else if (valor < 0f)
   {
    valor = 0f;
   }
 }
 public float Valor
 {
  get { return valor; }
  set { valor = value; }
 }
 public float Magnitud
 {
  get { return magnitud; }
  set { magnitud = value; }
 }
 }
}

También se crea una clase estática que inicializará las explosiones cuando queramos:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace EfectoOnda
{
 public static class BlastManager
 {
  public static Blast blast;

  static BlastManager()
  {
   blast = new Blast();
  }

  public static void Update(GameTime gameTime)
  {
   blast.Update(gameTime);
  }

  public static void SetBlast(float mag, Vector2 centro)
  {
   blast.Valor = mag;
   blast.Magnitud = mag;
   blast.Centro = centro;
  }
 }
}

Para ver en uso las clases, añado una imagen al proyecto inicial, en este caso escogí una imagen con fondo del espacio, también creo un objeto RenderTarget2D que será del tamaño de la ventana.

Creamos las variables necesarias:

Texture2D fondo;
RenderTarget2D Target;

Cargamos la imagen de fondo e inicializamos el RenderTarget:

fondo = Content.Load<Texture2D>("stars");
Target = new RenderTarget2D(GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);

Actualizamos las explosiones y cada vez que hagamos clic, creamos una explosión, en la posición donde esta el Mouse: (Método Update)

BlastManager.Update(gameTime);
MouseState ms = Mouse.GetState();
if (ms.LeftButton == ButtonState.Pressed)
{
 BlastManager.SetBlast(5f, new Vector2(ms.X, ms.Y));
}

Dibujamos el fondo original y si se esta ejecutando una explosión, dibujamos las copias (Este es el código principal del efecto)

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);

GraphicsDevice.SetRenderTarget(Target);
GraphicsDevice.Clear(Color.Black);

spriteBatch.Begin();
spriteBatch.Draw(fondo, Vector2.Zero, Color.White);
spriteBatch.End();

GraphicsDevice.SetRenderTarget(null);

spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(Target, new Vector2(), Color.White);

spriteBatch.End();

if (BlastManager.blast.Valor > 0f)
{
 spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
 for (int i = 0; i < 6; i++)
 {
  spriteBatch.Draw(Target, BlastManager.blast.Centro, new Rectangle(0, 0, 800, 600),
  new Color(new Vector4(1f, 1f, 1f, .5f * (BlastManager.blast.Valor / BlastManager.blast.Magnitud))),
  0f, BlastManager.blast.Centro, (1.0f + (BlastManager.blast.Magnitud - BlastManager.blast.Valor) * .1f + ((float)(i + 1) / 40f)), SpriteEffects.None, 1f);
 }
 spriteBatch.End();
}
base.Draw(gameTime);
}

hyperspace effect

Al modificar la magnitud de la explosión, el resultado final es que entre más mayor es la magnitud, más se va a demorar el efecto en acción.

Si se modifica el BlendState de AlphaBlend a NonPremultiplied vemos un efecto de una onda expansiva:

blast effect

El efecto en acción lo podemos ver también en la siguiente imagen, de un juego que estoy haciendo, donde al haber una explosión, aparece una onda expansiva:

tanque blast

Un pensamiento en “Efecto Onda o Salto al Hiperespacio – XNA

Deseas comentar o sugerir algo?

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s