Anterior | Índice | Siguiente
Capítulo 4: Animación Básica de Sprites
Lenguaje: C#
Para: VS2003 / VS2005 / VS2008
Por Dark-N: hernaldog@gmail.com
Visita mi Blog


http://darknromhacking.com


Objetivo: Animar un Sprite al moverse con el teclado.
NOTA: Se obtuvo como base el ejemplo de la página oficial de SDL.NET.

Lo primero es copiar esta imagen en la carpeta imagenes del proyecto. Esta imagen contiene la animación del personaje:


Creamos una nueva clase cap4.cs y adentro pon este simple código que inicializa la pantalla con un mensaje:
using System;
using System.Drawing;
using SdlDotNet;
using SdlDotNet.Sprites;

namespace tutorial
{    
    public class cap4
    {
        int resx = 400;
        int resy = 300;
    

        //Constructor
        public cap4()
        {            
            Video.SetVideoModeWindow(resx, resy);
            Video.WindowCaption = "Tutorial SDL: Capitulo 4";
            Video.WindowIcon(new System.Drawing.Icon("../../Imagenes/mario3.ico"));
            //Los Eventos iran en Run()
        }

        private void Events_Tick(object sender, TickEventArgs e)
        {

            Video.Screen.Fill(Color.Black);        
            Video.Screen.Update();
            juego();
        }

        // lógica de nuestro juego
        private void juego() 
        {
            
            SdlDotNet.Font fuente = new SdlDotNet.Font("../../fuentes/ARIAL.TTF",14);            
            TextSprite texto = new TextSprite("Ejemplo Animación de Sprite", fuente, Color.Yellow, new Point(0,0));            
            texto.Render(Video.Screen);
            
        }        

        public void Run()
        {    
            Events.KeyboardDown +=new KeyboardEventHandler(Events_KeyboardDown);
            Events.Run();
        }

        private void Events_KeyboardDown(object sender, KeyboardEventArgs e)
        {                
            if(e.Key == Key.Escape)
            {
                Events.QuitApplication();
            }        
        }

        [STAThread]
        public static void Main()
        {
            cap4 juego = new cap4();
            juego.Run();
        }
    }
    
}

Abajo de la declaración resx, resy, creamos la variable Hero de tipo AnimatedSprite:
private AnimatedSprite hero = new AnimatedSprite();

Dentro del método Run() se setea los FPS (Frames por Segundo) de la animación y se crea un manejador de eventos para KeyboardUp es decir, un Event Handler que registre cuando soltemos alguna tecla. Recuerda que el Event Handler de KeyboradDown ya existe y la usamos para programar cuando se presiona Escape. Entonces Run() nos queda así:
public void Run()
{	
    Events.Fps = 50;
    Events.Tick += new TickEventHandler(Events_Tick);
    Events.KeyboardDown += new KeyboardEventHandler(Events_KeyboardDown);
    Events.KeyboardUp += new KeyboardEventHandler(Events_KeyboardUp);
    Events.Quit += new QuitEventHandler(Events_Salir);
    Events.Run();
}

Dentro del constructor agregamos distintas cosas:
  • Los Frames de Animación gracias a la clase SurfaceCollection(imagen, tamaño_en_pix, fila_numero).
  • Agregamos las animaciones con miAnimatedSprite.Animations.Add(alias_animacion, Animación(miSurface),delay_frame).
  • Sacamos el color purpura de fondo de la imagen con miAnimatedSprite.TransparentColor.
  • Iniciamos el personaje no en movimiento con miAnimatedSprite.CurrentAnimation.
  • Posicionamos el personaje en el centro de la pantalla con miAnimatedSprite.Center.

    public cap4()
    {       
        Video.SetVideoModeWindow(resx, resy);
        Video.WindowCaption = "Tutorial SDL: Capitulo 4";
        Video.WindowIcon(new System.Drawing.Icon("../../Imagenes/mario3.ico"));
    
        // Se carga la imagen
        Surface image = new Surface("../Imagenes/Hero.png");
    
        // Se crean los Frames de Animación
        SurfaceCollection walkUp = new SurfaceCollection(image, new Size(24,32), 0); //24x32 cada frame, fila 0, será cuando el personaje suba
        SurfaceCollection walkRight = new SurfaceCollection(image, new Size(24,32), 1);
        SurfaceCollection walkDown = new SurfaceCollection(image, new Size(24,32), 2);
        SurfaceCollection walkLeft = new SurfaceCollection(image, new Size(24,32), 3); //ultima fila de la imagen
    
        // Agregamos las animaciones al objeto hero
        hero.Animations.Add("WalkUp", new Animation(walkUp, 35));
        hero.Animations.Add("WalkRight", new Animation(walkRight, 35));
        hero.Animations.Add("WalkDown", new Animation(walkDown, 35));
        hero.Animations.Add("WalkLeft", new Animation(walkLeft, 35));
    
        // Pintamos transparente el fondo del sprite
        hero.TransparentColor = Color.Magenta;
    
        // Seteamos la animacion inicial y que no se mueva
        hero.CurrentAnimation = "WalkDown";
        hero.Animate = false;
    
        // Lo colocamos en el centro de la pantalla
        hero.Center = new Point(Video.Screen.Width/2, Video.Screen.Height/2);
    }
    

    Dentro de Events_Tick se cambia un poco lo que se tenia en un principioy se agrega el Evento Events_Salir:

    private void Events_Tick(object sender, TickEventArgs e)
    {
        Video.Screen.Fill(Color.Black);        
        //se rendera aquí el personaje
        hero.Render(Video.Screen);    
        SdlDotNet.Font fuente = new SdlDotNet.Font("../../fuentes/ARIAL.TTF",14);
        TextSprite texto = new TextSprite("Ejemplo Animación de Sprite", fuente, Color.Yellow, new Point(0,0));
        texto.Render(Video.Screen);    
        Video.Screen.Update();
        juego();
    }
    
    private void Events_Salir(object sender, SdlDotNet.QuitEventArgs e)
    {
        Events.QuitApplication();
    }
    

    Ahora dentro del método juego() se mueve el objeto hero:

    private void juego() 
    {  
      // Si Hero esta animado, el camina, así que se mueve
      if(hero.Animate)
      {
        switch(hero.CurrentAnimation)
        {
            case "WalkLeft":
                // 2 es la velocidad cuando camina
                hero.X -= 2;
                break;
            case "WalkUp":
                hero.Y -= 2;
                break;
            case "WalkDown":
                hero.Y += 2;
                break;
            case "WalkRight":
                hero.X += 2;
                break;
        }
      }
    }
    

    Ahora vamos a los eventos del teclado que moverán el personaje, primero el evento manejador de presionar alguna tecla llamado Events_KeyboardDown(sender,arg):

    private void Events_KeyboardDown(object sender, KeyboardEventArgs e)
    {
        // Chequea que tecla es presionada y cambia la animación
        switch(e.Key)
        {        
            case Key.LeftArrow:   //se mueve a la izquierda
                hero.CurrentAnimation = "WalkLeft";
                hero.Animate = true;
                break;
            case Key.RightArrow:
                hero.CurrentAnimation = "WalkRight";
                hero.Animate = true;
                break;
            case Key.DownArrow:
                hero.CurrentAnimation = "WalkDown";
                hero.Animate = true;
                break;
            case Key.UpArrow:
                hero.CurrentAnimation = "WalkUp";
                hero.Animate = true;
                break;
            case Key.Escape:  //salimos del juego
                Events.QuitApplication();
                break;
        }
    }
    

    Y solo falta el código al evento manejador que se gatilla al soltar una tecla que lo llamamos Events_KeyboardUp:

    private void Events_KeyboardUp(object sender, KeyboardEventArgs e)
    {
        // Al soltar la tecla deja de moverse Hero
        if(e.Key == Key.LeftArrow && hero.CurrentAnimation == "WalkLeft")
            hero.Animate = false;
        else if(e.Key == Key.UpArrow && hero.CurrentAnimation == "WalkUp")
            hero.Animate = false;
        else if(e.Key == Key.DownArrow && hero.CurrentAnimation == "WalkDown")
            hero.Animate = false;
        else if(e.Key == Key.RightArrow && hero.CurrentAnimation == "WalkRight")
            hero.Animate = false;
    }
    

    Ahora solo has el Rebuild para ver si hay errores y generar el ejecutable y luego presiona F5 para ver como funciona:


    Por último ve a la carpeta bin/Debug donde tienes el proyecto, en mi caso C:SDL\tutorial\bin\Debug y cámbiale el nombre al archivo tutorial.exe por cap4_animacion_sprite.exe.


    Código fuente de este capítulo para VS2003 y SDL 4.0:

    //Tutorial de SDL.NET
    //Archivo: cap4.cs
    //Autor: Dark-N (naldo_go@hotmail.com)
    //Fecha: 28-11-2006
    //Capitulo4: Animación básica de Sprites
    
    using System;
    using System.Drawing;
    using SdlDotNet;
    using SdlDotNet.Sprites;
    
    namespace tutorial
    {    
        public class cap4
        {
            int resx = 400;
            int resy = 300;
            
            private AnimatedSprite hero = new AnimatedSprite();
        
            //Constructor
            public cap4()
            {            
                Video.SetVideoModeWindow(resx, resy);            
                Video.WindowCaption = "Tutorial SDL: Capitulo 4";
                Video.WindowIcon(new System.Drawing.Icon("../../Imagenes/mario3.ico"));
                
                // Se carga la imagen
                Surface image = new Surface("../../Imagenes/Hero.png");
        
                // Se crean los Frames de Animación
                SurfaceCollection walkUp = new SurfaceCollection(image, new Size(24,32), 0);
                SurfaceCollection walkRight = new SurfaceCollection(image, new Size(24,32), 1);
                SurfaceCollection walkDown = new SurfaceCollection(image, new Size(24,32), 2);
                SurfaceCollection walkLeft = new SurfaceCollection(image, new Size(24,32), 3);
    
                // Agregamos las animaciones al objeto hero
                hero.Animations.Add("WalkUp", new Animation(walkUp, 35));
                hero.Animations.Add("WalkRight", new Animation(walkRight, 35));
                hero.Animations.Add("WalkDown", new Animation(walkDown, 35));
                hero.Animations.Add("WalkLeft", new Animation(walkLeft, 35));
    
                // Pintamos transparente el fondo del sprite
                hero.TransparentColor = Color.Magenta;
    
                // Seteamos la animacion inicial y que no se mueva
                hero.CurrentAnimation = "WalkDown";
                hero.Animate = false;
    
                // Lo colocamos en el centro de la pantalla
                hero.Center = new Point(Video.Screen.Width / 2, Video.Screen.Height / 2);
            }
    
            private void Events_Tick(object sender, TickEventArgs e)
            {
                Video.Screen.Fill(Color.Black);        
                hero.Render(Video.Screen);
    
                SdlDotNet.Font fuente = new SdlDotNet.Font("../../fuentes/ARIAL.TTF",14);            
                TextSprite texto = new TextSprite("Ejemplo Animación de Sprite", fuente, Color.Yellow, new Point(0,0));
                texto.Render(Video.Screen);
    
                Video.Screen.Update();
                juego();
            }
    
            // lógica de nuestro juego
            private void juego() 
            {        
                // Si Hero esta animado, el camina, asi que se mueve
                if(hero.Animate)
                {
                    switch(hero.CurrentAnimation)
                    {
                        case "WalkLeft":
                            // 2 es la velocidad cuando camina
                            hero.X -= 2;
                            break;
                        case "WalkUp":
                            hero.Y -= 2;
                            break;
                        case "WalkDown":
                            hero.Y += 2;
                            break;
                        case "WalkRight":
                            hero.X += 2;
                            break;
                    }
                }
            }        
    
            public void Run()
            {    
                Events.Fps = 50;
                Events.Tick += new TickEventHandler(Events_Tick);
                Events.KeyboardDown += new KeyboardEventHandler(Events_KeyboardDown);
                Events.KeyboardUp += new KeyboardEventHandler(Events_KeyboardUp);
                Events.Quit += new QuitEventHandler(Events_Salir);
                Events.Run();
            }
    
            private void Events_Salir(object sender, SdlDotNet.QuitEventArgs e)
            {
                Events.QuitApplication();
            }
    
            private void Events_KeyboardDown(object sender, KeyboardEventArgs e)
            {
                // Chequea que tecla es presionada y cambia la animación
                switch(e.Key)
                {                
                    case Key.LeftArrow:
                        hero.CurrentAnimation = "WalkLeft";
                        hero.Animate = true;
                        break;
                    case Key.RightArrow:
                        hero.CurrentAnimation = "WalkRight";
                        hero.Animate = true;
                        break;
                    case Key.DownArrow:
                        hero.CurrentAnimation = "WalkDown";
                        hero.Animate = true;
                        break;
                    case Key.UpArrow:
                        hero.CurrentAnimation = "WalkUp";
                        hero.Animate = true;
                        break;
                    case Key.Escape:
                        Events.QuitApplication();
                        break;
                }                            
            }
    
            private void Events_KeyboardUp(object sender, KeyboardEventArgs e)
            {
                // Al soltar la tecla deja de moverse Hero
                if(e.Key == Key.LeftArrow && hero.CurrentAnimation == "WalkLeft")
                    hero.Animate = false;
                else if(e.Key == Key.UpArrow && hero.CurrentAnimation == "WalkUp")
                    hero.Animate = false;
                else if(e.Key == Key.DownArrow && hero.CurrentAnimation == "WalkDown")
                    hero.Animate = false;
                else if(e.Key == Key.RightArrow && hero.CurrentAnimation == "WalkRight")
                    hero.Animate = false;
            }
    
            [STAThread]
            public static void Main()
            {
                cap4 juego = new cap4();
                juego.Run();
            }
        }	
    }
    



    Código fuente de este capítulo para VS2008 y SDL 6.1. Tiene una pequeños cambios pero la base es la misma:

    //Tutorial de SDL.NET
    //Archivo: cap4.cs
    //Autor: Dark-N
    //Fecha: 13-06-2011
    //Capitulo4: Animación básica de Sprites. Ahora usando VS2008 con SDL.NET 6.1
    
    using System;
    using System.Drawing;
    using SdlDotNet;
    using SdlDotNet.Graphics; //para Sprites y surface Video
    using SdlDotNet.Core; //Eventos Tick y Quit
    using SdlDotNet.Input; //eventos teclado
    using SdlDotNet.Graphics.Sprites;  //textos y graficos
    
    namespace tutorial
    {	
    	public class cap4
    	{
    		int resx = 400;
    		int resy = 300;
    		
    		private AnimatedSprite hero = new AnimatedSprite();
    		private SdlDotNet.Graphics.Font fuente = new SdlDotNet.Graphics.Font("../../fuentes/ARIAL.TTF", 14);  
    	
    		//Constructor
    		public cap4()
    		{			
    			Video.SetVideoMode(resx, resy);			
    			Video.WindowCaption = "Tutorial SDL: Capitulo 4 - VS2008 - SDL 6.1";
    			
    			
    			// Se carga la imagen
    			Surface image = new Surface("../../Imagenes/Hero.png");
        
    			// Se crean los Frames de Animación
    			SurfaceCollection walkUp = new SurfaceCollection();
    			SurfaceCollection walkRight = new SurfaceCollection();
    			SurfaceCollection walkDown = new SurfaceCollection();
    			SurfaceCollection walkLeft = new SurfaceCollection();
    			walkUp.Add(image, new Size(24,32), 0);
    			walkRight.Add(image, new Size(24, 32), 1);
    			walkDown.Add(image, new Size(24, 32), 2);			
    			walkLeft.Add(image, new Size(24, 32), 3);
    			
    			AnimationCollection an1 = new AnimationCollection();
    			AnimationCollection an2 = new AnimationCollection();
    			AnimationCollection an3 = new AnimationCollection();
    			AnimationCollection an4 = new AnimationCollection();
    			
    			an1.Add(walkUp, 35);
    			an2.Add(walkRight, 35);
    			an3.Add(walkDown, 35);
    			an4.Add(walkLeft, 35);
    
    			// Agregamos las animaciones al objeto hero
    			hero.Animations.Add("WalkUp", an1);
    			hero.Animations.Add("WalkRight", an2);
    			hero.Animations.Add("WalkDown", an3);
    			hero.Animations.Add("WalkLeft", an4);
    
    			// Pintamos transparente el fondo del sprite
    			hero.TransparentColor = Color.Magenta;
    			hero.Transparent = true;
    
    			// Seteamos la animacion inicial y que no se mueva
    			hero.CurrentAnimation = "WalkDown";
    			hero.Animate = false;
    
    			// Lo colocamos en el centro de la pantalla
    			hero.Center = new Point(Video.Screen.Width / 2, Video.Screen.Height / 2);
    		}
    
    		private void Events_Tick(object sender, TickEventArgs e)
    		{
    			Video.Screen.Fill(Color.Black);
    			Video.Screen.Blit(hero);
    			TextSprite texto = new TextSprite("Ejemplo Animación de Sprite", fuente, Color.Yellow, new Point(0,0));
    			Video.Screen.Blit(texto);
    			Video.Screen.Update();
    			juego();
    		}
    
    		// lógica de nuestro juego
    		private void juego() 
    		{		
    			// Si Hero esta animado, el camina, asi que se mueve
    			if(hero.Animate)
    			{
    				switch(hero.CurrentAnimation)
    				{
    					case "WalkLeft":
    						// 2 es la velocidad cuando camina
    						hero.X -= 2;
    						break;
    					case "WalkUp":
    						hero.Y -= 2;
    						break;
    					case "WalkDown":
    						hero.Y += 2;
    						break;
    					case "WalkRight":
    						hero.X += 2;
    						break;
    				}
    			}
    		}		
    
    		public void Run()
    		{	
    			Events.Fps = 60;
    			Events.Tick += new EventHandler(this.Events_Tick);
    			Events.KeyboardDown += new EventHandler(Events_KeyboardDown);
    			Events.KeyboardUp += new EventHandler(Events_KeyboardUp);
    			Events.Quit += new EventHandler(this.Events_Salir);
    			Events.Run();
    		}
    
    		private void Events_Salir(object sender, QuitEventArgs e)
    		{
    			Events.QuitApplication();
    		}
    
    		private void Events_KeyboardDown(object sender, KeyboardEventArgs e)
    		{
    			// Chequea que tecla es presionada y cambia la animación
    			switch(e.Key)
    			{				
    				case Key.LeftArrow:
    					hero.CurrentAnimation = "WalkLeft";
    					hero.Animate = true;
    					break;
    				case Key.RightArrow:
    					hero.CurrentAnimation = "WalkRight";
    					hero.Animate = true;
    					break;
    				case Key.DownArrow:
    					hero.CurrentAnimation = "WalkDown";
    					hero.Animate = true;
    					break;
    				case Key.UpArrow:
    					hero.CurrentAnimation = "WalkUp";
    					hero.Animate = true;
    					break;
    				case Key.Escape:
    					Events.QuitApplication();
    					break;
    			}							
    		}
    
    		private void Events_KeyboardUp(object sender, KeyboardEventArgs e)
    		{
    			// Al soltar la tecla deja de moverse Hero
    			if(e.Key == Key.LeftArrow && hero.CurrentAnimation == "WalkLeft")
    				hero.Animate = false;
    			else if(e.Key == Key.UpArrow && hero.CurrentAnimation == "WalkUp")
    				hero.Animate = false;
    			else if(e.Key == Key.DownArrow && hero.CurrentAnimation == "WalkDown")
    				hero.Animate = false;
    			else if(e.Key == Key.RightArrow && hero.CurrentAnimation == "WalkRight")
    				hero.Animate = false;
    		}
    
    		[STAThread]
    		public static void Main()
    		{
    			cap4 juego = new cap4();
    			juego.Run();
    		}
    	}
    	
    }
    

    Fuentes:

  • Proyecto VS2003 usando SDL.NET 4.0 - Cap 1 al 4.
  • Proyecto VS2008 usando SDL.NET 6.1 - Solo cap 4.



    Anterior | Índice | Siguiente
    Volver a Página Principal

    blog comments powered by Disqus
    2003 - 2018    La Web de Dark-N