jueves, marzo 08, 2007

Cristianismo e Hipocresía

¿Existe la gente mala? ¿Existe la gente buena? ¿Qué tipo de gente sos? ¿Por qué? Mis respuestas: NO, NO, ?, -.
"La gente mala" esto suena a un grupo social diferenciado del resto (que sería "la gente buena") , lo cual me parece estúpido. Cualquier persona tiene maldad, o sea es capaz de ejercer el mal y tambien es capaz de ejercer el bien. Si bien alguien puede ser juzgado de "bueno" por sus actitudes hacia el resto, esto no quita que desaparesca su capacidad de ejercer el mal, y viceversa. El esfuerzo de basarse en la doctrina, ideas y perceptos del cristianismo nunca va a eliminar de una persona su capacidad de ejercer el mal, esto solo conlleva a la hipocresía de creerse "bueno" o hacerse ver como tal. Un ejemplo práctico de esto es un liceo católico, donde por lo general hay un cura principal que ejerce "autoridad" sobre la institución imponiendo su doctrina e ideas, tal vez basadas en las de jesucristo, no sé, y no creo. Si alguien de la institución no respeta esas ideas será castigado hasta que aprenda a cumplirlas. Rezar, estar al día con las cuotas y colaborar con el mantenimiento de la institución son hechos que determinan la bondad de una persona dentro (y fuera) de la institución, lo cual evidentemente es absurdo. Veo desde cerca cómo un "amigo" ("egresado" de liceo católico) se considera una buena persona por rezar cuando tiene problemas, hacerse la cruz cuando pasa por frente a una iglesia y tener crucesitas o virgenes de plastico en su casa, cuando en la vida real es envidioso, mentiroso, falso y constantemente tiene el deseo de estar deseandole el mal a alguien para satisfacerse, entre otras cosas. Más alla de si soy quien o no para juzgarlo, son cosas que veo claras en su actitud. La única forma de evadir el mal dentro de una persona es la aceptación del mismo, el seguimiento de la disciplina e ideas hacia el ideal de "buena persona" o "santo" solo conducen a la hipocresía y la mediocridad de creer un perfil que no existe.

Etiquetas:

viernes, marzo 10, 2006

Sistema de Partículas III : Rendering

Recién ahora se podría pensar en qué motor usar, en caso de elegir no reinventar la rueda, claro. SDL es muy lento, y requiere de optimizaciones a mano hasta para poner un pixel en pantalla. Hay muchas funciones rondando por la web para dibujar un pixel en pantalla con SDL, ésta es la típica (la que se ve en todas partes) y es deprimente (el autor avisa que no está optimizada, pero no creo que el comentario ayude de mucho despues de ver cómo está implementada) . La que voy a usar está hecha por mí, y tampoco es una de las mejores...pero es bastante rápida y consume 6 veces menos memoria que la anterior. Es importante optimizar esta parte, ya que es una etapa crucial dentro del sistema: interpretar en pantalla la física actual de cada partícula. También está sujeta a la cantidad total de partículas. En los screenshots he usado 10.000 partículas y el consumo total del sistema fue de 3.480 KB y aún se podría seguir optimizando, pero no mucho. Una optimización clave es que he usado un sistema estático, y las partículas aún muertas siguen chupando memoria. Si fuese dinámico el consumo tiende a 0 en menos de 5 segundos, almenos para esta explosión en particular.

  • Sin considerar ninguna paleta


No voy a considerar ninguna paleta, por ahora almenos...En el sistema inicial las explosiones siempre las hice rojas con chispitas negras al final...Se ajusta a mi manera de dibujar XD. Es muy fácil usar una paleta, pero no tan fácil es modelarla, hay que probar y probar viendola en pantalla hasta que quede bien. Hasta ahora he probado estas implementaciones con la paleta anterior (rojo y negro) y con una que saqué de "All about color palettes, Chapter 8" ; no sé el nombre del libro, pero los fascículos están muy buenos y completos, tiene todo sobre programación gráfica en 2D.
  • Explosiones: ejemplo

Para modelar explosiones usamos los algoritmos de setup y movimiento de partículas vistos en el cap. 2, modificando los siguientes parámetros:

- gravedad: +3.5
- considerar: muertes y sistema muerto

Considerar muertes implica asegurar que luego de que una partícula queda pegada a una superficie (al piso por ejemplo) ya no se la esté intentando mover. El sistema está muerto cuando todas las partículas están muertas. Si esto no se controla, al finalizar la explosión el sistema seguirá chupando recursos innecesariamente.

Para los ejemplos usé 10.000 partículas, la resolución que usé es 320x200. Este sistema en su pico máximo (todas las partículas vivas) consume 3480 KB (sí, un disparate). Este mismo sistema a una resolución de 800x600 consume 4716 KB. El motor influye mucho en el rendimiento, y también la forma de usarlo. Notar que el sistema es estático, o sea que con 'pico máximo' me refiero a poca diferencia con pico mínimo. Una vez mas...es recomendable implementarlo de forma dinámica.

Esta es la función que usé para ver las partículas:

void putpixel(SDL_Surface *screen, int x, int y, Uint32 color)
{
// Determinamos posición de inicio
char *buffer=(char*) screen->pixels;
// Calculamos offset para y
buffer+=screen->pitch*y;
// Calculamos offset para x
buffer+=screen->format->BytesPerPixel*x;
// Copiamos el pixel
memcpy(buffer, &color, screen->format->BytesPerPixel);
}


Explosión con pixeles: (10.000 partículas)





Explosión usando 1.000 partículas:




































  • Que venga la sangre!!!

Con este algoritmo generar cascadas, salpicones, etc. de sangre es muy fácil, y va muy bien :D. En cascada:





No se nota mediante shots, pero hay un leve rebote antes de terminar de caer.
Lo mejor de todo, es la vagancia de implementar la sangre, simplmente hice las siguientes modificaciones:

-> gravedad = +3.5
-> las partículas mueren cuando alcanzan la coordenada y=180

Como vimos en el capítulo 2, considerabamos choques con las superficies. Por lo tanto al existir gravedad, se genera una serie de rebotes descendentes, acabando las partículas muertas en el piso. Si no se considerara las colisiones con el piso, las partículas mueren apenas alcancen la coordenada y=180 , esto sería ideal para cuando la sangre cae de una ventana o algo así...sin tocar piso o nada en su camino.

  • Obtener otras orientaciones
Solo basta con jugar con los parámetros de la función setup, dado que hay que modificar la inicialización de cada partícula para obtener otras orientaciones hacia donde sea.

Ejemplo:
// olvidemos la clase vector por un instante
// sinó no me da el espacio ;)

// coordenadas de inicio
// si hubiese que modelar lluvia
// sería y=0, x= rand()%320
particles[i].x = float(rand()%2+ 160);

particles[i].y = float(rand()%2+ 100);

// para obtener direcciones a gusto
// hay que modificar los ángulos de
// salida

// generamos ángulo pseudoaleatorio
// en grados y lo pasamos a radianes

int grade = rand()% 360;
float angle = (float) grade/180 * 3.1416;

// incializamos velocidad
float vel = 4.0f;
// generamos el vector dirección
particles[i].dirx = sin(angle) * vel;
particles[i].diry = cos(angle) * vel;

Notar que hemos cambiado la forma de disparar las partículas respecto de lo visto en el capítulo 2. Ambas formas funcionan, es decir, mediante ángulos y mediante valores pseudoaleatorios, sin embargo con el segundo método aparecen 2 lineas perpendiculares en el centro de explosión, y se debe a que en esas rectas no hay partículas viajando porque sus valores iniciales no pertenecen a la recta. Las rectas no son de partículas en sí, son de vacío, es decir, el conjunto de partículas explota y deja espacios vacíos alrededor de esas rectas. En fin, es solo un detalle, pero para más calidad usar ángulos para incializar las direcciones.

  • Dibujando las partículas
La función Draw_Particle dibuja una partícula, la función Draw_Particles llama PARTICLES veces a Draw_Particles.

void Draw_Particle(particle *aparticle)
{
long x, y;

// pasando las coordenadas a enteros...

x = (long)(aparticle->x);
y = (long)(aparticle->y);

// color rojo, no hay paleta

Uint32 c=SDL_MapRGB(pantalla->format,255,0,0);

// dibujamos la partícula en pantalla

putpixel(paux,x,y,c);

}

  • Dinámica en pantalla
Este es el orden de invocación que usé en el bucle principal:

// limpiar la pantalla
SDL_FillRect(pantalla, 0, SDL_MapRGB(pantalla->format, 0, 0, 0));
// dibujar partículas
Draw_Particles(particles);
// doble buffer
SDL_BlitSurface(paux, 0, pantalla, &dstrect);
// mover partículas
Move_Particles(particles);
// actualizar
SDL_Flip(pantalla);

Esto es todo por el capítulo 3...Quedan muchos efectos, aunque después de hacer 2 o 3 y entender la dinámica es fácil imaginarse otros efectos con tan solo modificar parámetros y colores. Una mejora que vale la pena es considerar una paleta de colores.

miércoles, febrero 22, 2006

Sistema de Partículas II : Explosiones

Esta serie que estoy escribiendo tiene fundamentalmente 2 objetivos. El primero es mostrar una posible manera de comenzar a hacer una sistema de partículas, comenzando por lo básico y luego con la práctica añadir efectos y mejoras al sistema. El otro objetivo es repuntar ideas de mi parte para luego formar el sistema independiente, expansible a medida que sea necesario. Dejando los discursos de lado, en este capítulo voy a mostrar una manera básica de implementar explosiones, y a partir de ella se podrá adaptar una explosión distinta para cada necesidaad. Más adelante veremos otros tipos de implementación para explosiones mas avanzadas.


  • Set up y movimiento de las partículas

Para modelar una explosión lo que hago primero que nada es inicializar cada partícula estableciendo las siguientes características:
  • Punto en común de orígen
  • Dirección
  • Energía

En las explosiones aéreas la dirección de cada partícula es distribuída en forma esférica centrada en el punto de orígen. Este tipo de explosiones podrían modelarse con la distribución de direcciones de cada partícula de manera uniforme. Si cortamos la esfera que forma esta distribución con un plano donde ocurre la explosión, una pared por ejemplo, la dirección e cada partíucula será distribuida en forma semi-esférica dado que cada una es disparada en la dirección normal al plano de impacto. Habría que adaptar esto ya que si la explosión surge en un ángulo las partículas deberían explotar correctamente para dar mas realismo, dado que necesariamente la distribución será esférica o semi-esférica.

Veamos el código de inicialización para cada partícula (set up). Como parámetros de entrada ingresamos las padrtículas, el vector coordenada de impacto y la cantidad total de partículas. Este último campo es para una implementación estática del sistema, podría obviarse con una celda dummy en el caso de implementación dinámica (recomendado). Minimizar la cantidad de operaciones con memoria (new y delete) hace mas eficiente el sistema, en el caso de la implementacion dinámica a medida que se necesitan partículas se siguen los siguientes pasos: Determinar si hay partículas muertas pero con alojo en memoria, en este caso resucitar las necesarias. Sin no hay muyertas,, entonces empezar a crear las que sean necesarias, pero claro, esto tampoco es barato. El alojamiento en memoria tiende a crecer dependiendo de la cantidad de eventos simultáneos, probablmenete sean partículas muertas las que estén alojadas. Mediante la implementacoión estática también logramos eficiencia, pero a un costo bastante mayor de entrada, dado que aunque haya solo 1 partícula viva en el sistema, siempre se tendrá el máximo de partículas alojado en memoria. Para las explosiones por lo general se conoce de entrada la cantidad de partículas máxima del sistema, y todas interactúan en la explosión (inicialmente). Sin embargo no siempre las explosiones toman el mismo tamaño y energía, entonces en necesario acotar conjuntos independientes del total para adaptar la explosión deseada. Es aquí donde entra en utilidad el campo active que indica si la partícula está activa (viva) o si no lo está (muerta). En nuestro caso usaremos arreglos dinámicos, y este campo solo servirá para descartar partículas muertas, no para acotar sistemas, por ahora almenos.

NOTA (sobre los vectores): en las imlementaciones aparecen directamente funciones de la clase vector. No vale la pena detenerese en esta clase, es muy intuitiva y las funciones también lo son, de hecho hablan por si solas.

// constantes del sistema
#define PARTICLES 1000
#define GRAVITY 9.8
#define ENERGY 7
...
// set up del sistema
particle* p= new particle*[PARTICLES];
...


void explosion::setup(particle* &p, vector coord, long tpar)=
{
float len, ie, dx, dy;
particle* paux=p;

for(long i=0; i < tpar; i++)
{
//activamos la partícula
paux->active= true;

//coordenadas del orígen
paux->pos.setx(coord.getx());

paux->pos.sety(coord.gety());

//dirección aleatoria al explotar
//negativa o positiva (a suerte)
paux->dir.setx(((rand()%4)-1.5));
paux->dir.sety(((rand()%4)-1.5));

//setup de energía inicial
ie= (rand() % ENERGY) + 1;

//registramos las coord para el cálculo
//del módulo, esto debe ir en la clase vector
dx= paux->pos.getx();
dy= paux->pos.gety();

//cálculo del módulo
len= sqrt(dx*dx + dy*dy);

//norma
if (len != 0.0)
len= 1.0 / len;

//normalizar para encontrar la dir.
//del vector, la distr. deja de ser uniforme
paux->pos.setx((paux->pos.getx())*len*ie);
paux->pos.sety((paux->pos.gety())*len*ie);

//color inicial
paux->color= 255;

paux++
}
}



Y el vector velocidad? La velocidad inicial no se tiene en cuenta en esta implementación, todas se mueven a velocidad constante. Recordar que esto es un primer intento, luego de tener la idea es fácil mejorarlo y agregar lo que venga. Con esta implementación mover las partóuclas es muy sencillo. Esta inicialización posiciona las partículas en el núcleo de la explosión. Ahora debemos expandir las partículas, recordando que no aceleran para este caso. Una explosión con partículas aceleradas y considerando adicinoalmente la aceleración de la gravedad, aunque se forme con pixeles, va de lujo en cualquier cosa :p, pero primero bastaría con formar una explosión común y corriente, para luego empezar a modificar a gusto teniendo el concepto.
Consideraremos una explosión en una habitación, para observar las colisiones. La habitación será un cadrado de 100x100 pixeles cuyo vértice superior izquierdo se ubica en el punto de coordenadas (350,250). También consideraremos la aceleración de la gravedad, y un efecto muy simple de "chispa pixelada" para indicar las partículas próximas a la muerte.

Veamos ahora la implementación para el movimiento.


void explosion::move_particles(particle*p, long tpar)
{
particle* paux= p;

for(long i=0; i < tpar; i++)
{
if (paux->active) {

//movemos la partícula de acuerdo al
//vector dir
paux->pos.setx(paux->pos.getx()+paux->dir.getx());
paux->pos.sety(paux->pos.gety()+paux->dir.gety());

//chequeamos colisiones con piso: muerte
if (paux->pos.gety() > 350)
paux->active= false;
else

//colisiones con techo
if (paux->pos.gety()) < 250)
{
paux->pos.sety(250);
paux->dir.setx(paux->dir.getx()/4);
paux->dir.sety(-(paux->dir.gety())/2);
}
else

//no actúan fuerzas en el eje x -> 0
//gravedad en el eje y -> 9.8
//en update sumo gravedad a la dirección en y
paux.update(0, GRAVITY);

//colisiones con paredes
if (paux->pos.getx() < 350)
{
paux->pos.setx(350);
paux->dir.setx(-(paux->dir.getx())/2);
paux->dir.sety(paux->dir.gety()/4);
}
else

if (paux->pos.getx() > 450) {
paux->pos.setx(450);
paux->pos.setx(-(paux->dir.getx())/2);
paux->dir.sety(paux->dir.gety()/4);
}

//si la partícula está próxima al piso
//hacemos un efecto de chispa cambiando
//el color del pixel

if (paux->pos.gety() >= 348)
paux->color= (rand() % 128) + 128;

}
paux++;
}
}



Esta implementación requiere de sincronismo. SDL_GetTicks() es la solución. Para los que no tienen ni idea de que es lo que hace esta función, devuelve (en milisegundos) el tiempo desde que se ha encendido la máquina. Podemos entonces implementar una función, que dado un punto de inicio retorna el tiempo transcurrido hasta el punto actual (en términos de tiempo):

inline Uint32 lapsedTime(Uint32 &t)
{
return t= SDL_GetTicks()-t;
}

Esto es todo por hoy. Recordar que éstas implementaciones pueden ser optimizadas. Pero al optimizar algunas cosas teóricas sencillas pueden resultar engorrosas, y lo importante es que quede el concepto, la implementación en este caso es lo de menos, cada cual implementa a su manera :).





miércoles, febrero 15, 2006

Sistema de Partículas I

Hace un tiempo atrás tenía implementado un sistema de partículas simple, lo había hecho antes de empezar con un juego de aviones, para modelar explosiones aéreas. A mitad de proyecto volví a cambiar la implementación del sistema agregando explosiones terrestres, pérdidas de combustible desde el mismo avión y otra clase para manejo de vectores. Eso en un principio, hoy mi sistema tiene ya varios efectos diferentes. Cada vez que se agrega un efecto es muy probable que haya que modificar varias clases, sobre todo la misma clase 'partícula'. El objetivo de esta serie 'Sistema de partículas' es comentar como he empezado mi sistema de partículas, desde los efectos iniciales. La idea es repasar mas que nada fragmentos de código (en C++) y algunos puntos teóricos. El código del sistema original no es corto, y está adaptado a mis necesidades en cuanto a lo que haga, asi que los fragmentos de código que use en esta serie pueden verse reducidos para no confundirse.
Humo, explosiones, nubes, chispas, lluvia, sangre son algunos efectos que se benefician de un sistema de partículas.

  • Performance y Requerimientos
Un sistema de partículas avanzado puede requerir de código extensamente largo, por tanto las estructuras deben estar lo mejor diseñadas posible. Un buen comienzo es hacer la menor cantidad de operaciones que impliquen memoria (new y delete) como sea posible. A veces, luego de que la partícula este muerta, es mejor no liberarla de memoria y simplemente darla por muerta desde un campo booleano de la partícula. En este caso, el sistema de partículas liberaría la memoria en el caso de que todas las partículas del sistema esten muertas.
Al crear un sistema de partículas es importante considerar todos los posibles parametros que sabremos que serán afectados en el sistema en algún momento del juego, y crear esa flexibilidad dentro del sistema.

  • Jerarquía del sistema dentro del motor
El sistema de partículas debe ser del mismo grado del motor, es decir, poder actuar sobre los mismos objetos. Por ejemplo disparar un misil y a su vez agregar el efecto de humo en la tobera del mismo, ó que la sangre corra por el cuerpo del personaje mientras este también corre. En estos casos, cuando el objeto se mueve la posición del sistema de partículas que está unido al objeto en cuestión debe ser actualizado correctamente. Lo mismo pasa al considerar la aceleración de la gravedad sobre cada objeto.

  • Multi-Rendering
Algunos sistemas de partículas deberán renderizar sus partículas de distinta manera. Un ejemplo, un chorro de sangre puede estar volando por el aire pero al tocar una pared deja de volar para mancharla, y dejar salpicones. Por tanto podemos diferenciar 2 sistemas a renderizar, "chorro de sangre" y "sangre chorreada" para pisos y paredes. También dependiendo de la situación las partículas pueden ser sólo pixeles, en el caso de las 2D un sprite, ó un modelo 3D. En este caso, una de las cosas a tener en cuenta es que el sistema de partículas incrementa enormemente el número de polígonos visibles por frame.

Existen muchos requerimientos, pero para empezar no es necesario saberselos todos. En esta serie siempre se hará referencia a un sistema de partículas en 2 dimensiones, dado que llevarla a 3 es simplemente agregar una componente, para el caso de los algoritmos (renderizar cada partícula es muy distinto, claro está). Como dije antes el código está escrito en C++ y usaré el motor SDL para la tarea simple de visualizar las partículas. La elección del motor depende únicamente del efecto visual que se desee para las partículas, en esta serie el cometido es el sistema de partículas en sí y no la parte de visualización de las mismas, por este motivo el motor a usar da lo mismo. También voy a considerar las partículas como pixeles, para facilitar el código.

Las Partículas

Una partícula es, en general, un solo punto en el espacio. A este punto se le asigna atributos o características. Las características más comunes de una partícula son:
  • posición
  • energía
  • velocidad
  • dirección
  • tiempo de vida
A medida que avanza la animación de la partícula las características son requeridas para ello, a la vez que se modifican y se actualizan. Tenemos entonces la clase partícula:


class particle {
public:
bool active;
int color;
vector pos;
vector dir;
vector oldpos;
vector vel;
float energy;

reload();
update(float& friction, float& gravity);
rendering();
}


active:
La partícula puede estar cargada en memoria, aún cuando muerta. Este campo indica cada caso.

color:
Define el color como un RGB (para los pixeles). Puede usarse para almacenar el índice de un arreglo de bitmaps creado previamente para colorear cada partícula.

energy:
Como la misma etiqueta, registra la energía actual de la partícula. Evita el tener 2 campos como 'lifetime' y 'age', a medida que la partícula actúa en el sistema la energía se va agotando o incrementando; cuando energy<=o la partícula ha muerto. Pero si esto es así, entonces para qué está la etiqueta 'active' ??? Bueno, por algo la puse ;) . Este campo será reemplzado por una constante en las explosiones simples (sin considerar aceleración).

oldpos: Es el vector posición anterior de la partícula, antes de haber sido modificado. No será usado en las explosiones (almenos en las mas comunes). Este campo es muy usado por ejemplo para modelar chispas y en algunos casos, llamaradas de fuego. El resto de los campos, hablan por sí solos.

Ahora veamos las funciones:

reload( ): Optimiza el rendimiento del sistema, evita las operaciones new y delete. Resucita una partícula muerta sin pedir memoria.

update( ): Actualiza la física de la partícula, sus valores pueden ser modificados en base a los parámetros que recibe (gravedad y fricción).

rendering( ): Es el encargado de renderizar el comportamiento de la partícula. La clase vector debe incluir, aparte de lo básico como vector de 2 componentes, una función para normalizar el vector, que será usada en los algoritmos de explosión para normalizar el vector dirección, como se verá mas adelante.

Esto es todo por el primer número, suficiente para empezar con las explosiones en el siguiente capítulo. Si al avanzar veo que quedó algo colgado, actualizaré el capítulo correspondiente para agregarlo, asi que hasta no terminar la serie los capítulos pueden ser modificados.

viernes, febrero 03, 2006

Cerrado por Examenes

Hace varios días no he tenido tiempo suficiente para nada, todo sería mas productivo durmiendo menos. Prácticamente se me han corrido todos los tiempos, me levanto a las 12 a.m. mínimo, almuerzo alrededor de las 3 p.m. y no tengo cena prácticamente, ya que a las 7 p.m. vuelvo a comer algo. Me estoy llendo a dormir en promedio a las 4 de la mañana. En términos "horarios" un desastre...pero en la obscuridad de mi cuarto no tengo noción de la hora, que sean las 2 a.m. o las 2 p.m. da lo mismo, me voy a dormir cuando tenga sueño y me despierto cuando abro los ojos jeje...A partir del lunes este blog no va a ser el mismo, no me gusta para nada el look actual, demasiado 'standard' y se nota que las entradas son solo 'por poner algo'. Pero vamos, esto no es de nerd ni de vago, simplemente no hay tiempo libre.

Etiquetas:

martes, enero 17, 2006

Unreal Engine 3: la nueva tecnología de Epic


Los de Epic han demostrado que utilizando su nuevo motor la produccion de juegos tendra un costo de entre 30% a 50% menor que el actual. Como era de esperarse Microsoft ha firmado un trato para utilizar el Unreal Engine 3 en su proxima generación de videojuegos, uniéndose así a Midway y BioWare. Tambien se informó que Epic esta actualmente desarrollando juegos en base a esta nueva tecnología, pero no se dieron a conocer datos relevantes sobre ellos. Segun rumores parece que Gears of War es uno de ellos. Tambien se rumorea que el coste del motor supera los USD 600.000 ... si aun despues de deprimirse con el precio quedan ganas de saber mas sobre él haz clic aqui.

jueves, enero 05, 2006

MK Armageddon, otro comienzo



Cuando tenia 11 años vi por primera vez la MK2 en un salon de makinitas, cuando llegamos con mi primo habia un grupo de gente apoyandose en la maquinita mirando la pantalla desesperados, ni siquiera pude ver que juego era. En cuanto pude tome un lugar y vi que era la MK2, recien llegada a Uruguay. Lo que me asombró no fueron ni los graficos ni el juego en sí, sino la rapidez con la que el tipo movia la palanca y combinaba los 5 botones. Luego la
MK3 y la Ultimate resultaron mucho mas rápidas que las anteriores, esto trajo un inconveniente para los lentos : tanta velocidad no daba cabida a la estrategia de juego, cosa de la que MK2 podía presumir. La inclusión del boton "run" y los "animalities" no le gustaron a mucha gente, personalmente no me gustó la aparición de personajes baratos como Stryker y Sindel, y el atrevimiento de sustituir a los clasicos Scorpion y Cage. Nunca presté atención a la historia detrás del juego, de hecho me aburre, pero como en todo juego no debe faltar. Como dije antes lo que me atrae es la alta velocidad de juego y la mezcla de habilidad-reflejo y estrategia, siempre y cuando se juege a ese nivel XD.
Lamentablemente la velocidad de juego murió a partir del MK Mythologies SUB-ZERO y personalmente le he puesto la cruz a sus sucesores. En este año está previsto el lanzamiento de la MK ARMAGEDDON para las plataformas x-box y ps2, siendo la continuacion de MK Deception (y bien puesto el nombre) . Ed Boon reveló que MK Armageddon presentará el cuadro de selección con más personajes de cualquier MK anterior. También se dijo que este juego estará construido bajo el motor de MKDA y MKD, pero con algunas novedades en el motor de lucha y un modo "Crea tu personaje" para el modo Konquest, ya que Ed Boon dijo que probablemente harían eso en MK7 ( armageddon). En cuanto a la dirección que tomará el argumento... de momento todo son especulaciones, pero por el nombre del juego parece posible que el mal haya vuelto a ganar, y el Único Ser está intentando volver y toda la realidad se colapsa: es la hora del Armagedón. (las imagenes son de MK-deception)