Jeu HTML5 (Canvas) - Techniques d'interface utilisateur?

23

Je suis en train de construire un jeu JavaScript / HTML5 (utilisant Canvas) pour mobile (Android / iPhone / WebOS) avec PhoneGap. J'essaie actuellement de concevoir comment l'interface utilisateur et le plateau de jeu devraient être construits et comment ils devraient interagir, mais je ne suis pas sûr de la meilleure solution. Voici ce que je peux penser -

Créez l'interface utilisateur directement dans le canevas à l'aide de choses comme drawImage et fillText Créez des parties de l'interface utilisateur en dehors du canevas à l'aide d'objets DOM normaux, puis faites flotter un div sur le canevas lorsque les éléments d'interface utilisateur doivent chevaucher le canevas de la carte de jeu. Y a-t-il d'autres techniques possibles que je peux utiliser pour créer l'interface utilisateur du jeu auxquelles je n'ai pas pensé? De plus, lequel d'entre eux serait considéré comme la méthode "standard" (je sais que les jeux HTML5 ne sont pas très populaires, il n'y a donc probablement pas encore de méthode "standard")? Et enfin, quelle voie recommanderiez-vous / utiliseriez-vous?

Merci d'avance!

Jason L.
la source
Gardez à l'esprit que Canvas n'est pas encore pris en charge dans IE (IE9 le serait prétendument) ... ce qui supprime une énorme part de marché pour votre jeu. Il existe un correctif javascript qui tente de le faire fonctionner dans IE, mais il ne fonctionne pas bien (lent comme l'enfer ... ne vaut pas la peine).
1
@Adam - Voir flashcanvas: flashcanvas.net
ehsanul
J'utilise des éléments dom comme gui, plusieurs divs flottants comme "windows" avec une fenêtre contenant un élément canvas (jeu réel). Et il y a toujours cette option: developer.mozilla.org/en-US/docs/HTML/Canvas/… :)
Kikaimaru

Réponses:

18

Les deux solutions (dessin sur votre toile VS HTML / CSS traditionnel) sont totalement valides et fonctionneront très bien. Quelques points à considérer:

  • Si vous utilisez déjà une bibliothèque basée sur canevas, votre code peut être plus propre / plus organisé en continuant à utiliser canevas au lieu d'avoir des méthodes supplémentaires (basées sur DOM) pour l'interface utilisateur.
  • Si votre interface utilisateur est extrêmement lourde en texte (avec des boîtes de dialogue, etc.), il peut être plus simple à mettre en œuvre via HTML / CSS. Par exemple, il est assez trivial que le texte circule dans un élément DOM (avec des choses comme l'habillage et l'espacement des paragraphes) et relativement difficile à implémenter dans le canevas.
  • Selon la bibliothèque que vous utilisez, il pourrait être beaucoup plus facile d'implémenter la gestion des clics sur les éléments DOM que dans votre canevas. Par exemple, si vous voulez détecter un clic sur un bouton "Ok", c'est une tâche banale dans le monde HTML / JS. Mais dans le canevas, vous devez écouter le clic sur un élément différent et vérifier ses coordonnées pour voir où le clic a eu lieu.
  • Certains agents utilisateurs (en particulier les appareils mobiles) peuvent être délicats lors de l'utilisation d'éléments DOM contenant du texte. Par exemple, Mobile Safari peut vouloir faire apparaître un modal avec les outils pour copier / coller. La prévention de ce comportement peut être difficile et serait probablement plus facile en zone de canevas.

Certains de ces éléments seront subjectifs; un développeur que je connais préfère toujours utiliser canvas car il trouve juste que DOM est laid et verbeux. Étant donné que l'une ou l'autre solution fonctionnera bien, je choisirais un simple écran unique dans votre application, je la développerais rapidement séparément en utilisant les deux méthodes et je verrais laquelle est la plus facile / meilleure.

Bonne chance!

richtaur
la source
Merci pour votre réponse! Très bons points. Je construis actuellement mon propre moteur. J'ai commencé avec Canvas mais je vais le modifier un peu pour tester des trucs CSS3 / WebKit. La seule raison pour laquelle je construis le mien est parce que le jeu est trop «simple» pour un «vrai» moteur. Nous n'avons même pas vraiment de boucle de jeu principale. La seule raison pour laquelle il y en a même est pour l'animation, mais compte tenu de la fréquence à laquelle cela se produit, nous pourrions probablement démarrer / arrêter les minuteries au besoin :)
Jason L.
5

J'utilise easeljs pour mon interaction avec le canevas.

C'est assez bon et facilite une conception solide. L'une des principales caractéristiques qui m'a fait choisir c'est la possibilité de synchroniser la position de vos objets de canevas et éléments dom.

Cela facilite la création de bulles de style CSS et d'éléments d'interface utilisateur statiques comme le cadre hud et ce genre de chose.

L'avantage que cela présente pour les navigateurs est que vous obtenez le canevas riche, mais vous pouvez mettre en gage les choses plus petites et statiques dans le dom pour garder les performances sous contrôle.

G. Davids
la source
4

Canvas est lent sur les plates-formes mobiles, au moins le safari mobile est de toute façon, vous voudrez donc utiliser le positionnement CSS des objets sur ceux-ci. Utilisez spécifiquement "translate3d" qui activera le rendu accéléré du matériel des objets.

Consultez la bibliothèque CAAT pour le canevas, c'est rapide et vous pouvez utiliser des "acteurs" soutenus par CSS et ne pas changer la logique du jeu.

Je ne peux pas encore poster de liens mais voici quelques pseudo liens http://labs.hyperandroid.com/animation

onedayitwillmake
la source
Je pense que le lien de dépôt sur la page des CAAT pointe vers l'ancien, alors assurez-vous d'utiliser celui-ci à la place! repo: github.com/hyperandroid/CAAT
onedayitwillmake
(désolé je ne peux ajouter un lien par poste actuellement) est ici une démonstration que j'ai créé qui contient un modèle bonjour-monde pour CAAT - onedayitwillmake.com/CAATCirclePack
onedayitwillmake
Merci pour les liens, je vais def. Vérifiez-le. J'ai entendu des rumeurs selon lesquelles Canvas était lent mais je suis généralement celui qui doit voir les choses lui-même :) Je dois également noter que le jeu que je crée est TRÈS léger sur les animations. Jamais plus d'un ou deux fonctionnant en même temps et à des intervalles d'une fois toutes les 5 à 10 secondes pendant une minute à la fois. Rien de fou. De plus, pour vérifier, suggérez-vous de ne pas utiliser Canvas du tout, mais d'utiliser de vieux objets DOM simples avec CSS / translate3d?
Jason L.
Pour être honnête, je ne peux pas dire pour votre scénario spécifique ou non. Cependant, si vous souhaitez cibler le safari mobile de manière spécifique, alors imo ouais, vous voudriez utiliser CSS avec des divs. C'est très rapide à faire par rapport à redessiner la toile de mon expérience. J'ai pu facilement déplacer 45 sprites basés sur des images à 30 images par seconde en utilisant 'translate3d' pour les déplacer en place. Assurez-vous de placer cela dans le CSS pour les objets que vous prévoyez de déplacer avec 'transform3d', sinon webkit animera ces objets là où spécifié au lieu de les placer. -webkit-transition: transform3d 0s linéaire;
onedayitwillmake
2

Je dois être d'accord sur la lenteur du canevas sur l'iPhone 4. Je suis presque sûr que le canevas safari n'est pas soutenu par GL. Mon jeu effrayant fonctionne rapidement sur iPhone 3GS et Android, mais sur iPhone 4, je pense que l'affichage de la rétine a trop de pixels, ou si la toile ne roule pas sur GL, cela expliquerait pourquoi elle traîne. J'aime le modèle de développement canvas, je n'ai pas encore essayé l'option css translate3d. En particulier, j'ai utilisé GWT et le wrapper de toile gwt-g2d (optimisation / obscurcissement). http://www.photonjunky.com/shootout.html


la source
1

Je suggère de conserver vos contrôles en tant qu'éléments html tels que menuet commandpour des raisons d'accessibilité. En utilisant un peu de CSS, vous pouvez afficher des éléments sur un canevas et ne pas perdre la fonctionnalité prédéfinie de HTML.

zzzzBov
la source
1

Je sais que c'est une vieille question, mais aujourd'hui (mars 2013) nous savons mieux. J'ai décidé de répondre au cas où quelqu'un d'autre tomberait ici comme moi. Je dois être en désaccord avec la plupart des autres réponses. Ils sont probablement valables pour le développement de navigateurs Web, mais pas pour les mobiles. Cela fait une grande différence quel chemin vous choisissez (DOM ou animation de canevas). La vue Web Android est complètement inutile (lente, bégaiement) en soi, ce qui rend Phonegap inutile pour le développement de jeux Android, à moins que vous ne puissiez appliquer une accélération matérielle, qui n'est actuellement possible qu'en utilisant une animation de canevas et un cadre approprié. Pour plus d'informations, consultez cette réponse .

Par Aronsson interrogé
la source
0

Vous pouvez le faire de mille façons. Cependant, vous vous sentez plus à l'aise et vos ingénieurs se sentent plus confiants.

Si vous cherchez de l'inspiration ou un exemple de code, voici une façon de le faire. J'ai une fonction qui dessine à plusieurs reprises un menu jusqu'à ce qu'un bouton soit enfoncé. Lorsque le bouton est enfoncé, le jeu se charge et les anciens écouteurs d'événements de clic de menu sont supprimés et de nouveaux écouteurs d'événements de clic de jeu sont ajoutés. Je termine également l'ancienne boucle de tirage du menu et commence une nouvelle boucle de tirage de jeu. Voici quelques extraits sélectionnés pour vous donner une idée de la façon dont cela se fait:

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 cette façon, je peux séparer le dessin du jeu et les événements du jeu du dessin du menu et des événements du menu. Cela me donne également une marge de manœuvre pour utiliser des éléments de jeu / d'animation dans mes menus si je veux les rendre vraiment jolis.

Simon Sarris
la source