Modelo de datos en Javascript

Meleagant

Parecerá una duda tonta, pero nunca antes me había surgido.

Estoy haciendo un jueguecillo con Javascript, y no sé cuál sería la mejor forma de definir el "modelo".

Con modelo me quiero referir a que tengo una serie de elementos en el juego definidos todos con la misma clase, ya que su comportamiento es idéntico, pero necesito diferenciarlos a la hora de dibujarlos en pantalla y a la hora de que la lógica del juego actúe de forma distinta ante distintas combinaciones de los mismos.

En otras ocasiones he hecho utilizado una especie de "Enums" como estos en un fichero de "constantes":

colors = {NONE: 0, BLUE: 1, GREEN: 2, YELLOW: 3, PURPLE: 4},
states = {IDLE: 0, RUNNING: 1, JUMPING: 2, SLASHING: 3}

Sin embargo en esta ocasión puede que haya muchísimos tipos distintos, 50 o más, con lo cual me gustaría asociar, además del tipo de objeto, un string para identificar su sprite y no tener que hacer un switch enorme en el código.

De esta manera, por ejemplo, cuando quiera sacar el string del sprite correspondiente al objeto que voy a dibujar, podría usar algo como "tipo.sprite" directamente.

He pensado en guardarlo todo en formato JSON y leerlo de ahí. ¿Sabéis cuál es la práctica habitual para este tipo de casos?

Thanat0s

Básicamente lo que necesitas es definir correctamente las clases que necesitas.

Creo que no necesitas ni enums, ni un fichero de constantes.

Por ejemplo, si no te he entendido mal, vas a tener elemento1 y elemento2, ambos van a ser de clases diferentes y con un padre común del que heredarán los atributos y los métodos/funciones.
Ambos tendrán un atributo sprite para dibujarlo en pantalla y tendrán métodos heredaros del padre que harán cosas diferentes dependiendo de la clase de cada uno de ellos.

Meleagant

No, no. Todos los elementos tienen el mismo comportamiento, por lo que me parece innecesario crear 50 clases distintas para 50 tipos distintos de objeto.

Por poner un ejemplo, imagínate un juego de juntar bloques de colores. Todos los bloques se mueven igual, y se comportan igual. Simplemente se diferencian en la imagen que los representa y en que la lógica del juego actuará distinto si se juntan 4 bloques del mismo tipo.

La clase Bloque tendría un atributo "tipo", que podrá ser VERDE, AMARILLO, etc. pero no tiene sentido crear 50 clases distintas heredando Bloque que sean BloqueAmarillo, BloqueVerde, etc. etc.

La historia es que además del tipo, quiero una estructura de datos que asocie al tipo un string, de manera que cuando tenga un Bloque, pueda asociarle directamente el sprite definido por ese string, en lugar de tener que hacer un switch(tipo){ case verde: poner sprite verde }.

No sé si me explico xD

Thanat0s

Si todos tienen el mismo comportamiento, entonces está claro que no necesitas nada más que 1 clase.

Lo del sprite lo puedes meter en un atributo al crear el objeto.

Para no tener que hacer un switch a la hora de otorgar a ese objeto el sprite, puedes hacer un array con todos los sprites y luego hacer un indexOf.

1 2 respuestas
DaRk-eXe

iba a decir lo mismo que #4 :)

1 respuesta
Meleagant

#4 #5 Muchas gracias a los dos.

El tema es que además de el sprite, depende del estado del objeto tiene otro sprite alternativo, e incluso puede tener más propiedades únicas que aún no haya pensado.

¿Lo haríais con dos arrays? ¿No sería más correcto utilizar alguna estructura JSON tipo como esta?

tiposBloques = {

verde: {
    a:'verdeA',
    b:'verdeB'
},

azul:{
    a:'azulA',
    b:'azulB'
}

}

Hablo de la forma más acorde a buenas prácticas.

PD: La idea del indexOf no me acaba de convencer porque cada vez que tuviese que buscar el sprite de un elemento, tendría que hacer una búsqueda sobre el array que es un proceso relativamente costoso (comparado con una asociación directa) ¿no?

1 respuesta
Thanat0s

#6 La idea es que creas los elementos con el sprite ya cargado, de tal forma que sólo lo usas un número x de veces y la búsqueda tiene complejidad de orden n, que es bastante óptimo.

Esas propiedades únicas de las que hablas siguen siendo atributos de la clase que varían dependiendo del estado del objeto, es decir, nada de almacenamiento externo al propio objeto.

d253

No se si lo he entendido bien, pero la cosa es crear un objeto con x,n atributos y tener fácil acceso a ellos. Contando que algunos atributos cambian por el estado.

Por lo que entiendo seria algo asi:
No se si te servira o si es exactamente lo que tienes pensado.

function buscarObjetoPorPropiedad(array, propiedad) {
    return array.filter(function (entry) {
        return Object.keys(propiedad).every(function (key) {
            return entry[key] === propiedad[key];
        });
    });
}

var bloque = function(color,estado) {
  var self = this;
  this.color = color;
  this.estado = estado;
  this.setEstado = function(estado) {
    this.estado = estado;
  },
  this.sprite = function() {
    var sprite;
    if (self.estado == 1 ) {
      sprite = this.color+'1';
    }else{
      sprite = this.color+'2';
    }
    return sprite+'.jpg';
  };
};

var verde = new bloque('verde',0);
var rojo = new bloque('rojo',0);
var naranja = new bloque('naranja',0);

var bloques = [verde,rojo,naranja];

var resultado = buscarObjetoPorPropiedad(bloques, { color: 'verde' });
console.log(resultado[0].sprite());

Si no se guardara ese JSON en bd ni localStorage ni nada lo veo inecesario, pero si es asi mejor usa un "hashtable" de dos indices que es muy facil de pasar a json y a la inversa.

Usuarios habituales

  • d253
  • Thanat0s
  • Meleagant
  • DaRk-eXe