//Archivo: Cuarto.cs
//Autor: Dark-N
//fecha: 20-11-2009
using System;
using System.Collections.Generic; //para eventos y otras cosas
using System.Drawing; //colores
using System.Collections;
using System.Diagnostics;
using SdlDotNet.Graphics; //para sprites
using SdlDotNet.Core; //Eventos
using SdlDotNet.Graphics.Sprites; //textos y graficos
using SdlDotNet.Input; //para teclado
namespace TutorialSDLNet
{
class Cuarto
{
private Surface screen;
private int velocidad_mov = 2;
private int resolucionX= 416;
private int resolucionY= 320;
private Surface arbol;
private Surface suelo;
private Surface personajes;
private Sprite spr_arbol;
private SdlDotNet.Graphics.Font fuente = new SdlDotNet.Graphics.Font("arial.TTF", 13);
private ArrayList listaNpc = new ArrayList();
string msg_superior = "";
string hora_msg = "";
Rectangle rectSuelo = new Rectangle(32,32, 384, 284);
Rectangle rectArboles = new Rectangle(16,16, 384, 284);
int unidadPixel = 16;
SpriteCollection copos = new SpriteCollection();
NPC npc1;
NPC npc2;
NPC npc3;
private void Evento_Salir(object sender, QuitEventArgs e)
{
Events.QuitApplication();
}
private void Evento_Teclado(object sender, KeyboardEventArgs e)
{
if (e.Key == Key.Escape)
Events.QuitApplication();
if (e.Key == Key.Space)
Reiniciar();
}
public void Run()
{
Video.WindowCaption = "Cuarto con NPCs";
screen = Video.SetVideoMode(resolucionX, resolucionY);
SdlDotNet.Core.Events.Fps = 60;
arbol = new Surface("cap9_arbol.png").Convert(screen, true, false);
spr_arbol = new Sprite(arbol);
suelo = new Surface("cap9_pasto.PNG").Convert(screen, true, false); //16 x 16 pixels
personajes = new Surface("cap9_hojasprites.png").Convert(screen, true, false);
npc1 = new NPC(1, new Size(24,32),new Rectangle(0,0,72,132), 100, 100, new Point(50,50));
npc2 = new NPC(2, new Size(24,32),new Rectangle(72,0,72,132), 80, 90, new Point(200,150));
npc3 = new NPC(3, new Size(24,32),new Rectangle(144,0,216,126), 70, 60, new Point(280,250));
npc1.sprite = CargaNPC(npc1.tamano, npc1.rectangulo);
npc2.sprite = CargaNPC(npc2.tamano, npc2.rectangulo);
npc3.sprite = CargaNPC(npc3.tamano, npc3.rectangulo);
npc1.sprite.CurrentAnimation = "abajo";
npc1.sprite.Center = npc1.centroInicial;
npc2.sprite.CurrentAnimation = "arriba";
npc2.sprite.Center = npc2.centroInicial;
npc3.sprite.CurrentAnimation = "derecha";
npc3.sprite.Center = npc3.centroInicial;
listaNpc.Add(npc1);
listaNpc.Add(npc2);
listaNpc.Add(npc3);
CargaInicialNieve(250); //250 Copos se ven a la vez
Events.KeyboardDown += new EventHandler < KeyboardEventArgs >(Evento_Teclado);
SdlDotNet.Core.Events.Tick += new EventHandler < TickEventArgs >(this.Evento_Tick);
SdlDotNet.Core.Events.Quit += new EventHandler < QuitEventArgs >(this.Evento_Salir);
Events.Run();
}
AnimatedSprite CargaNPC(Size size, Rectangle rect)
{
AnimatedSprite ap = new AnimatedSprite();
AnimationCollection an1 = new AnimationCollection();
AnimationCollection an2 = new AnimationCollection();
AnimationCollection an3 = new AnimationCollection();
AnimationCollection an4 = new AnimationCollection();
Surface surf_temp = new Surface(72,132).Convert(screen, true, false);
surf_temp.Blit(personajes, new Point(0,0), rect);
SurfaceCollection walkUp = new SurfaceCollection();
walkUp.Add(surf_temp, size, 0);
SurfaceCollection walkRight = new SurfaceCollection();
walkRight.Add(surf_temp, size, 1);
SurfaceCollection walkDown = new SurfaceCollection();
walkDown.Add(surf_temp, size, 2);
SurfaceCollection walkLeft = new SurfaceCollection();
walkLeft.Add(surf_temp, size, 3);
an1.Add(walkUp);
ap.Animations.Add("arriba",an1);
an2.Add(walkRight);
ap.Animations.Add("derecha",an2);
an3.Add(walkDown);
ap.Animations.Add("abajo",an3);
an4.Add(walkLeft);
ap.Animations.Add("izquierda",an4);
ap.TransparentColor = Color.Black;
ap.Transparent = true;
return ap;
}
//ciclo de juego (game-loop)
private void Evento_Tick(object sender, TickEventArgs args)
{
screen.Fill(Color.Black);
pintaMensajes();
pintaSuelo();
pintaArboles();
pintaNPCs();
screen.Blit(copos);
screen.Update();
}
void pintaMensajes()
{
TextSprite textoSup = new TextSprite(msg_superior, fuente, Color.Yellow);
screen.Blit(textoSup,new Point(10,3));
TextSprite textoInf = new TextSprite("Presiona ESPACIO para reiniciar", fuente, Color.Yellow);
screen.Blit(textoInf,new Point(10,screen.Height-unidadPixel));
TextSprite textoDemo = new TextSprite("Demo por Dark-N", new SdlDotNet.Graphics.Font("arial.TTF", 11), Color.White);
screen.Blit(textoDemo,new Point(310,screen.Height-15));
// borramos los mensajes pasados 1 segundo
if (msg_superior != "")
{
string hora_temp = DateTime.Now.ToString("HH-mm-ss");
if (hora_temp == hora_msg)
msg_superior = "";
}
}
void pintaArboles()
{
for (int i = unidadPixel; i <= rectArboles.Height; i=i+unidadPixel) //linea vertical izquierda
screen.Blit(spr_arbol, new Point( unidadPixel, i ));
for (int i = unidadPixel; i <= rectArboles.Height; i=i+unidadPixel) //linea vertical derecha
screen.Blit(spr_arbol, new Point( rectArboles.Width, i ));
for (int i = unidadPixel; i <= rectArboles.Width; i=i+unidadPixel) //linea horiz superior
screen.Blit(spr_arbol, new Point( i, unidadPixel ));
for (int i = unidadPixel; i <= rectArboles.Width; i=i+unidadPixel) //linea horiz inferior
screen.Blit(spr_arbol, new Point( i, rectArboles.Height ));
}
void pintaSuelo()
{
for (int i = rectSuelo.X; i <= rectSuelo.Width; i=i+unidadPixel)
for (int j = rectSuelo.Y; j <= rectSuelo.Height; j=j+unidadPixel)
screen.Blit(suelo, new Point( i, j ));
}
void pintaNPCs()
{
Random rand = new Random();
foreach(NPC npc in listaNpc)
{
if (npc.tiempoRestante == npc.intervaloMovimiento/2)
{
npc.sprite.Animate = false;
npc.direccion = 0;
}
if (npc.tiempoRestante == 0 || npc.moverPrimeraVez == true)
{
npc.direccion = rand.Next(1,5);
npc.tiempoRestante = npc.intervaloMovimiento;
npc.moverPrimeraVez = false;
}
if (npc.direccion == 1) //arriba
{
if (npc.sprite.CurrentAnimation != "arriba")
npc.sprite.CurrentAnimation = "arriba";
if (npc.sprite.Top > rectSuelo.Y)
{
int poc_anterior = npc.sprite.Y;
npc.sprite.Y = npc.sprite.Y - velocidad_mov;
if (validaColisionFutura(npc) == true)
npc.sprite.Y = poc_anterior;
npc.sprite.Animate = true;
}
}
else
if (npc.direccion == 2) //derecha
{
if (npc.sprite.CurrentAnimation != "derecha")
npc.sprite.CurrentAnimation = "derecha";
if (npc.sprite.Right < rectSuelo.Width)
{
int poc_anterior = npc.sprite.X;
npc.sprite.X = npc.sprite.X + velocidad_mov;
if (validaColisionFutura(npc) == true)
npc.sprite.X = poc_anterior;
npc.sprite.Animate = true;
}
}
else
if (npc.direccion == 3) //abajo
{
if (npc.sprite.CurrentAnimation != "abajo")
npc.sprite.CurrentAnimation = "abajo";
if (npc.sprite.Bottom < rectSuelo.Height)
{
int poc_anterior = npc.sprite.Y;
npc.sprite.Y = npc.sprite.Y + velocidad_mov;
if (validaColisionFutura(npc) == true)
npc.sprite.Y = poc_anterior;
npc.sprite.Animate = true;
}
}
else
if (npc.direccion == 4) //izquierda
{
if (npc.sprite.CurrentAnimation != "izquierda")
npc.sprite.CurrentAnimation = "izquierda";
if (npc.sprite.Left > rectSuelo.X)
{
int poc_anterior = npc.sprite.X;
npc.sprite.X = npc.sprite.X - velocidad_mov;
if (validaColisionFutura(npc) == true)
npc.sprite.X = poc_anterior;
npc.sprite.Animate = true;
}
}
npc.tiempoRestante--; //actualizo el timer de la animacion respectiva
screen.Blit(npc.sprite);
}
}
#region Funciones Generales
void Reiniciar()
{
//CargaInicialNieve(2550);
foreach(NPC npc in listaNpc)
{
npc.sprite.Center = npc.centroInicial;
}
msg_superior = "";
}
bool validaColisionFutura(NPC npc)
{
bool resultado = false;
foreach(NPC npcs in listaNpc)
{
if (npc.id != npcs.id)
{
if (npc.sprite.IntersectsWith(npcs.sprite))
{
npc.direccion = 0;
npc.sprite.Animate = false;
npcs.direccion = 0;
npcs.sprite.Animate = false;
msg_superior = "Intercepta "+npc.id.ToString() +" con "+ npcs.id.ToString() ;
//definimos un timer para que el mensaje se muestre solo 2 segundos
hora_msg = DateTime.Now.AddSeconds(2).ToString("HH-mm-ss");
resultado = true;
}
}
}
return resultado;
}
void CargaInicialNieve(int numeroCopos)
{
for (int i = 0; i < numeroCopos; i++)
{
copos.Add(new CopoNieve());
}
copos.EnableTickEvent();
}
void RandomValores(ref int x, ref int y, ref int t)
{
Random r = new Random(DateTime.Now.Millisecond);
x = r.Next(1,rectArboles.Width+1);
y = r.Next(1,rectArboles.Height+1);
t = r.Next(1,6);
}
#endregion
static void Main()
{
Cuarto ejemploNpc = new Cuarto();
ejemploNpc.Run();
}
}
public class NPC
{
public int id;
public AnimatedSprite sprite;
public Size tamano;
public Rectangle rectangulo;
public int direccion;
public bool moverPrimeraVez;
public int intervaloMovimiento;
public int tiempoRestante;
public Point centroInicial;
public NPC(int id, Size t, Rectangle r, int intervalo, int tiempo, Point centroIni)
{
this.id = id;
this.tamano = t;
this.rectangulo = r;
this.moverPrimeraVez = true;
this.intervaloMovimiento = intervalo;
this.tiempoRestante = tiempo;
this.centroInicial = centroIni;
}
}
public class CopoNieve : Sprite
{
static Random random = new Random();
float speed;
float wind;
float delta = 0.05f;
int resolucionX = 416;
int resolucionY = 320;
public CopoNieve() : base(new Surface(4, 4))
{
base.Surface.Fill(Color.White);
base.Surface.TransparentColor = Color.FromArgb(255, 0, 255);
base.Rectangle = new Rectangle(this.Surface.Width, this.Surface.Height, 0, 0);
Reset();
base.Y = -1 * random.Next(5000 - base.Surface.Height);
}
void Reset()
{
wind = random.Next(3) / 10.0f;
base.X = (int)random.Next(-1 * (int)(wind * resolucionX), resolucionX - base.Surface.Width);
base.Y = 0 - base.Width;
speed = random.Next(180, 255);
base.Surface.Alpha = (byte) speed;
base.Surface.AlphaBlending = true;
}
public override void Update(TickEventArgs args)
{
float change = delta * 30;
this.Y += (int)change;
this.X += (int)Math.Ceiling(change * wind);
if (this.Y > resolucionY)
{
Reset();
}
}
}
}
|