Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema desarrollo juego estrategia

Iniciado por mvelazquezm, 18 de Agosto de 2006, 09:02:37 AM

« anterior - próximo »

mvelazquezm

Hola a todos.

Estoy desarrollando un juego en java de estrategia por turnos en 2D. El juego es de barcos de la época de colonizadores, piratas...(los típicos barcos de madera). De momento todo va bien, pero me ha surgido un problema: Tengo clases islas, con oro (clase oro) y clase barco para representar los barcos. Hay muchos barcos distintos y la información de cada uno (movimiento, disparo,...) lo obtengo de una base de datos con la información de todos los barcos disponibles. El problema me surge porque todos o casi todos los barcos tienen reglas especiales que alteran el transcurso normal del juego. Por ejemplo un barco puede tener la siguiete regla: "al principio del turno con un 20% de posibilidad este barco mueve dos veces" y otras muchas más posibilidades. Implementar esto sería fácil, pero el problema es que hay cientos de barcos con habilidades distintas y no quiero: ni tocar el código de las acciones (movimiento, disparo) ya que si tengo que contenplar tantas habilidades especiales me volvería loco y haría del código básico del juego una bestialidad. Tampoco quiero crear una clase para cada barco por lo mismo: hay cientos de barcos y con el tiempo se va aumentando este número.
La única solución que he visto y no se si es posible es crear una clase que será inmensa que tenga listeners para las habilidades. A ver si me explico, por ejemplo en el caso anterior, cuando sea el turno de movimiento de este barco, que salte el listener y realice el cálculo del porcentaje y si se dá el caso, permitir otra acción de movimiento sobre el mismo barco.
¿Que opinais vosotros? ¿Si es correcta mi intención de solución me podrias hacer un ejemplo pequeño de cómo realizar el listener?

Muchas gracias. Si necesitais más información no dudeis en pedirmeló.

Un saludo.

josepzin

No controlo mucho de Javascript, pero me parece que hacer los calculos en JS y en el Explorador va a hacer que sea facil hacer trampas... o no?

Suerte!

mvelazquezm

Bueno en realidad no estoy usando JavaScript. Usó sólo Java. J2SE 1.5. En un entorno Swing

josepzin

Perdon entonces... no dije nada  :oops:

1cacalvo

Y si subdivides los barcos para crear una herencia, podrias tener la clase barco, y de ella heredan barcos aliados, barcos enemigos, y de cada una de ellas las distintas clases de barcos con lo cual podrian tener propiedades distintas para las mismas acciones...

Igual lo estas haciendo asi ya, y estoy diciendo una tonteria... :S

mvelazquezm

No es lo que pensé, de hecho un juego muy similar que hice hace poco era así, hice una clase general con lo básico y para cada tipo, una que hereda de la básica.
El problema viene de que hay muchos tipos de barcos, habrá unos 100 y cada 6 meses salén de nuevo unos 30 barcos (es que el juego está basado en un juego de cartas coleccionables) Yo creo que va a ser la única solución. El caso es que de esta forma necesito crear una clase para cada tipo de barco; mientras que con la supuesta solución de los listeners podría aprovechar algunas reglas especiales que varios barcos tienen igual.

Lo único que me gustaría es saber como se implementa esto en otros juegos, ya que muchos juegos, sobretodo los de estrategias en los que hay muchas unidades y demás.

Muchas gracias por las respuestas, que aunque de momento no me sirven para dar una solución real, me están sirviendo para dirigirme hacia ella.

PD: josepzin no pasa nada  :wink:

Un saludo.

shephiroth

Buenas.

A mi se me ocurre una forma, no se si es la mejor en cuanto a eficiencia, pero creo q fucionara. La idea es que te crees dos clases, Barcos y CreadorBarcos.

Barcos sería la clase q tienes actualmente, los barcos en sí. Aqui tienes todas sus características bases.

CrearBarcos sería una clase que manejaria los eventos que comentas y modificarían los datos del barco. El codigo seria como:


Barco *uno;
CrearBarco *temporal = new CrearBarco();
temporal->clear();
temporal->listenerMovimiento(//argumentos que sean//);
temporal->listenerVida(...);
temporal->agregarBarco(uno);


El tener una clase separa para crear los barcos y demas puede parecer una tontería, quizas sea mejor en la propia clase de barcos, pero segun que tipo de herencia utilices puede irte mejor asi ^^

mvelazquezm

Muchas gracias. Intentaré provar a ver que tal

Warchief

Uhm, se me ocurre que el cargador de datos (de cartas, ficheros, etc) register las acciones necesarias.


class IAccion {
  public void Do();
}

class TipoBarco
{

 Contenedor accionesPreTurno;
 Contenedor accionesTurno;
 Contenedor accionesPosTurno;

 public void InsertarAccionPreTurno( IAccion accion );
 public void InsertarAccionTurno( IAccion accion );
 public void InsertarAccionPosTurno( IAccion accion );

};

class Barco {
 TipoBarco MiTipo;

 public void Control() {
    // Pseudo-código
    PARA CADA accion en MiTipo.accionesPreTurno DO do();
    PARA CADA accion en MiTipo.accionesTurno      DO do();
    PARA CADA accion en MiTipo.accionesPosTurno DO do();
 }

};

// Ficheros de cartas, xml o lo que sea
Llevan el nombre de la IAccion a implementar

<TipoBarco type"npi">
 <preaccion tipo="AccionPrepararMoverDoble" porcentaje="0.20"/>
 <accion tipo="AccionMover" porcentaje="0.20"/>
 <accion tipo="AccionDisparar" porcentaje="0.20"/>
</TipoBarco>


No sé si se puede obtener una clase a partir de su nombre (como AccionPrepararMoverDoble).

(java.reflect? http://java.sun.com/docs/books/tutorial/reflect/object/create.html )

Pros:
Versátil. Puedes añadir acciones sin tener que tocar nada el resto del código. (Sólo añadir una nueva subclase de IAccion)

Contras:
Hay que definir bien el xml o fichero de tipo de barco.

Uhm, como se relaciona el barco con el tipo también habría que pensarlo.

No sé, igual es una pinza mental, pero ahí queda. XD

paquitoChocolatero

Hola, otra opción, que puede ser la mas compleja, aunque la mas completa y flexible podria ser hacer un "interprete" de esas "reglas especiales".

Es decir por lo que cuentas un barco es algo como:

publi class Barco{

    private String nombre;

    private int disparo;
    private int capacidad;
    private int movimiento;
    private int pasajeros;

    public void disparar(Object objetivo){ ... }
    public void mover(Posicion destino){ ... }

}

La clase representan una carta de juego de barco, y los atributos las caracteristicas o numeros de la carta.

Pero ademas las cartas tienen un texto de "regla especial" pues bien sigamos representando la carta, solo tienes que añadir...

    private String texto;

Que tambien vendra de un campo de la base de datos (correctamente escrito en algun lenguaje de script que luego deberas interpretar). Y ahora el tema es lo que quieras complicarte en la flexibilidad de las reglas y lo completo que quieras que sea el lenguaje de script.

de modo que en el codigo de:

    public void mover(Posicion destino){
         ...
         ...
         resolverRegla()
    }

    private void resolverRegla(){
        ...
        /* Y aqui viene el tomate, puedes usar algun lenguaje de script  mediante alguna libreria de java o hacerte tu uno0 muy sencillo, por ejemplo
      caracteristica = NUM_MODIF */
        ...
    }

De modo que para aumentar una caracteristica como movimiento la regla seria movimiento = 3 (esto con stringTokenizer es una tonteria de implementar, pero calro no es muy flexible y querras que tenga mas potencia, pues tendras que currartelo mas.

Esta es mi sugerencia que se me ha ocurrido sobre la marcha, espero que haya quedado mas o menos claro.

Un saludo.

mvelazquezm

Lo primero muchas gracias a todos por el interés y los intentos de soluciones. La solución que más se acerca a mi idea es la de paquitoChocolatero. Como bien has dicho los barcos son del estilo que muestras y las habilidades especiales aunque recojo el texto para mostrar al usuario de qué habilidad se trata, siempre recupero un código de habilidad.

Cuando creo un barco puedo crear el objeto de la clase Especial con el código de la habilidad. Puedo tener varios tipos de habilidades agrupadas a la acción que afectan: habilidades de movimiento, de disparo, ....
para que si el barco que realiza una acción tiene reglas especiales de ese tipo se llama a resolverRegla() que a su vez llamará al objeto Especial para que realice la acción.

Mi problema era que pensaba en la captura de estas habilidades de una forma global, de ahi lo de usar unos listeners activos que saltasen cuando fuera el turno del barco y en la acción adecuada. Viendo esto a nivel de cada barco, simplemente tengo que comprobar cuando realice la acción: las habilidades especiales que pueden ocurrir.

Muchas gracias a todos. Entre toda esta información seguro que obtengo algo claro por fin.

Un saludo.

MartinCalveira

Soy nuevo en el foro, hola. Al leer tu consulta me acordé del libro "Head First Patterns" que he estado leyendo y en donde en los primeros 3 capítulos habla de un patron de diseño que resuelve tu problema. Ahora no recuerdo que capítulo es pero está entre los 3 primeros.
Espero que te sirva.

Saludos.

Martín

mvelazquezm

muchas gracias por el nombre del libro. Intentaré buscarlo

bnl

Una solución que se me ocurre podría ser crear una clase para cada regla especial que contuviera el codigo de la regla y luego a cada barco segun su tipo se le podria asignar una instancia de la regla adecuada. La asociacion de un tipo de barco a una regla podria estar guardada en la base de datos.
De esta forma no tendrias que repetir el codigo de las reglas y lo reutilizarias.

En el metodo de mover del barco (en la clase base) llamarias al metodo aplicar del objeto regla especial. De esta forma el codigo te queda generico e iria todo en la clase base o padre del barco. Como cada barco tendra su objeto regla especial diferente realizaran las acciones que correspondan.
Mi web: http://www.brausoft.com/
No sabían que era imposible, así que lo hicieron.

MartinCalveira

mvelazquezm:

Me equivoqué con el nombre, me faltó una palabra, el nombre es "O'Reilly 2004 Head First Design Patterns.pdf" Está en inglés pero es muy práctico y entendible porque las explicaciones la realizan con diagramas y figuras.
Muy bueno el libro lo recomiendo.

Saludos

Martín






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.