2009-02-26 14 views
6

Editar: Esto tiene mucho más sentido para mí ahora que me he alejado un paso del código, gracias por la ayuda.Gameloop para j2me juego "por turnos"

Acabo de encontrar desbordamiento de pila el otro día a través de Coding Horror y se ve increíble. Me imagino que le preguntaría a la comunidad sobre un problema que estoy tratando de resolver.

Estoy desarrollando un juego de sortilegios roguelike usando j2me para teléfonos midp 2.0. El proyecto aún se encuentra en las etapas básicas de desarrollo a medida que descubro cómo funcionará. La parte en la que estoy estancado actualmente tiene que ver con enhebrar.

El juego tiene una clase personalizada HaxCanvas que extiende GameCanvas e implementa ejecutable. El método de ejecución llama a repaint() y luego duerme durante 50 ms, lo que da como resultado una velocidad de fotogramas de 20 FPS. Esto me permite escribir el resto del juego sin tener que volver a pintar en todas partes y hacer las animaciones y los efectos más fáciles de hacer más adelante. (al menos en teoría).

El flujo del juego está controlado por una clase GameManager, que recorre todos los NPC del mapa, tomando su turno, hasta que es el turno del jugador. En este punto, necesito obtener información para permitir al jugador moverse y/o atacar cosas. Originalmente estaba llamando al gameManager.runUntilHeroTurn() en el método keyPressed de mi HaxCanvas. Sin embargo, después de leer los hilos del sistema j2me, me di cuenta de que poner un método con el potencial de funcionar durante un tiempo en una devolución de llamada es una mala idea. Sin embargo, debo utilizar keyPressed para hacer la entrada de datos, ya que necesito acceso a las teclas numéricas, y getKeyStates() no es compatible con esto.

Sofar mis intentos de poner mi Gameloop en su propio hilo han provocado un desastre. Aparece una extraña "ArrayIndexOutOfBoundsException" no registrada sin ningún rastro de pila después de que el juego se haya ejecutado durante varios turnos.

Así que supongo que mi pregunta es la siguiente:

Para un "basado en turnos" juego en J2ME, ¿cuál es la mejor manera de implementar el bucle del juego, lo que permite la entrada handeling sólo cuando es el turno del jugador?

+0

Por cierto, buena pregunta. +1 – Fostah

Respuesta

3

Evitaría enhebrar la lógica del juego ya que el enhebrado J2ME, dependiendo del fabricante, por supuesto, no hace un buen trabajo al compartir los recursos limitados. A menudo verá pausas mientras un hilo realiza un procesamiento pesado. Solo recomendaría los subprocesos para cargar o las características de conectividad de red, ya que en este caso solo le dará al usuario los comentarios básicos de "Cargando ...".

Para manejar esto, no tendría sub-bucles para actualizar cada uno de los AI en un marco.Me gustaría hacer algo como siguiente en la función de ejecución:

public void run() { 
    while(true) { 
     // Update the Game 
     if(gameManager.isUsersTurn()) { 
      // Collect User Input 
      // Process User Input 
      // Update User's State 
     } 
     else { 
      // Update the active NPC based on their current state 
      gameManager.updateCurrentNPC(); 
     } 

     // Do your drawing 
    } 
} 

se quiere evitar tener todo actualizado en un marco como 1) la actualización podría ser lento, lo que no hay una respuesta visual inmediata para el usuario 2) que pueda No anime a cada PNJ individual mientras hacen su acción. Con esta configuración, puede tener estados NPC, NPC_DECIDE_MOVE y NPC_ANIMATING, que le permitan un mayor control de lo que está haciendo el NPC. NPC_ANIMATING básicamente pondría el juego en estado de espera para que la animación tenga lugar, evitando cualquier procesamiento adicional hasta que la animación se complete. Luego podría pasar al siguiente turno de NPC.

Además, me gustaría tener un gameManager.update() y gameManager.paint (g) (la pintura se llamará desde la pintura) que manejaría todo y mantendría el método de ejecución delgado.

Finalmente, ¿miró en flushGraphics()? Con GameCanvas generalmente creas un objeto Graphics, dibujas todo a eso y luego llamas a flushGraphics(), luego esperas. El método que mencionas es la forma de abordarlo para la clase Canvas. Solo pensé en mencionar esto y publicar un enlace: Game Canvas Basics

5

Aunque no específicamente j2me, debe capturar la entrada del usuario, la estrategia general es ponerla en cola hasta que llegue el momento de procesar la entrada.

input ---> queue <---> Manager(loop) 

De esta manera, incluso puede escribir la entrada de scripts para depuración.

Así que no necesita un hilo nuevo. Cada vez que el usuario presiona la tecla, la almacena en un búfer y luego procesa el contenido del búfer cuando sea necesario. Si el buffer del jugador no tiene entrada, el manager debe omitir todo el juego, hacer animaciones y luego comenzar de nuevo (ya que el juego no es un juego de acción).