Juego HTML5 (Canvas): ¿Técnicas de IU?

23

Estoy en el proceso de crear un juego JavaScript / HTML5 (usando Canvas) para dispositivos móviles (Android / iPhone / WebOS) con PhoneGap. Actualmente estoy tratando de diseñar cómo se debe construir la interfaz de usuario y el tablero de juego y cómo deben interactuar, pero no estoy seguro de cuál es la mejor solución. Esto es lo que puedo pensar:

Cree la interfaz de usuario directamente en el lienzo utilizando elementos como drawImage y fillText Cree partes de la interfaz de usuario fuera del lienzo utilizando objetos DOM regulares y luego flote un div sobre el lienzo cuando los elementos de la interfaz de usuario necesiten superponerse al lienzo del tablero de juego. ¿Hay alguna otra técnica posible que pueda usar para construir la interfaz de usuario del juego que no haya pensado? Además, ¿cuál de estos se consideraría la forma "estándar" (sé que los juegos HTML5 no son muy populares, por lo que probablemente todavía no haya una forma "estándar")? Y finalmente, ¿de qué manera recomendarías / usarías?

¡Muchas gracias de antemano!

Jason L.
fuente
Tenga en cuenta que Canvas aún no es compatible con IE (IE9 supuestamente lo hará) ... por lo que elimina una gran cuota de mercado para su juego. Hay un parche de JavaScript que intenta que funcione en IE, pero no funciona bien (LENTO como el infierno ... no vale la pena).
1
@Adam - Ver flashcanvas: flashcanvas.net
ehsanul
Utilizo elementos dom como gui, múltiples divisiones flotantes como "ventanas" con una ventana que contiene un elemento de lienzo (juego real). Y siempre existe esta opción: developer.mozilla.org/en-US/docs/HTML/Canvas/… :)
Kikaimaru

Respuestas:

18

Ambas soluciones (dibujar en su lienzo VS. HTML / CSS tradicional) son totalmente válidas y funcionarán bien. Algunas cosas a considerar:

  • Si ya está utilizando una biblioteca basada en lienzo, su código puede estar más limpio / organizado si continúa utilizando el lienzo en lugar de tener métodos adicionales (basados ​​en DOM) para la IU.
  • Si su interfaz de usuario es extremadamente pesada en texto (con diálogos, etc.), entonces puede ser más simple de implementar a través de HTML / CSS. Por ejemplo, es bastante trivial que el texto fluya en un elemento DOM (con elementos como el ajuste y el espacio entre párrafos) y comparativamente difícil de implementar en el lienzo.
  • Dependiendo en gran medida de la biblioteca que esté utilizando, podría ser mucho más fácil implementar el manejo de clics en elementos DOM que dentro de su lienzo. Por ejemplo, si desea detectar un clic en un botón "Aceptar", esa es una tarea trivial en el mundo HTML / JS. Pero en el lienzo necesitaría escuchar el clic en un elemento diferente y verificar sus coordenadas para ver dónde se realizó el clic.
  • Algunos agentes de usuario (especialmente dispositivos móviles) pueden ser difíciles al usar elementos DOM que contienen texto. Por ejemplo, Mobile Safari puede querer abrir un modal con las herramientas para copiar / pegar. La prevención de este comportamiento podría ser difícil y probablemente sería más fácil en el terreno del lienzo.

Algo de esto será subjetivo; un desarrollador que conozco siempre prefiere usar el lienzo, ya que considera que DOM es feo y detallado. Dado que cualquiera de las soluciones funcionará bien, elegiría una sola pantalla simple en su aplicación, la desarrollaría rápidamente por separado utilizando ambos métodos y vería cuál se siente más fácil / mejor.

¡La mejor de las suertes!

richtaur
fuente
¡Gracias por su respuesta! Muy buenos puntos. De hecho, estoy construyendo mi propio motor en este momento. Lo comencé a usar Canvas pero lo modificará un poco para probar CSS3 / WebKit. La única razón por la que estoy construyendo la mía es porque el juego es demasiado "simple" para un motor "real". Ni siquiera tenemos un bucle principal del juego. La única razón por la que incluso existe es para la animación, pero teniendo en cuenta la frecuencia con la que ocurren, probablemente podríamos simplemente iniciar / detener los temporizadores según sea necesario :)
Jason L.
5

He estado usando easeljs para mi interacción con el lienzo.

Es bastante bueno y facilita un diseño sólido. Una de las características clave que me hizo elegirlo fue la posibilidad de sincronizar la posición de sus objetos de lienzo y elementos dom.

Esto facilita hacer burbujas de discurso CSS y elementos de interfaz de usuario estáticos como el marco del hud y ese tipo de cosas.

La ventaja que esto tiene para los navegadores es que obtienes el lienzo rico pero puedes empeñar las cosas más pequeñas y estáticas en el dom para mantener el rendimiento bajo control.

G. Davids
fuente
4

El lienzo es lento en las plataformas móviles, al menos el safari móvil lo es de todos modos, por lo que querrá usar el posicionamiento de objetos basado en CSS en esos. Utilice específicamente "translate3d" que activará la representación de objetos acelerada por hardware.

Echa un vistazo a la biblioteca CAAT para el lienzo, sin embargo, es rápido y puedes usar "actores" respaldados por CSS y no cambiar la lógica del juego.

Todavía no puedo publicar enlaces, pero aquí hay algunos pseudo enlaces http://labs.hyperandroid.com/animation

onedayitwillmake
fuente
Creo que el enlace del repositorio en la página de CAAT apunta al anterior, ¡así que asegúrese de usar este en su lugar! repo: github.com/hyperandroid/CAAT
onedayitwillmake
(lo siento, solo puedo agregar un enlace por publicación actualmente) Aquí hay una demostración que creé que contiene una plantilla de hello-world para CAAT - onedayitwillmake.com/CAATCirclePack
onedayitwillmake
Gracias por los enlaces, def. Echale un vistazo. He oído rumores de que Canvas es lento, pero soy de los que generalmente tiene que ver las cosas por sí mismo :) También debo tener en cuenta que el juego que estoy creando es MUY ligero en las animaciones. Nunca más de uno o dos corriendo al mismo tiempo y en intervalos de una vez cada 5-10 segundos durante un minuto a la vez. Nada loco Además, para verificar, ¿sugiere no usar Canvas en absoluto, sino usar objetos DOM viejos y simples con CSS / translate3d?
Jason L.
Para ser honesto, no puedo decir para su escenario específico o no. Sin embargo, si desea apuntar a un safari móvil específicamente, entonces, sí, querría usar CSS con divs. Es muy rápido en hacer eso comparado redibujando el lienzo desde mi experiencia. Pude obtener fácilmente 45 sprites basados ​​en imágenes moviéndose a 30FPS usando 'translate3d' para moverlos a su lugar. Asegúrese de colocar esto en el CSS para los objetos que planea mover con 'transform3d', de lo contrario, webkit animará esos objetos donde se especifique en lugar de colocarlos. -webkit-transition: transform3d 0s lineal;
onedayitwillmake
2

Tengo que estar de acuerdo sobre la lentitud del lienzo en el iPhone 4. Bastante seguro de que el lienzo de safari no está respaldado por GL. Mi descarado juego funciona rápido en iPhone 3GS y Android, pero en iPhone 4 creo que la pantalla retina tiene demasiados píxeles, o si el lienzo no se monta en GL, esto explicaría por qué se arrastra. Me gusta el modelo de desarrollo del lienzo, todavía no he probado la opción css translate3d. En particular, utilicé GWT y el gwt-g2d canvas wrapper (optimización / ofuscación). http://www.photonjunky.com/shootout.html


fuente
1

Sugeriría mantener sus controles como elementos html como menuy commandpor razones de accesibilidad. Usando un poco de CSS, puede mostrar elementos sobre un lienzo y no perder la funcionalidad preconstruida de HTML.

zzzzBov
fuente
1

Sé que esta es una vieja pregunta, pero hoy (marzo de 2013) lo sabemos mejor. Decidí responder en caso de que alguien más tropezara aquí como yo. Tengo que estar en desacuerdo con la mayoría de las otras respuestas. Probablemente sean válidos para el desarrollo del navegador web, pero no para dispositivos móviles. Hace una gran diferencia qué ruta elegir (DOM o animación de lienzo). La vista web de Android es completamente inútil (lenta, tartamudeante) en sí misma, lo que hace que Phonegap sea inútil para el desarrollo de juegos de Android, a menos que pueda aplicar la aceleración de hardware, que actualmente solo es posible usando animación de lienzo y un marco adecuado. Para más información, vea esta respuesta .

Por Quested Aronsson
fuente
0

Puedes hacerlo de mil maneras. Sin embargo, se siente más cómodo y sus ingenieros se sienten más seguros.

Si está buscando inspiración o un ejemplo de código, aquí hay una manera de hacerlo. Tengo una función que dibuja repetidamente un menú hasta que se presiona un botón. Cuando se presiona el botón, se carga el juego y se eliminan los antiguos oyentes de eventos de clic de menú y se agregan nuevos oyentes de eventos de clic de juego. También finalizo el antiguo ciclo de extracción del menú y comienzo un nuevo ciclo de extracción del juego. Aquí hay algunos fragmentos seleccionados para darle una idea de cómo se hace:

Game.prototype.loadMenu = function() {
  var game = this;
  var can = this.canvas;

  // now we can use the mouse for the menu
  can.addEventListener('click', game.menuClickEvent, false);
  can.addEventListener('touchstart', game.menuClickEvent, false);

  // draw menu
  this.loop = setInterval(function() { game.drawMenu() }, 30);
};

Game.prototype.drawMenu = function() {
  // ... draw the menu
}

Game.prototype.loadLevel = function(levelstring) {
  // unload menu
  var can = this.canvas;
  var game = this;
  can.removeEventListener('click', game.menuClickEvent, false);
  can.removeEventListener('touchstart', game.menuClickEvent, false);

  if (this.loop) clearInterval(this.loop);

  // ... other level init stuff


  // now we can press keys for the game
  //can.addEventListener('click', game.gameClickEvent, false);
  can.addEventListener('touchstart', game.gameClickEvent, false);
  can.addEventListener('keydown', game.gameKeyDownEvent, false);

  this.loop = setInterval(function() { game.tick() }, 30);
}

// called from tick()
Game.prototype.draw = function(advanceFrame) {
  // ...
}

De esta manera, puedo separar el dibujo del juego y los eventos del juego del dibujo del menú y los eventos del menú. También me da margen para usar elementos de juego / animación en mis menús si quiero que se vean realmente bonitos.

Simon Sarris
fuente