Partager via


Cet article a fait l'objet d'une traduction automatique.

Développement de jeux

Les Techniques de dessin 2D et de bibliothèques pour les jeux Web

Michael Oneppo

Pendant longtemps, il n'y avait vraiment qu'une seule façon de faire inter­jeux Web actifs : Flash. Le veuille ou pas, Flash a un système de tirage rapide. Tout le monde il utilisé pour créer des animations, des aventures de pointer-cliquer et toutes sortes d'autres expériences.

Lorsque les navigateurs alignement sur les standards du Web HTML5, il y avait une véritable explosion des options pour le développement rapide et qualité graphique — sans avoir besoin de plug-ins. Cet article présente un petit échantillon de méthodes de dessin, ainsi que les technologies sous-jacentes et certaines bibliothèques pour ce qui les rend plus faciles à utiliser. Je ne couvrir bibliothèques spécifiquement destinés aux jeux. Il y a tant de ceux que je vais enregistrer ce débat pour un autre article.

Normes de dessin

Avec l'arrivée de HTML5, trois méthodes classiques pour dessiner en 2D ont émergé : le fournisseur de services Internet (DOM, Document Object Model), la toile et le format Scalable Vector Graphics (SVG). Avant de sauter dans l'enquête sur les bibliothèques qui utilisent ces technologies, je vais passer en revue comment chacun travaille afin de mieux comprendre les compromis de chaque méthode.

Sans surprise, la façon la plus élémentaire pour dessiner des graphiques au format HTML est en effet avec HTML. En créant un certain nombre d'éléments d'arrière-plan ou l'image et à l'aide d'une bibliothèque comme jQuery, vous pouvez rapidement faire des sprites, que vous pouvez vous déplacer sans redessiner la scène. Le navigateur le fera pour vous. Ce type de structure est souvent appelé un graphe de scène. Dans le cas de l'HTML, le graphe de scène est le DOM. Parce que vous allez utiliser CSS pour coiffer vos sprites, vous pouvez également utiliser CSS transitions et des animations pour animer certains lisse votre scène.

La question clé avec cette méthode, c'est qu'il est dépendant sur le moteur de rendu de DOM. Cela peut ralentir les choses vers le bas lorsque vous avez une scène complexe. Je ne recommanderais pas l'utilisation de plusieurs éléments de centaines. Si quelque chose de plus complexe qu'un match-trois ou un jeu de plateforme pourrait avoir des problèmes de performances. Et une soudaine augmentation du nombre d'éléments, comme dans un système de particules, peut causer le hoquet dans l'animation.

Un autre problème avec cette méthode est que vous devez utiliser CSS à des éléments de style. Selon la façon dont vous écrivez CSS, il peut être décemment rapide ou très lent. Enfin, écrivez du code visé pour HTML peut être difficile de passer à un autre système, comme le code C++ natif. Ceci est important si vous voulez transférer votre jeu à quelque chose comme une console. Voici un résumé des pros :

  • S'appuie sur la structure de base d'une page Web
  • jQuery et autres bibliothèques le rendent facile à faire bouger les choses
  • Sprites sont relativement faciles à mettre en place
  • Système d'animation intégré avec CSS transitions et des animations

Ainsi qu'un résumé de la cons :

  • De nombreux petits éléments peuvent vous ralentir
  • Il faut faire de la CSS à des éléments de style
  • Aucune des images vectorielles
  • Peut être difficile de portage vers d'autres plates-formes

HTML5 Canvas

L'élément canvas traite beaucoup de la cons. Il fournit un environnement de mode immédiat rendu — une plate bande de pixels. Vous lui dire ce qu'il faut dessiner en JavaScript, et il attire immédiatement. Parce que c'est de convertir vos commandes de dessin aux pixels, vous pouvez rapidement empilent une longue liste de commandes de dessin sans enlisement du système. Vous pouvez dessiner la géométrie, les textes, les images, les dégradés et les autres éléments. Pour lire plus d'informations sur toile pour les jeux, consultez article de David Catuhe à bit.ly/1fquBuo.

Alors, quel est l'inconvénient ? Parce que la toile oublie ce qu'il a tiré au moment où qu'il l'a fait, il faut redessiner la scène chaque fois que vous voulez pour changer. Et si vous souhaitez modifier une forme de manière complexe, comme la flexion ou l'animation, vous devez effectuer les calculs et redessiner l'élément. Cela signifie que vous devez maintenir un grand nombre de données sur votre scène dans vos propres structures de données. Ce n'est pas vraiment une affaire énorme, vu il y a les bibliothèques que vous faciliter la tâche. Si vous voulez vraiment faire quelque chose de personnalisé, sachez que la toile ne conserve pas d'informations pour vous. Enfin, toile n'inclut pas animations. Vous devez dessiner votre scène en étapes successives pour faire une animation fluide. Voici un résumé des pros :

  • Dessine directement — scènes peuvent s'avérer plus complexes
  • Prend en charge beaucoup de différents éléments visuels

Ainsi qu'un résumé de la cons :

  • Aucune mémoire inhérente de la scène ; vous devez construire vous-même
  • Complexe transforme et animations doivent se faire manuellement
  • Aucun système d'animation

SVG : Scalable Vector Graphics

Comme un balisage basé sur XML pour décrire les effets visuels 2D, SVG est similaire à HTML. La différence essentielle est que SVG est destinée au dessin, tandis que le HTML est principalement conçu pour du texte et de mise en page. Par conséquent, SVG a quelques possibilités de dessin puissantes telles que des formes lisses, des animations complexes, déformations et même les filtres d'image comme flou. Comme le langage HTML, SVG a une structure de graphe de scène, donc vous pouvez prendre connaissance des éléments SVG, ajouter des formes, modifier leurs propriétés et ne pas s'inquiéter tout redessiner. Le navigateur le fera pour vous. La vidéo, « Travailler avec SVG en HTML5, » de Channel 9 (bit.ly/1DEAWmh) en dit plus.

Comme le langage HTML, des scènes complexes peuvent enliser SVG. SVG peut gérer une complexité, mais il ne peut pas correspondre tout à fait la complexité offerte à l'aide de la toile. En outre, les outils de manipulation de SVG peuvent être complexes, bien qu'il existe d'autres outils pour simplifier le processus. Voici un résumé des pros :

  • Nombreuses options de dessin comme surfaces courbes et des formes complexes
  • Structuré sans avoir à redessiner

Ainsi qu'un résumé de la cons :

  • Complexité il peut enliser
  • Difficile à manipuler

Bibliothèques de dessin 2D

Maintenant que vous savez sur les normes disponibles pour dessiner sur le Web, je vais jeter un oeil à certaines bibliothèques qui peuvent faciliter votre dessin et l'animation. Il est à noter que rarement tirez-vous sans faire autre chose avec le dessin. Par exemple, vous avez souvent besoin de graphiques de réagir à l'entrée. Les bibliothèques aident à faire les tâches courantes associées à dessin plus facile.

KineticJS veux un graphe de scène pour la toile ? KineticJS est une bibliothèque de toile extrêmement puissant qui commence par un graphe de scène et ajoute plus de fonctionnalités. Au niveau de la base, KineticJS vous permet de définir les couches dans la toile qui contiennent des formes dessiner. Par exemple, Figure 1 montre comment dessiner un cercle rouge simple à l'aide de KineticJS.

Figure 1 tracé un cercle avec KineticJS

// Points to a canvas element in your HTML with id "myCanvas"
var myCanvas = $('#myCanvas'); 
var stage = new Kinetic.Stage({
  // get(0) returns the first element found by jQuery,
  // which should be the only canvas element
  container: myCanvas.get(0),
    width: 800,
    height: 500
  });
   
var myLayer = new Kinetic.Layer({id: “myLayer”});
stage.add(myLayer);
var circle = new Kinetic.Ellipse({
  // Set the position of the circle
  x: 100,                                            
  y: 100,
   
  // Set the size of the circle
  radius: {x: 200, y: 200},
   
  // Set the color to red
  fill: '#FF0000'  
});
 
myLayer.add(circle);
stage.draw();

Vous aurez besoin d'appeler la ligne finale de Figure 1 chaque fois que vous voulez la scène de redessiner. KineticJS fera le reste en se souvenant de la disposition de la scène et s'assurer tout est dessiné correctement.

Il y a des choses intéressantes dans les KineticJS qui le rendent très puissant. Par exemple, la propriété fill d'un objet peut être un certain nombre de choses, y compris un dégradé :

fill: {
  start: {x: 0, y: 0},
  end: {x: 0, y: 200},
  colorStops: [0, '#FF0000', 1, '#00FF00']
},

Ou une image :

// The "Image" object is built into JavaScript and
// Kinetic knows how to use it
fillPatternImage: new Image('path/to/an/awesome/image.png'),

KineticJS a un système d'animation, de plus, qui vous permet de déplacer des choses, en créant un objet d'Animation ou en utilisant un objet Tween à propriétés de transition sur les formes dans votre scène. La figure 2 montre les deux types d'animations.

Figure 2 Animations à l'aide de KineticJS

// Slowly move the circle to the right forever
var myAnimation = new Kinetic.Animation(
  function(frame) {
    circle.setX(myCircle.getX() + 1);
  },
  myLayer);
 
// The animation can be started and stopped whenever
myAnimation.start();
// Increase the size of the circle by 3x over 3 seconds
var myTween = new Kinetic.Tween({
  node: circle,
  duration: 3,
  scaleX: 3.0,
  scaleY: 3.0
});
 
// You also have to initiate tweens
myTween.play();

KineticJS est puissant et largement utilisé, surtout pour les jeux. Découvrez le code, l'échantillons et la documentation à kineticjs.com.

Paper.js Paper.js fournit plus qu'une bibliothèque pour simplifier le dessin de la toile. Il fournit une version légèrement modifiée de JavaScript appelée PaperScript pour simplifier les tâches de dessin communs. Lorsque vous incluez PaperScript dans votre projet, un lien vers elle comme vous le feriez un script ordinaire, juste avec un autre type de code :

<script type=“text/paperscript" src=“mypaperscript.js”>

Cela permet Paper.js d'interpréter le code un peu différemment. Il y a vraiment que deux morceaux pour cela. Tout d'abord, PaperScript a deux objets intégrés appelés Point et Size. PaperScript inclut ces objets d'usage courant dans ses fonctions et offre la possibilité de directement additionner, soustraire et multiplier ces types. Par exemple, pour déplacer un objet PaperScript, vous pourriez faire ceci :

var offset = new Point(10, 10);
 
var myCircle = new Path.Circle({
  center: new Point(300, 300),
  radius: 60
});
 
// Direct addition of Point objects!
myCircle.position += offset;

La deuxième chose que Paper.js interprète différemment répond aux événements. Considérez que vous écrivez le code suivant en JavaScript :

function onMouseDown(event) {
  alert("Hello!");
}

Cela ne fera rien parce que la fonction n'est pas liée aux événements de n'importe quel élément. Cependant, comment écrire le code même en PaperScript, Paper.js détectera automatiquement cette fonction et liez-le à l'événement de souris appuyée. En savoir plus sur le sujet à paperjs.org.

Fabric.js Fabric.js est une bibliothèque de toile dispositif-emballée, avec la possibilité de mélanger un certain nombre d'effets avancés et formes dans une page Web sans beaucoup de code. Quelques caractéristiques notables incluent des filtres d'image comme la suppression de l'arrière-plan, des classes personnalisées pour faire vos propres objets composés et soutien "gratuit dessin" où vous pouvez dessiner juste sur la toile dans un certain nombre de styles. Fabric.js est similaire à KineticJS, dans lequel il a un graphe de scène, sauf avec une structure plus concise, certaines personnes préfèrent. Par exemple, vous ne devez jamais redessiner la scène :

var canvas = new fabric.Canvas('myCanvas');
var circle = new fabric.Circle({
  radius: 200,
    fill: '#FF0000',
    left: 100,
    top: 100
});
 
// The circle will become immediately visible
canvas.add(circle);

Ce n'est pas une énorme différence, mais Fabric.js fournit des contrôles de rendu à grain fin qui mélangent le rafraîchissement automatique et manuel redessiner. Pour donner un exemple, amplifier un cercle en Fabric.js ressemble à ceci :

circle.animate(
  // Property to animate
  'scale',
  // Amount to change it to
  3,
  {
    // Time to animate in milliseconds
    duration: 3000,
    // What's this?
    onChange: canvas.renderAll.bind(canvas)
  });

Lorsque l'animation quelque chose dans Fabric.js, vous devez lui dire quoi faire lorsqu'il modifie une valeur. Pour l'essentiel, vous le voulez pour redessiner la scène. C'est ce que canvas.renderAll.bind(canvas) fait référence. Ce code retourne une fonction qui restitue toute la scène. Si vous êtes animer un grand nombre d'objets de cette façon, cependant, la scène serait inutilement redessiner une fois pour chaque objet. Au lieu de cela, vous pouvez supprimer de redessiner toute la scène et redessiner les animations vous-même. Figure 3 illustre cette approche.

Figure 3 plus serré redessiner le contrôle en Fabric.js

var needRedraw = true;
 
// Do things like this a lot, say hundreds of times
circle.animate(
  'scale',
  3,
  {
    duration: 3000,
       
    // This function will be called when the animation is complete
    onComplete: function() {
      needRedraw = false;
    }
  });
 
// This function will redraw the whole scene, and schedule the
// next redraw only if there are animations going
function drawAnimations() {
  canvas.renderAll();
  if (needRedraw) {
    requestAnimationFrame(drawAnimations);
  }
}
 
// Now draw the scene to show the animations
requestAnimationFrame(drawAnimations);

Fabric.js fournit beaucoup de personnalisation, vous pouvez optimiser votre dessin uniquement lorsque vous devez. Pour certains, qui peuvent être difficiles à gérer. Pour de nombreux jeux complexes, cependant, cela peut être une caractéristique essentielle. Découvrez plus à fabricjs.com.

Raphaël Raphaël est une utile bibliothèque SVG qui élimine la plupart de la complexité en traitant de SVG. Raphaël utilise SVG lorsque disponible. Quand il n'est pas, Raphaël implémente SVG en JavaScript à l'aide de quelles que soient les technologies sont disponibles dans le navigateur. Chaque objet graphique créé dans Raphaël est également un objet DOM, avec toutes les fonctionnalités des objets DOM profiter, comme la liaison des gestionnaires d'événements et l'accès de jQuery. Raphaël a également un système d'animation qui vous permet de définir des animations indépendantes des objets dessinés, permettant la réutilisation de lourde :

var raphael = Raphael(0, 0, 800, 600);
 
var circle = raphael.circle(100, 100, 200);
circle.attr("fill", "red");
circle.animate({r: 600}, 3000);
 
// Or make a custom animation
var myAnimation = Raphael.animation(
  {r: 600},
  3000);
circle.animate(myAnimation);

Dans ce code, au lieu de dessiner un cercle, Raphaël placera un document SVG sur la page avec un élément du cercle. Curieusement, Raphaël n'est pas en mode natif permet de charger des fichiers SVG. Raphaël a une communauté riche, donc il y a un plug-in pour cela disponible à bit.ly/1AX9n7q.

Snap.svg Snap.svg ressemble un peu à Raphaël :

var snap = Snap("#myCanvas"); // Add an SVG area to the myCanvas element
var circle = snap.circle(100, 100, 200);
circle.attr("fill", "#FF0000");
circle.animate({r: 600}, 1000);

Une des principales différences est Snap.svg comprend l'importation sans soudure de SVG :

Snap.load("myAwesomeSVG.svg");

La deuxième différence est que Snap.svg fournit de puissants outils intégrés afin de rechercher et de modifier le SVG structure en place, si vous connaissez la structure de la SVG avec laquelle vous travaillez. Par exemple, imaginez que vous vouliez faire de tous les groupes (balises « g ») dans votre SVG invisible. Après le chargement de SVG, vous devez ajouter cette fonctionnalité dans un rappel à la méthode load :

Snap.load("myAwesomeSVG.svg", function(mySVG) {
  mySVG.select("g").attr("opacity", 0);
});

La méthode select fonctionne beaucoup comme le sélecteur de « $» jQuery, et il est assez puissant. Découvrez Snap.svg à snapsvg.io.

Un peu plus : P5.js

Beaucoup de ces bibliothèques fournissent un petit extra pour les tâches courantes. Cela crée un éventail de technologies pour traiter un large éventail d'applications, du simple dessin à des médias interactifs et des expériences de jeu complexe. Quoi d'autre est là, au milieu du spectre — quelque chose de plus que des solutions simples de dessin, mais pas tout à fait un moteur de jeu complet ?

Un projet intéressant de noter est p5.js, qui est construit à partir du traitement populaire langage de programmation (voir processing.org). Cette bibliothèque JavaScript fournit un environnement de médias interactifs en implémentant le traitement dans le navigateur. P5.js regroupe les tâches les plus courantes en un ensemble de fonctions, que vous devez définir pour répondre aux événements dans le système, à redessiner la scène ou l'entrée de la souris. C'est beaucoup comme Paper.js, mais avec les médiathèques, aussi bien. Voici un exemple, qui montre comment cette approche se traduit par des code graphique plus concis :

float size = 20;
function setup() {
  createCanvas(600, 600);
}
 
function draw() {
  ellipse(300, 300, size, size);
  size = size + .1;
}

Ce programme prend un cercle qui pousse dans la taille qu'elle remplisse l'écran. Découvrez p5.js à p5js.org.

Jusqu'à ce qu'il faut utiliser ?

Il y a clairement des avantages et des inconvénients à la toile et SVG. Il y a également des bibliothèques qui réduisent considérablement beaucoup des inconvénients de chaque approche. Donc ce que devez-vous utiliser ? Je ne recommanderais pas généralement à l'aide de vanille HTML. Il est probable qu'un jeu modern dépassera la complexité graphique, qu'il peut supporter. Donc, cela nous amène à un choix entre le SVG et la toile, ce qui est difficile.

Pour les genres de jeux très distinctifs, la réponse devient un peu plus facile. Si vous créez un jeu avec des centaines de milliers de particules, vous aurez envie d'utiliser de la toile. Si vous créez un jeu d'aventure point-and-click avec un style de bande dessinée, vous pourriez vouloir considérer SVG.

Pour la plupart des jeux, il n'est pas descendu à la performance, que beaucoup voudraient vous faire croire. Vous pouvez passer des heures belaboring quelle bibliothèque à utiliser. En fin de compte, cependant, c'est temps que vous pourriez être le jeu d'écriture.

Ma recommandation est de faire une sélection basée sur vos ressources de l'art. Si vous préparez vos animations de personnage dans Adobe Illustrator ou Inkscape, pourquoi convertir chaque image de vos animations à pixels ? Utiliser le vecteur de l'art en mode natif. Don' t waste tout ce travail de bachotage votre art dans la toile.

À l'inverse, si votre art est principalement basé sur les pixels, ou que vous allez générer des effets complexes sur une base de pixel par pixel, la toile est une option idéale.

Une autre Option

Si vous recherchez les meilleures performances possibles, et vous êtes prêt à faire face à un peu plus de complexité pour y arriver, je recommande vivement de que vous considérer Pixi.js. Contrairement à toute autre chose je vous ai montré dans cet article, que Pixi.js utilise WebGL pour le rendu 2D. Ceci fournit des améliorations de performances principales.

L'API n'est pas tout à fait aussi simple que les autres décrits ici, mais ce n'est pas une énorme différence. En outre, WebGL n'est pas pris en charge sur le plus grand nombre de navigateurs comme les autres technologies. Les systèmes plus anciens etc. Pixi.js n'a aucun avantage en termes de performances. Quoi qu'il en soit, faites votre choix et profiter du processus.


Michael Oneppo est technicien créatif et responsable de l'ancien programme chez Microsoft dans l'équipe de Direct3D. Ses efforts récents incluent le travail comme directeur technique à la technologie de la bibliothèque pour tous à but non lucratif et explorer une maîtrise à l'Université de New York Interactive Telecommunications Program.​

Merci aux experts techniques Microsoft suivants d'avoir relu cet article : Shai Hinitz