<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1487914221330335184</id><updated>2012-02-16T04:45:13.537-08:00</updated><category term='optimisation'/><category term='introduction'/><category term='Background'/><category term='java'/><category term='Andrew Davison'/><category term='gameplay'/><category term='Kevin Glass'/><category term='Jonathan Harbour'/><category term='David Brackeen'/><category term='gdd'/><category term='sprite'/><category term='graphisme'/><category term='motivation'/><category term='Render'/><category term='Rule Based'/><category term='shmup'/><category term='AI'/><category term='pulpcore'/><category term='concept'/><category term='jogl'/><category term='UQAM'/><category term='design'/><category term='Fabien Sanglard'/><category term='performance'/><category term='formes primitives'/><category term='Conjure'/><category term='Bullet Hell'/><category term='racine carrée'/><category term='Slick2D'/><category term='Gradius'/><category term='TÉLUQ'/><category term='OpenGL'/><title type='text'>Péripéties de développement d'un jeu</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-3416658877649146757</id><published>2011-03-27T21:42:00.000-07:00</published><updated>2011-03-27T21:42:17.155-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='concept'/><title type='text'>Castle Doodle</title><content type='html'>Ces derniers jours, j’ai travaillé sur quelques éléments que je pourrais inclure dans mes arrières plans. L’image ci-dessous est un collage de quelques éléments conçus par moi. Le château flottant est celui sur lequel j’ai mis le plus de temps. Pourtant le résultat n’est pas si bon que ça. Il y a un problème de perspective évident. Cela se voit avec la bâtisse carré près de la fusée. En plus, il manque des ombres et lumières. J’étais trop paresseux pour les faire. Il faut quand même se rappeler qu’un élément de décor n’a pas à être trop détaillé, sinon il nuira à la jouabilité du jeu. Il y a un dernier point qui m’agace, le gazon est trop vert. Ça focalise l’attention et ce n’était pas le but recherché. Il y aussi une différence entre les rochers. C’est tout simplement qu’ils sont constitués de deux images pour faciliter leurs intégrations au jeu. Toutefois, en travaillant sur deux images séparées, je n’ai pas fait attention à ma palette de couleurs ce qui a donné des rochers rendus différemment. Tant pis, je fais tout ça pour apprendre après tout.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://fc09.deviantart.net/fs71/f/2011/086/f/8/background_elements_by_ledarkange-d3cn1xv.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://fc09.deviantart.net/fs71/f/2011/086/f/8/background_elements_by_ledarkange-d3cn1xv.jpg" width="400" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Cliquer sur l'image pour la voir dans sa taille originale. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-3416658877649146757?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/3416658877649146757/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2011/03/castle-doodle.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/3416658877649146757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/3416658877649146757'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2011/03/castle-doodle.html' title='Castle Doodle'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-4212941984446870407</id><published>2011-02-27T03:14:00.001-08:00</published><updated>2011-02-27T03:14:08.062-08:00</updated><title type='text'>Prochaine Étape</title><content type='html'>&lt;div class=Section1&gt;  &lt;p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; line-height:normal'&gt;&lt;span lang=FR-CA style='letter-spacing:-.2pt'&gt;Depuis quelques temps, j&amp;#8217;ai mis la programmation de côté. Je travail toujours sur mon gestionnaire d&amp;#8217;arrière-plans, mais comme j&amp;#8217;ai besoin de sprites pour tester les scènes de type SPRITED, j&amp;#8217;ai délaissé le clavier pour le crayon. J&amp;#8217;ai commencé à dessiner des châteaux flottants. Suivront des débris rocheux, des tours, des murs brisés, etc. En fait je vais créer des sprites pour camper un décor médiéval qui sera le thème du deuxième niveau. Enfin, peut-être, c&amp;#8217;est sujet à changements. Pour le premier niveau, je pense refaire le monde de forêts et de montagnes du Gradius original. Avec l&amp;#8217;espèce de rocher en forme de gland juste avant le boss.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; line-height:normal'&gt;&lt;span lang=FR-CA style='letter-spacing:-.2pt'&gt;Quand j&amp;#8217;aurai assez d&amp;#8217;éléments pour fabriquer l&amp;#8217;arrière-plan, je vais implanter la scène de type SPRITED. Ensuite, je vais créer le joueur pour commencer à tester les niveaux. Et aussi mettre en place le système de caméra. Ça représente encore beaucoup de travail avant d&amp;#8217;avoir un prototype jouable. D&amp;#8217;autant plus que cette année j&amp;#8217;ai prévu travailler sur le site web des Productions Juliette. Ce site sera le projet final de mon certificat en informatique. Quant à mon éditeur de niveau, j&amp;#8217;ai décidé de repousser ce projet pour une date indéterminée. De toute façon, je n&amp;#8217;aurais pas été prêt à l&amp;#8217;implémenter cette année. Je n&amp;#8217;aurais donc pas eu mon diplôme cette année. L&amp;#8217;avantage d&amp;#8217;un site web, malgré que j&amp;#8217;ai bien du rattrapage à faire au niveau de la théorie, est que le site peut aboutir facilement à un produit livrable en autant qu&amp;#8217;il reste simple. Peu d&amp;#8217;interactions, peu de graphismes, ennuyeux. Alors, en fonction du temps que je pourrai y consacrer, ce site sera au minimum un ensemble de pages html statiques. Ou un site interactif fonctionnant sous PHP/JavaScript pour l&amp;#8217;interaction et XML/XSLT/CSS/MySQL pour les données et les vues. Le XML/XSLT est une condition du cours d&amp;#8217;intégration du certificat. Je vais essayer de suivre le pattern MVC qui semble le de facto du développement web. Mais, quel est le rapport avec le projet Kradius?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; line-height:normal'&gt;&lt;span lang=FR-CA style='letter-spacing:-.2pt'&gt; Et bien, c&amp;#8217;est simple. D&amp;#8217;abord, les Productions Juliette est le projet de ma conjointe. Grosso-modo, il s&amp;#8217;agit du nom sous laquelle elle fait ses activités professionnelles qui sont liées à la littérature jeunesse&amp;nbsp;: animation, théâtre, formation. De mon côté, je commence de plus en plus à avoir d&amp;#8217;autres projets qui eux sont reliés à l&amp;#8217;informatique. Les jeux vidéo étant le pôle principal. De plus, avec l&amp;#8217;expérience que j&amp;#8217;ai acquise sur ce blog, je me rends compte qu&amp;#8217;un blog ne répond pas à tous mes besoins de visibilité et de crédibilité sur le web. Sans compter que Blogger semble trop facilement pollué par les pop-up. Je voulais donc, tout comme ma conjointe, un site web dédié à mes projets qui pourrait également me servir de e-portfolio pour&amp;#8230; enfin je vous laisse deviner. Le site que je construirai sera donc un site bicéphale présentant les projets de moi et ma conjointe. Et oui, Indie-darkange c&amp;#8217;est fait avaler par les Productions Juliette. Étant donné que la visibilité est plus importante pour ma conjointe, le site sera plus identifié à ses projets. Mais je m&amp;#8217;y réserve un espace. C&amp;#8217;est là que le projet Kradius va déménager ainsi que ce blog&amp;#8230; Le site sera hébergé par une entreprise québécoise payante. Donc, avec un meilleur contrôle sur les publicités intempestives et sur les fonctionnalités du site. Je pourrai éventuellement tester des possibilités de jeux en ligne ou de système de «&amp;nbsp;High score&amp;nbsp;». Les possibilités sont excitantes. Le site et le projet Kradius seront développés en parallèle à partir de maintenant.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; line-height:normal'&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-4212941984446870407?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/4212941984446870407/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2011/02/prochaine-etape.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4212941984446870407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4212941984446870407'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2011/02/prochaine-etape.html' title='Prochaine Étape'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-349007814934719608</id><published>2011-01-30T22:49:00.001-08:00</published><updated>2011-02-02T14:52:58.108-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Background'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>Back to ground zero.</title><content type='html'>&lt;div class="Section1"&gt;&lt;div class="MsoNormal"&gt;Dans un jeu vidéo, en particulier ceux en 2D, les backgrounds ou arrière-plans ajoutent de la profondeur à l’environnement. L’effet est encore plus saisissant lorsqu’on utilise plusieurs backgrounds à la fois ou qu’on utilise un avant-plan.&amp;nbsp; Chaque plan peut se déplacer, être animé ou complètement statique. Ils campent le décor du jeu et de ce fait, ils sont quasi indispensables.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;De puis que j’ai décidé d’utiliser OpenGL plutôt que les BufferedImage de java pour mes graphiques, j’ai eu un paquet de problèmes. En particulier en ce qui à trait au temps de chargement des images et à la taille permise des images à chargées. OpenGL étant limité à certaines valeurs. En plus, les dimensions des images doivent être un multiple de deux. Quoique cela, ça dépend des versions d’OpenGL. Mais lorsque l’on développe, il faut toujours penser que les usagers ne possèdent pas nécessairement les plus récentes technologies. Ces restrictions ont complètement démolie mon système de gestion des arrière-plans qui était basé sur les techniques de KGPIJ, jusqu’à maintenant.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Je ne pouvais tolérer un temps de chargement interminable. Donc, après quelques recherches sur le web, j’ai constaté qu’une bonne pratique concernant les arrière-plans consiste à découper l’image d’origine et de construire l’arrière-plan à partir de ces petites images. Un peu comme un casse-tête.&amp;nbsp; C’est la technique des tuiles ou briques.&amp;nbsp; J’ai donc élaboré une structure que j’ai nommé «&amp;nbsp;Scene&amp;nbsp;» pour représenter un avant ou un arrière-plan. La scène est d’abord décrite dans un fichier XML. Ce qui me permet de la modifier à volonté sans passer par le code source. De plus, je pourrais éventuellement utiliser les fichiers XML pour d’autres applications (web, documentation, etc.).&amp;nbsp; Les scènes sont gérées par la classe «&amp;nbsp;SceneManager&amp;nbsp;». Cette&amp;nbsp; classe à la responsabilité de&amp;nbsp;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;Charger les scènes&lt;o:p&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Modifier les scènes&lt;o:p&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Mettre à jour les scènes&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt; &lt;/span&gt;Afficher les scènes&lt;/li&gt;&lt;/ol&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Le fait de déléguer ces tâches à un manager permet de contrôler plus facilement la gestion des scènes. Par exemple, selon la situation (la confrontation final à la fin d’un niveau – scène statique), on peut demander d’arrêter la mise à jour des scènes et la reprendre plus tard. Permettant ainsi à d’autres routines de faire mieux leur travail. Ou de booster le nombre d’éléments à l’écran (bullet hell). C’est un principe que j’utilise pour les autres groupes d’objets du jeu&amp;nbsp;: le feu ennemi, les sprites ennemis, l’interface, la musique, etc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Le chargement et la création des scènes est assez banal. Le manager lit le fichier XML et utilise les données convertit par le parseur XML pour créer les scènes. Ces données sont organisées en tableau de sorte que chaque cellule du tableau correspond à une scène à créer. La première donnée lu est le type de scène à créer. Les scènes sont construites par rapport à ce type, soit&amp;nbsp;:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt; &lt;/span&gt;TILED&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;SPRITED&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li&gt;PLAIN&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li&gt;GRADIENT_H&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li&gt;GRADIENT_V&lt;/li&gt;&lt;/ol&gt;&lt;div class="MsoListParagraphCxSpLast" style="text-align: justify; text-indent: -18pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoListParagraphCxSpLast" style="text-align: justify; text-indent: -18pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Seule la scène SPRITED reste à implémenter. À cette étape-ci dans le développement, je n’ai pas besoin de ce type de scène pour tester mes techniques. Mais éventuellement, c’est avec ces scènes que j’ajouterai de l’animation aux arrières et avant-plans.&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Voici le résultat d’une scène TILED avec près de 10000 bullets à l’écran. Noter les données statistiques en haut de l’image.&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/uc?id=0B7B6XmrHiCzBZmQzZTJiNGQtOGEzMS00NzQzLTg5MmUtMzgyMTkyMGM4YTBk&amp;amp;hl=en" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="https://docs.google.com/uc?id=0B7B6XmrHiCzBZmQzZTJiNGQtOGEzMS00NzQzLTg5MmUtMzgyMTkyMGM4YTBk&amp;amp;hl=en" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/uc?export=download&amp;amp;id=0B7B6XmrHiCzBWXU1N2FlQ2w5WVVBK1JEL2dwY3dTM3E3a1JzPQ&amp;amp;revision=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;D’abord on voit dans l’arrière plan le caractère répétitif du motif bleu turquoise. Cela démontre que la scène à été créée avec une petite image répétée. Ensuite, au niveau de la performance, même avec 9874 bullets à l’écran, j’obtiens un FPS de 49. Ce qui est très bien à mon avis. Remarque que le temps de chargement est encore assez long. Je devrai sûrement trouver une méthode plus efficace.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;La mise à jour de la scène ce fait de la façon suivante&amp;nbsp;:&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;SceneManager &lt;span style="font-family: Wingdings;"&gt;--&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;/**&lt;/span&gt;&lt;o:p style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp; Mise à jour à intervalles de temps des scènes.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span lang="EN-CA"&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void move(GamePadController.COMPASS cDirection){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (clMoveTimer &amp;gt; 0){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ctLifetimeTimer.getTimer() &amp;gt; (clMoveStart + clMoveTimer)){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// Mise à zéro du temps de mouvement.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clMoveStart = ctLifetimeTimer.getTimer();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Bouge la sprite par la quantité du vecteur vélocité.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span lang="EN-CA"&gt;if (cDirection == GamePadController.COMPASS.WEST) moveLeft();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (cDirection == GamePadController.COMPASS.EAST) moveRight();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else stayStill();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&amp;nbsp;&amp;nbsp;&amp;nbsp; // Update at cpu clockspeed.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (cDirection == GamePadController.COMPASS.WEST) moveLeft();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (cDirection == GamePadController.COMPASS.EAST) moveRight();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else stayStill();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // Fin if.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif; font-size: small;"&gt;&lt;span lang="EN-CA" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 9pt;"&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif; font-size: small;"&gt;}&lt;/span&gt;&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;La direction du mouvement des scènes ce fait selon la direction lu sur le contrôleur de jeu. La mise à jour ce fait à chaque intervalle de temps clMoveTimer. Ainsi, on peut forcer que la mise à jour ce fasse 20 fois seconde, 60 fois seconde. C’est comme on veut. De façon général, je crois qu’il est moins pertinent de consacrer trop de ressources système aux arrière-plans. Il vaut mieux les mettre à jour 30 fois par seconde et mettre à jour les sprites 60 fois seconde. Ça devrait augmenter la qualité du jeu.&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Voici ce qui se passe dans la classe «&amp;nbsp;Scene&amp;nbsp;»&amp;nbsp;:&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Mise à jour des scènes. La mise à jour diffère selon le type de scènes. */&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void update(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ciType == 1) updateGradientH();&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ciType == 5) updateTiledScene();&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; // fin de la méthode.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Dessine les scènes. Varie selon le type de scènes. &lt;span lang="EN-CA"&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void draw(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ciType == 1) displayGradientGL();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (ciType == 5) displayTiledGL();&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; // fin de la méthode.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Incrémente la valeur de xSceneHead dépendamment des flags.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Elle peut varier entre -width et width(exclus), qui est la&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;* largeur de l'image.&amp;lt;br /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Attention au transtypage, on peut perdre de la précision dans le&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * &amp;lt;code&amp;gt;xSceneHead&amp;lt;/code&amp;gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Note: les méthodes sont public pour une mise à jour indépendante si souhaité.&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void updateTiledScene(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (isMovingRight) fSceneHead = (fSceneHead + cvVelocity.getStepX()) % pixeledWidth;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span lang="EN-CA"&gt;else if (isMovingLeft) fSceneHead =&amp;nbsp; (fSceneHead - cvVelocity.getStepX()) % pixeledWidth;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span lang="EN-CA"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;xSceneHead = (int)fSceneHead;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="line-height: normal; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 9pt;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; // fin de la méthode.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;La mise à jour et le rendu diffère selon le type de scène. Dans updateTiledScene, la valeur xSceneHead est mise à jour selon la direction du mouvement de la scène. Cette technique et celle de l’affichage des tuiles est similaire à KGPIJ. Sauf qu’étant donné que je travail avec des floats, la mise à jour de xSceneHead était un problème. Comme cette valeur est un entier, la précision par rapport à un float limitait énormément les vitesses de déplacement que je pouvais utiliser. J’ai donc ajouté la variable globale fSceneHead qui est essentiellement la même chose que xSceneHead mais en floats. fSceneHead n’est jamais transtypé ce qui fait qu’elle ne perd pas sa précision. Sa valeur est copiée dans xSceneHead pour positionner correctement l’affichage des tuiles. Éventuellement, il faudra que je fasse une mise à jour prenant en compte les mouvements verticaux.&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Dans le cas de la scène de type gradient&amp;nbsp;: &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/7s6Tw9fDljtH_FQew_-BN6ou7CYxCpJCBJEpAGY5MkIOpFltJfnf_Uqv-S-0AebHazHbTp4AS0ZtQrH2_vwqSZ59fQ=s512" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="https://lh5.googleusercontent.com/7s6Tw9fDljtH_FQew_-BN6ou7CYxCpJCBJEpAGY5MkIOpFltJfnf_Uqv-S-0AebHazHbTp4AS0ZtQrH2_vwqSZ59fQ=s512" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;La mise à jour ne contient aucunes actions. J’ai quand même expérimenté un peu et en faisant augmenter le rouge à chaque update, on obtient un bel effet de crépuscule à mesure que le temps passe. C’est une voie à explorer. L’affichage d’un gradient en OpenGL ce fait de cette façon&amp;nbsp;:&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="line-height: normal; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 9pt;"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; /**&lt;/span&gt;&lt;o:p style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp; Affiche un arrière plan de type Gradient.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void displayGradientGL(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glPushMatrix();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Si on utilise une texture blanche, la scène est beaucoup plus vive.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Sans textures, la scène est sombre. Comme-ci on peignait sur du noir.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;ctBasicRenderingTexture.bind();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // translate to the right location and prepare to draw&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glTranslatef(0, 0, 0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glBegin(GL11.GL_QUADS);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glColor3f(cfaColor1[0],cfaColor1[1],cfaColor1[2]);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(0, 0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(playableWidth, 0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glColor3f(cfaColor2[0],cfaColor2[1],cfaColor2[2]);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(playableWidth, playableHeight);// / 2);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(0, playableHeight);// / 2);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glEnd();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="font-family: Arial,Helvetica,sans-serif; line-height: normal; text-align: justify;"&gt;&lt;b&gt;&lt;span lang="EN-CA" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: small;"&gt;GL11.glPopMatrix();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormalCxSpMiddle" style="line-height: normal; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 9pt;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Pour plus de renseignements sur les techniques d’OpenGL, voir le site de &lt;a href="http://nehe.gamedev.net/"&gt;Neon Helium Productions&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;J’ai peint mon gradient sur une texture blanche de 32x32 dans un carré (GL_QUADS) de la dimension de la surface de jeu. Et l’effet est parfait. Si j’avais peint la scène sur une texture plus foncée, les couleurs auraient étés moins vives. De plus, comme elle est peinte sur une texture, rien ne m’empêche de jouer avec la transparence pour ajouter de l’effet. J’ai voulu faire ce type de scène pour mettre une couleur intéressante dans le fond et du fait même, faire ressortir les éléments ce trouvant à l’avant. Bon, je ne suis pas sûr de savoir comment je vais l’utiliser, mais si j’en ressens le besoin, je pourrai le faire.&amp;nbsp;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Je ne crois pas que ce type de scène doit «&amp;nbsp;bouger&amp;nbsp;», conséquemment les updates et les rendus peuvent ce faire moins souvent.&amp;nbsp;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="text-align: justify;"&gt;Voilà où j’en suis. Le problème que j’ai en ce moment (un autre&amp;nbsp;!) est que la création des scènes avant même qu’elles soient décrites dans le fichier XML, n’est pas une mince affaire. Je dois créer mes images dans Photoshop ou Gimp, les sectionner (Tiled) et construire la scène finale. Après cela, tout inscrire sur papier afin de transférer les informations dans le fichier XML adéquatement. Un jour, il me faudra un éditeur de niveau qui fera ces tâches pour moi.&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-349007814934719608?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/349007814934719608/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2011/01/back-to-ground-zero.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/349007814934719608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/349007814934719608'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2011/01/back-to-ground-zero.html' title='Back to ground zero.'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-7220956267712907571</id><published>2010-12-05T21:10:00.001-08:00</published><updated>2010-12-05T21:16:56.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UQAM'/><category scheme='http://www.blogger.com/atom/ns#' term='TÉLUQ'/><title type='text'>TÉLUQ = Méchante facture</title><content type='html'>&lt;div class="Section1"&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Le sujet que je vais aborder dans les prochaines lignes ne concerne pas directement le projet Kradius. Je m’en excuse. J’ai tout de même voulu le faire parce que ça touche mes études et d’une certaine façon, mon intégrité.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span lang="FR-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Le 30 novembre dernier, l’émission d’intérêt public «&amp;nbsp;La Facture&amp;nbsp;» diffusée à Radio-Canada, mettait en lumière la difficulté que certains étudiants en psychologie ont eu à faire reconnaître leurs cours dans différentes universités. Pour ceux qui ont manqué l’émission, elle est disponible sur tou.tv&amp;nbsp;: &lt;/span&gt;&lt;a href="http://tou.tv/la-facture/S2010E13" target="_blank"&gt;http://tou.tv/la-facture/S2010E13&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;span class="postbody"&gt;Le litige amené par l’émission concerne deux étudiantes qui n’ont pu faire reconnaître leurs certificats en psychologie afin de poursuivre au niveau du bac. Après maintes démarches, seule l’UQTR a acceptée de reconnaître le certificat au complet mais en admettant avec bonhommie que les cours n’étaient pas tout à fait au niveau. Mais, à la fin du bac, le retard serait comblé. Comme&amp;nbsp;les étudiantes interviewées n’étaient pas de la région de Trois-Rivières, elles ont du déménager pour poursuivre leurs études. Ce qui n’était pas possible pour l’une d’entre elle. Cette dernière se plaint donc d’avoir étudié pour rien et d’avoir perdu plus de 3000$ sans compter le temps gaspillé. Suite au reportage, certaines universités ont révisé leur politique de reconnaissance des acquis, mais paradoxalement, seule l’UQAM demeure fermée à toute entente. C’est étrange puisque la TÉLUQ fait maintenant partie de l’UQAM. Pourquoi cette fermeture au juste&amp;nbsp;? Parce que, selon l’UQAM, le certificat en psychologie est constitué de cours en dessous de la base. Des cours introductifs. L’UQAM ne reconnaît même pas son propre certificat qu’elle donne sur campus. Que ce soit à la TÉLUQ ou à l’UQAM, un étudiant serait en droit de s’attendre à ce que son certificat lui permettre d’entrer au bac sans problèmes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="postbody"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Au delà du problème spécifique à la psychologie, ce qui m’agace, c’est l’allusion comme quoi un certificat universitaire ne vaut pas une année d’étude du bac. Que la matière est introductive, que ce sont des cours gentils et tous mignons. Et comme la seule université représentée était la TÉLUQ, il est facile de faire le lien comme quoi les études à distances sont de piètres qualités. Évidemment, ce reportage a suscité une discussion intéressante sur le forum de la TÉLUQ. Parmi les commentaires émis par rapport à ce sujet, il y avait le cas d’étudiants qui ont fait des cours à la fois sur campus et à distance dans le même domaine et qui ont trouvé la version à distance plus difficile et plus complète. Cette question dépend en réalité des cours même. Et non de la façon, soit à distance ou sur campus. Un cours universitaire en général peut être difficile ou non, avec beaucoup de travaux ou non, examen ou pas, etc. Personnellement, j’ai trouvé les cours de mon certificat en informatique de difficulté et de contenu variables. Certains étaient exigeant, d’autres contenaient énormément de matière, d’autres moins. INF5100, l’intelligence artificielle, par exemple. Et bien, ce cours est mon plus facile pour le moment, je mets moins d’efforts que dans les autres cours et pourtant mes résultats sont de l’ordre du A+. D’un autre côté, quand j’ai fait ADM2005, gestion informatisée, j’ai paniqué face à la matière a étudiée. Il y en avait trop et je la comprenais mal. Mais à force de travail, j’ai bien réussi. Les études à distances apportent non seulement un bagage académique indéniable, mais comme l’a mentionné un étudiant, elles exigent des qualités personnelles très recherchées par les employeurs d’aujourd’hui&amp;nbsp;: &lt;/span&gt;autonomie, organisation, capacité à prendre des décisions, gestion du temps, collaboration, etc. J’ajouterais à cette liste&amp;nbsp;: autodidactie. Parce qu’étudier à distance est synonyme de solitude, on est forcé de se débrouiller et on doit répondre à nos propres questions. On expérimente la théorie à notre manière, on fouille dans les forums du web, bref on apprend par nous même parce qu’il n’y a pas de profs pour nous tenir la main et personne pour nous dire quoi faire. Sans cette qualité que je crois sincèrement avoir développée au fil de mes études, je n’aurais jamais été aussi loin dans le projet Kradius. J’aurais probablement abandonné il y a longtemps. Et plus je travail le projet, plus j’ai de nouvelles idées. Un livre&amp;nbsp;? Donner de la formation&amp;nbsp;? Qui sait. Une étudiante a ajouté qu’un certificat était l'équivalent de la première année d’un bac et qu'il correspond en fait à des cours qui introduisent la matière. Les années suivantes du bac servent à l’approfondissement et la pratique (stage). Et bien, avec Kradius, je fais mon propre approfondissement et ma propre pratique.&lt;br /&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Il va sans dire que le directeur général de l’UQAM est venu à la défense de la TÉLUQ. Le texte qui suit est un extrait de la lettre qu’il a publié sur le site de la TÉLUQ. Malheureusement, je n’ai pas été en mesure de retrouver le lien.&lt;br /&gt;&lt;br /&gt;&lt;span lang="FR-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="postbody"&gt;&lt;i&gt;&lt;span lang="FR-CA" style="font-size: 10pt; line-height: 115%;"&gt;«&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span class="postbody"&gt;&lt;i&gt;&lt;span style="font-size: 10pt; line-height: 115%;"&gt;Il est important de noter que les problèmes liés à la reconnaissance des cours semblent circonscrits aux programmes de psychologie conduisant à la profession de psychologue. Comme l’a rappelé La Facture, la qualité des cours de la TÉLUQ n’est pas en cause et l’institution jouit d’une réputation d’excellence.&amp;nbsp;Elle est la deuxième plus grande université à distance au Canada.&amp;nbsp;Chaque année, plus de 20 % des étudiants qui fréquentent la TÉLUQ sont des étudiants dits «&amp;nbsp;par transferts&amp;nbsp;», c’est-à-dire des étudiants inscrits dans les autres universités du Québec et qui suivent des cours de la TÉLUQ avec la pleine autorisation de leur responsable de programme. Il va sans dire que pour ces milliers d’étudiants, la question de la reconnaissance des cours ne se pose pas.&amp;nbsp;»&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-size: 10pt; line-height: 115%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="postbody"&gt;«&amp;nbsp;Quant aux diplômes de la TÉLUQ, ils sont très largement reconnus par les employeurs, les associations professionnelles et les autres universités. Dans le cadre d’une enquête réalisée par la firme SOM au printemps de 2010 auprès de diplômés récents de la TÉLUQ, 80 % déclarent que leur employeur actuel ou des employeurs potentiels reconnaissent la formation acquise. Ceux qui ont changé d’emploi dans l’année suivant l’obtention de leur diplôme sont encore plus positifs&amp;nbsp;: selon eux, c’est 88 % des employeurs qui reconnaissent la formation acquise à la TÉLUQ.&amp;nbsp;»&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="postbody"&gt;&lt;b&gt;Raymond Duchesne&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="postbody"&gt;Directeur général&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="font-size: 10pt; line-height: 115%;"&gt;&lt;span class="postbody"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="font-size: 10pt; line-height: 115%;"&gt;&lt;span class="postbody"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="postbody"&gt;Quelle perception le public aura de la TÉLUQ maintenant&amp;nbsp;? Le reportage de «&amp;nbsp;La Facture&amp;nbsp;» laisse un goût amer. Comme aucune autre université à distance n’a été représentée, la TÉLUQ donne l’impression de décerner des diplômes de valeurs moindres et que c’est la seule à le faire. Et c’est bien dommage. Comme la plupart des étudiants, je suis convaincu que ce n’est pas le cas. D’ailleurs, le journaliste Pierre Craig à bien dit que la TÉLUQ avait une réputation d’excellence. Le litige, rappelons-le, est au niveau de la reconnaissance des acquis. Et j’espère que l’intervention de Mr. Duchesne saura rassurer les étudiants. Je me demande aussi si l’AETÉLUQ a pris la bonne décision en amenant ce débat devant la place publique. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-7220956267712907571?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/7220956267712907571/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/12/teluq-mechante-facture.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7220956267712907571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7220956267712907571'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/12/teluq-mechante-facture.html' title='TÉLUQ = Méchante facture'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-4221017651389099169</id><published>2010-11-06T22:27:00.000-07:00</published><updated>2010-11-06T22:42:22.060-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AI'/><category scheme='http://www.blogger.com/atom/ns#' term='Rule Based'/><title type='text'>C'est la règle</title><content type='html'>&lt;div&gt;Dans le cadre de mon cours en intelligence artificielle, j’ai voulu écrire ce billet afin d’illustrer une application des techniques vu dans le cours à une situation qui pourrait se produire dans mon projet de jeu vidéo. Grosso-modo, le tiers du cours est fait. Il a été question de différentes façons de représenter des connaissances afin qu’un système puisse les traiter. Les façons abordées étaient jusqu’à maintenant, toutes sous formes de règles &lt;a href="http://fr.wikipedia.org/wiki/Modus_ponens"&gt;&lt;b&gt;modus ponens &lt;/b&gt;&lt;/a&gt;: logique propositionnel, logique des prédicats, etc. Ces règles ressemblant à une série de Si A alors B, sont à la base des systèmes experts permettant d’obtenir des réponses sur un problème d’un domaine bien précis. Par le chaînage avant ou arrière, le système questionne l’usager afin de déduire des faits et de proposer une solution à un problème. Cette technique peut être utilisée dans une situation de jeu vidéo. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;L’objectif du projet Kradius est d’abord de créer un shoot’em up à haute intensité d’action (bullet hell), dont les inspirations viennent de Gradius et de shooter comme Ikaruga. La technique d’IA que je veux illustrer est plus ou moins pertinente dans ce genre de jeu. La raison en est simple, ces jeux sont basés sur l’intensité de l’action, les réflexes du joueur et non la stratégie. Les ennemis ont des patterns d’attaques bien définis. Le joueur n’a qu’à entrer dans la danse et survivre. Par contre, mon projet est plus ambitieux que cela. Une fois l’étape « bullet hell » atteinte, je prévois incorporer différents gameplay afin de diversifier le jeu. Par exemple, dans les niveaux d’action, je pense intégrer des « zones d’atterrissages » ou le joueur aurait la possibilité de sortir de son vaisseau et de continuer l’exploration à pied. Admettons que ce soit le cas et que le pilote se retrouve sur une planète en guerre. Son seul refuge est un village extra-terrestre sur le point d’être assiégé par un ennemi impitoyable. Hors, la seule chance de survie du pilote, est de coopérer avec les villageois pour organiser la défense du village, repousser l’ennemi et récupérer le vaisseau du pilote qui a bien évidemment été capturé par l’ennemi. À ce point, le gameplay passe d’un shoot’em up à un RTS style &lt;a href="http://us.blizzard.com/en-us/games/sc/"&gt;Starcraft &lt;/a&gt;qui est tout à fait approprié pour l’intégration de techniques IA basé sur un système de règles.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.shmup.com/index.php?page=fiche&amp;amp;id=514"&gt;Gradius III&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/uc?id=0B7B6XmrHiCzBZTNmZDIwOGEtYmNjOS00NDhiLThkZDMtMTllNDYyMTRhNGFl&amp;amp;hl=en" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://docs.google.com/uc?id=0B7B6XmrHiCzBZTNmZDIwOGEtYmNjOS00NDhiLThkZDMtMTllNDYyMTRhNGFl&amp;amp;hl=en" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://doc-10-8c-docs.googleusercontent.com/docs/secure/jj023urnm00k9f2ib77fnbca06junpu6/ctip9727ulv8r7rpr6mo3f7t3kinad6r/1289088000000/11122521856939196104/11122521856939196104/0B7B6XmrHiCzBZTNmZDIwOGEtYmNjOS00NDhiLThkZDMtMTllNDYyMTRhNGFl?nonce=m9tcb943g9dui&amp;amp;user=11122521856939196104&amp;amp;hash=hn19regd84bitnntgkkd4i5sfkf6dp4q%20" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.shmup.com/index.php?page=fiche&amp;amp;id=760"&gt;Ikaruga&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/uc?id=0B7B6XmrHiCzBMTQ4ZjkxODUtMTQ4Ni00OTQ0LThmN2UtMzk2NDEwODk5YmQ2&amp;amp;hl=en" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://docs.google.com/uc?id=0B7B6XmrHiCzBMTQ4ZjkxODUtMTQ4Ni00OTQ0LThmN2UtMzk2NDEwODk5YmQ2&amp;amp;hl=en" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/leaf?id=0B7B6XmrHiCzBMTQ4ZjkxODUtMTQ4Ni00OTQ0LThmN2UtMzk2NDEwODk5YmQ2&amp;amp;hl=en" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;Vous-êtes vous déjà demandé comment un jeu s’y prenait pour offrir une compétition réaliste à un joueur? Comment l’adversaire informatique pouvait se comporter de façon humaine? Pourquoi dans un jeu de combat comme &lt;a href="http://www.streetfighter.com/"&gt;Street Fighter&lt;/a&gt;, l’adversaire ne contre pas chaque coup avec exactement le bon coup au bon moment? Pourquoi dans un RTS, il n’envoie pas exactement le bon nombre de soldats combattre les forces du joueur? Le jeu pourrait faire tout cela, il sait tout ce que le joueur sait, il connaît chaque mouvement du joueur à la milliseconde près. Une IA basée sur un système de règles sert justement à simuler le fait que l’ordinateur doit apprendre du joueur pour pouvoir lui offrir une résistance réaliste.&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/uc?id=0B7B6XmrHiCzBMmRlYmFiMjUtMzU5YS00MGJjLWFkZGEtMTJhM2NjMGJmMWFh&amp;amp;hl=en" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="440" src="https://docs.google.com/uc?id=0B7B6XmrHiCzBMmRlYmFiMjUtMzU5YS00MGJjLWFkZGEtMTJhM2NjMGJmMWFh&amp;amp;hl=en" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://doc-10-8c-docs.googleusercontent.com/docs/secure/jj023urnm00k9f2ib77fnbca06junpu6/b2r3mgdfhhfft8hu84damk2gqfurfkif/1289088000000/11122521856939196104/11122521856939196104/0B7B6XmrHiCzBMmRlYmFiMjUtMzU5YS00MGJjLWFkZGEtMTJhM2NjMGJmMWFh?nonce=btl0702hvr3o8&amp;amp;user=11122521856939196104&amp;amp;hash=ql4lkmjl38j3nbhhrgjhk9kh5gl6ggik" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Observons le graphique précédent. Il s’agit de l’arbre technologique hypothétique de Kradius. Notre héros s’est donc écrasé sur une planète hostile où il se retrouve à la tête d’un petit village. Afin de préparer les villageois au combat et finalement regagner l’espace, le héros doit entrainer les villageois (ils deviendront soit, ouvrier, charpentier ou scout), construire des bâtiments, et récolter des ressources. Le but ici, est de mettre  l’adversaire informatique au courant de l’avancé technologique du joueur afin qu’il puisse planifier et déployer des ressources offensives et défensives selon la situation du joueur. Comme je l’ai mentionné plus haut, on pourrait rendre l’ordinateur omniscient mais se serait injuste et se serait plus réaliste que l’ordinateur puisse améliorer ses connaissances sur cette situation en faisant des inférences sur l’état technologique du joueur. L’ordinateur devra donc envoyer des scouts en éclaireur sur le terrain de son adversaire pour récolter l’information lui permettant de faire des déductions sur son avancement technologique. Le joueur pourrait avoir la possibilité de couper l’information en éliminant le scout avant qu’il ne transmettre ses nouvelles données, par exemple.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Le système de règle est constitué de deux éléments principaux : la base de faits  et les règles.  La base de faits de notre exemple pourrait ressembler à ceci :&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public enum MemoryValue {YES, NO, MAYBE, UNKNOWN};&lt;br /&gt;&lt;br /&gt;// Variables globales.&lt;br /&gt;public MemoryValue villageois;&lt;br /&gt;public MemoryValue scout;&lt;br /&gt;public MemoryValue ouvrier;&lt;br /&gt;public MemoryValue charpentier;&lt;br /&gt;public MemoryValue bouclier;&lt;br /&gt;public MemoryValue murEnceinte;&lt;br /&gt;public MemoryValue maison;&lt;br /&gt;public MemoryValue ecole;&lt;br /&gt;public MemoryValue technicien;&lt;br /&gt;public MemoryValue usineArme;&lt;br /&gt;public MemoryValue scientifique;&lt;br /&gt;public MemoryValue tank;&lt;br /&gt;public MemoryValue caserne;&lt;br /&gt;public MemoryValue fusillier;&lt;br /&gt;public MemoryValue mitrailleur;&lt;br /&gt;public MemoryValue sniper;&lt;br /&gt;public MemoryValue soldat;&lt;br /&gt;public MemoryValue piloteTank;&lt;br /&gt;public MemoryValue piloteAvion;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cette base contient tous les nœuds du graphe qui peuvent prendre 4 valeurs : YES, NO, MAYBE, UNKNOWN. Une valeur à YES implique que le joueur possède la technologie. Si le joueur possède tous les éléments nécessaires à la construction d’une technologie, mais que le fait doit être confirmé par un scout, la valeur est à MAYBE.  L’ordinateur peut alors rassembler des faits en envoyant ces scouts et en faisant des observations. Si le scout rencontre un Mur d’enceinte, alors murEnceinte est mis à YES. Si le scout retourne à sa base sain et sauf, alors l’adversaire ajoute les observations du scout à sa base de fait et effectue des déductions sur les technologies possibles que le joueur est en mesure de posséder. Il le fait en inférant à travers les règles de déductions de sa base de règles. Une règle peut ressembler à celle-ci :&lt;br /&gt;&lt;code&gt;&lt;br /&gt;If (murEnceinte == MemoryValue.YES) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; charpentier = MemoryValue.YES ;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cette règle nous dit qu’étant donné qu’un mur d’enceinte a été observé, il y a forcément un charpentier en jeu qui l’a construit. On peut aussi supposer que s’il y un charpentier, il y a probablement des maisons. Ce qui se traduit par la règle :&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if ((charpentier == MemoryValue.YES) &amp;amp;&amp;amp;( maison == MemoryValue.UNKNOWN)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; maison = MemoryValue.MAYBE ;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;On pourrait se demander à quoi peut servir une valeur MAYBE. Et bien, admettons que l’adversaire doit déployer des forces en se basant sur ces valeurs, avant de gaspiller des ressources contre une technologie hypothétique, il pourra soit envoyer plus de scouts pour combler les informations manquantes ou envoyer 20% moins de soldats étant donnée qu’il ne peut confirmer la présence de cette technologie même s’il a un doute raisonnable. La stratégie à adopter selon les données de la base de faits dépasse le cadre de mon exemple.&lt;br /&gt;&lt;br /&gt;Voici d’autres exemples de règles :&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (bouclier == MemoryValue.YES) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ouvrier = MemoryValue.YES ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; technicien = MemoryValue.YES ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (usineArme == MemoryValue.YES) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ouvrier = MemoryValue.YES ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; technicien = MemoryValue.YES ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scientifique = MemoryValue.YES ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if ((fusillier == MemoryValue.YES) &amp;amp;&amp;amp;( sniper == MemoryValue.UNKNOWN)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sniper = MemoryValue.MAYBE ;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ceci étant dit, il ne reste qu’à traduire chaque lien de l’arbre technologique en règles pour que le moteur d’IA fasse les déductions adéquates. Attention, cela peut représenter un nombre impressionnant de règles. Et si certains faits ne sont pas, ou sont mal représentés par les règles, le moteur d’inférence ne pourra jamais faire les bonnes déductions. De plus, il ne s’agit pas d’utiliser nécessairement un véritable moteur d’inférence pour faire ces déductions, il faut simplement recréer son fonctionnement au sein du module IA de l’engin. Il faut que l’algorithme soit simple puisque les déductions peuvent être requises à chaque itération de la boucle de jeu. Comme les déductions se produisent par l’ajout de nouvelles données, l’algorithme le plus simple reste le chaînage avant.&lt;br /&gt;&lt;br /&gt;Le chaînage avant est constitué de 3 étapes principales. Dans notre exemple, une fois que les scouts ont transmis les informations au commandement central, et que la base de fait ai été mise à jour, les déductions commencent. La première étape consiste à faire correspondre les règles aux faits.  Ceci ce fait en vérifiant la partie conditionnelle des règles. Lorsqu’il y a une correspondance, la règle peut être activée. Mais avant, il faut vérifier si d’autres règles s’appliquent pour les mêmes faits. Et choisir la règle à activer. C’est l’étape de résolution des conflits, l’étape 2. On peut choisir les règles en prenant soit la première rencontrée, soit une au hasard parmi celles applicable, ou leur donner un poids dans le but d’appliquer la plus pertinente. Une fois que la résolution des conflits est terminée, la règle choisie est activée. C’est l’étape 3. La règle peut alors enclencher des évènements ou comme dans notre exemple, déduire de nouveaux faits. Quand des nouveaux faits ont été déduits, il faut recommencer les inférences jusqu’à ce qu’il n’y ai plus rien à déduire.&lt;br /&gt;&lt;br /&gt;En résumé, l’adversaire informatique doit récolter des informations pour pouvoir établir la stratégie à adopter face à son adversaire humain. Cette façon de faire rend le jeu plus réaliste, plus satisfaisant, plus juste. L’expérience en sera donc plus grande et le jeu sera plus apprécié.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;BIBLIOGRAPHIE&lt;/b&gt;&lt;br /&gt;1- David M. Bourg &amp;amp; Glenn Seemann, AI for Game Developers, 2004, O’Reilly Media, Livre sur l’intelligence artificielle pour les jeux video.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-4221017651389099169?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/4221017651389099169/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/11/cest-la-regle.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4221017651389099169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4221017651389099169'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/11/cest-la-regle.html' title='C&apos;est la règle'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-722504665979621043</id><published>2010-10-30T08:37:00.000-07:00</published><updated>2010-10-30T08:37:52.689-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Render'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><category scheme='http://www.blogger.com/atom/ns#' term='formes primitives'/><title type='text'>Ghost Mysteries</title><content type='html'>Plus mon travail avançait avec OpenGL via LWJGL, plus je me décourageais. &lt;br /&gt;Rien ne fonctionnait, le chargement des images était trop long et en plus &lt;br /&gt;elles ne se dessinaient pas à l’écran. En suivant la méthodologie de &lt;br /&gt;Kevin Glass, j’ai finalement réussi à obtenir un résultat intéressant. &lt;br /&gt;Les projectiles sont bien rendus. Mais je n’ai pas réglé le temps de &lt;br /&gt;chargement. En plus, jusqu’à tout récemment, je ne pouvais afficher &lt;br /&gt;d’objets primitifs à l’écran. J’ai cherché une solution sur le web sans &lt;br /&gt;rien trouver. Mais à force de réfléchir, j’ai résolu mon problème.&lt;br /&gt;&lt;br /&gt;Un objet primitif, est un objet dessiné directement avec des fonctions &lt;br /&gt;d’OpenGL. Un carré par exemple, ou une ligne. Je voulais en dessiner sans &lt;br /&gt;passer par des images pré-dessinées pour pouvoir représenter des lasers à &lt;br /&gt;longueurs variables ou différentes choses (effets visuels) destinées à &lt;br /&gt;évoluer selon la situation de jeu. Comme un système de particule, de la &lt;br /&gt;pluie, etc. Sauf que malgré tous mes efforts, les formes n’étaient pas &lt;br /&gt;rendues à l’écran. Personne ne semblait avoir de solution à ce problème, &lt;br /&gt;ce qui est relativement rare sur le web. Voici ma solution : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;public void gameRender2(){&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;EnemyFireManager2.INSTANCE.displayGL();&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;cWhiteTexture32x32.bind();&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glBegin(GL11.GL_POLYGON);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; float color = 1f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glColor4f(color, color, color, 1f);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(position.getStepX() + 0.0f, position.getStepY() + 0.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(position.getStepX() + 0.0f, position.getStepY() + 30.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(position.getStepX() + 40.0f, position.getStepY() + 30.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(position.getStepX() + 60.0f, position.getStepY() + 15.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(position.getStepX() + 40.0f, position.getStepY() + 0.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glEnd();&lt;br /&gt;&lt;br /&gt;GL11.glPushMatrix();&lt;br /&gt;GL11.glColor3f(1f,1f,1f);&lt;br /&gt;GL11.glBegin(GL11.GL_LINES);&lt;br /&gt;GL11.glVertex2f(100.0f, 100.0f); // origin of the FIRST line&lt;br /&gt;GL11.glVertex2f(300.0f, 140.0f); // ending point of the FIRST line&lt;br /&gt;GL11.glVertex2f(120.0f, 170.0f); // origin of the SECOND line&lt;br /&gt;GL11.glVertex2f(540.0f, 120.0f); // ending point of the SECOND line&lt;br /&gt;GL11.glEnd( );&lt;br /&gt;GL11.glPopMatrix();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int factor = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; firePress; i++) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; factor = i * 60;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glBegin(GL11.GL_TRIANGLE_FAN);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glColor4f(color1, color2, color3, 1f); // 0 et 1.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(x + factor, y);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int angle = 0; angle &amp;lt; 400; angle += 40) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glVertex2f(x + factor + Trigo.sin(angle) * (radius + factor/10), y + Trigo.cos(angle) * (radius + factor/10));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GL11.glEnd();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; // fin de la méthode.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Il s’agit de ma méthode d’affichage des éléments de jeu dans ma classe &lt;br /&gt;principale. Évidemment, elle n’est pas complète. C’est cette ligne qui &lt;br /&gt;s’occupe d’afficher les projectiles : &lt;br /&gt;&lt;b&gt;EnemyFireManager2.INSTANCE.displayGL();&lt;/b&gt;. Tout fonctionnait &lt;br /&gt;correctement pour l’affichage de formes texturées, mais les primitives ne &lt;br /&gt;s’affichaient pas. Jusqu’à ce que j’ajoute la ligne suivante : &lt;br /&gt;&lt;b&gt;cWhiteTexture32x32.bind();&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Mon raisonnement est le suivant, les primitives semblent exister puisque &lt;br /&gt;lorsque l’écran est pollué d’images (projectiles), la forme des &lt;br /&gt;primitives est parfois visible (noir sur fond noir). Et ce même si je &lt;br /&gt;demandais que les primitives soient colorées en blanc. Je me suis demandé &lt;br /&gt;alors, si le problème ne venait pas du fait que ces formes n’avaient pas &lt;br /&gt;de textures. En fait c’était un peu comme peindre sur du vide. Alors, &lt;br /&gt;j’ai simplement créé une texture 32x32 blanche. Tout simplement. Un carré &lt;br /&gt;blanc. Que j’ai chargé, et que j’ai « bindé » avant le rendu des &lt;br /&gt;primitives. Ligne : &lt;b&gt;cWhiteTexture32x32.bind();&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;Et bien, j’avoue que sans trop savoir pourquoi, les formes ont étés &lt;br /&gt;dessinées exactement comme je le souhaitais par la suite. Avec la couleur &lt;br /&gt;que je souhaitais. Peut importe que le carré soit blanc ou non. La &lt;br /&gt;couleur venait de GL11.glColor3f ou GL11.glColor4f. En plus, j’ai lié la &lt;br /&gt;texture à OpenGL qu’une fois. Toutes les primitives, même les lignes ont &lt;br /&gt;été rendus adéquatement. Je n’ai pas encore fini mon expérimentation, &lt;br /&gt;mais je suis convaincu que je pourrai appliquer des effets de &lt;br /&gt;transparence ou de brouillage à mes formes. &lt;br /&gt;&lt;br /&gt;Enfin, je suis bien content. C’est le mystère du fantôme blanc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-722504665979621043?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/722504665979621043/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/10/ghost-mysteries.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/722504665979621043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/722504665979621043'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/10/ghost-mysteries.html' title='Ghost Mysteries'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-7853495832190053382</id><published>2010-10-01T00:21:00.001-07:00</published><updated>2010-10-01T00:28:19.598-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='AI'/><category scheme='http://www.blogger.com/atom/ns#' term='Kevin Glass'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>Sur la bonne voie??</title><content type='html'>&lt;div class="Section1"&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Enfin l'automne est arrivé. Fini les belles chaleurs, les BBQ, la piscine. Bonjour le désir de pitonner sur l'ordi avec un petit café à ses côtés. Et hourra pour un des petits monstres qui a recommencé la garderie. Avec la fraicheur automnale et un peu plus de temps à soi, les idées, les solutions, les plans d'attaques et surtout, la motivation reviennent.&amp;nbsp; Mais suis-je pour autant sur la bonne voie?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span lang="FR-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Je me suis attaqué à mon problème d'affichage des images en utilisant OpenGL. La dernière fois, j'avais pas mal terminé le gros de la refonte de ma classe principale de chargement des images mais lors des tests, il ne se passait rien. Ma technique était basée sur celle utilisée par Sanglard et elle avait le défaut de ne pas dessiner les images de la même manière dépendamment de la version de java utilisée. J'ai donc trouvé sur le web un exemple utilisant LWJGL écrit par &lt;a href="http://www.cokeandcode.com/kevsblog"&gt;Kevin Glass&lt;/a&gt; qui semble correspondre à mes besoins. Dans son code, il y a une section qui convertit les images chargées dans le bon format pour OpenGL. J'espère que cette conversion réglera le problème de l'affichage inconsistant. J'ai à nouveau fait une refonte de la classe de chargement des images. J'ai déjà fait un test ou deux et j'avoue que ça n'a pas marché. Le problème semble se produire quand vient le temps d'afficher l'image, à ce moment, java pointe sur un objet null. De plus, avec la technique de Glass, le chargement des images est long, trop long. Ça va pour les petites images mais pour mon background, j'utilise une scène spatiale qui est une grande image dont seule la portion visible sera dessinée. Le chargement de cette image ne prend pas loin de 30 secondes à elle seule. Je ne m'acharnerai pas trop sur ce problème car à mon avis, s'en est un d'optimisation. Je suis quand même allé voir sur le web, et il semble y avoir un consensus général qui dit que c'est une très mauvaise idée d'utiliser d'énormes images pour des arrière-plans. Il est préférable de séparer l'image en plusieurs petites. Comme un casse-tête. Ainsi, on dessine les images que l'on a besoin, et la même petite image peut être utilisée à plus d'un endroit à la fois. Ce qui diminue la charge sur les composants vidéo. Plus tard, j'optimiserai mes backgrounds pour qu'ils utilisent cette technique.&lt;br /&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Une autre chose que je désirais faire et qui a bien avancée, est une petite application Excel qui extrait les données emmagasinées dans le fichier hprof généré par le profileur java. Ça serait déjà terminé si je n'avais pas eu la fantaisie d'ajouter une section qui gère les fichiers .bat (commandes DOS). J'ai toujours trouvé que c'était pénible à gérer ce genre de fichier. Ainsi, avec cette application, je pourrai avoir plusieurs fichiers de commandes sous la main selon que je veuille faire rouler le programme en mode profilage, avec optimisation du GC ou en mode production. Et les graphiques Excel montreront l'état de la mémoire de la JVM, les classes et méthodes les plus utilisés, etc.&amp;nbsp; En plus, cette application est indépendante du programme, ce qui veut dire qu'elle peut fonctionner avec tout programme java.&lt;br /&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Afin de poursuivre mon cheminement en informatique, je me suis finalement réinscris à un cours à la TELUQ. Au début je voulais suivre un cours sur les bases de données, mais ça fait au moins 100 ans qu'il est indisponible. Il était sensé être prêt pour l'automne mais il ne l'est pas. J'ai donc pris, un peu à contrecœur, un cours sur l'intelligence artificielle. Et, à bien y repenser, ce cours me sera 10 fois plus utile pour mon projet que les DB. Enfin j'espère, car j'ai lu les premiers chapitres et je trouve que ça date un peu, que l'approche démontrée est du genre&amp;nbsp;: poser une question à l'ordi et il répondra adéquatement. Ce n'est pas très impressionnant. Il s'agit juste de monter une DB et de l'interroger. Et selon certaines règles préprogrammées, l'ordinateur fournira une réponse ou une autre question. Un système expert, quoi.&amp;nbsp; J'envisageais plus la simulation des comportements humains. Par exemple&amp;nbsp;: le chasseur et la proie. Comment décrire leurs comportements pour que l'interaction entre eux soit plausible. Comment faire pour que le chasseur pose des pièges pertinents et que la proie ne tombe pas nécessairement dedans à tous coups&amp;nbsp;? Ou plus modestement, la proie se sauve en x,y , le chasseur converge alors vers x,y aussi. Sauf que si la proie est en mesure de menacer le chasseur, celui-ci se met à l'affut jusqu'à ce qu'une possibilité de capture se présente. Le cours ne semble pas traité de ce genre de choses. Mais ce n'est pas grave, c'est un cours de base dont je pourrai certainement utiliser les préceptes pour les comportements de mes Sprites.&lt;br /&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Et finalement, juste une chose&amp;nbsp;: free sex. Ha, ben non, c'est une blague. C'est juste pour que les moteurs de recherche me trouvent plus facilement. Sérieusement, j'ai pensé à mon projet de fin de certificat. Un éditeur de niveau. Faire un jeu fonctionnel me paraît irréaliste étant donné les problèmes qui me reste à surmonter et le temps que je peu y consacrer. Mais un éditeur de niveau me sera très utile, et me semble assez complexe pour être un projet valide. Il faudra juste convaincre mon futur tuteur. Comment&amp;nbsp;??? Free sex&amp;nbsp;!&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-7853495832190053382?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/7853495832190053382/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/10/sur-la-bonne-voie.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7853495832190053382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7853495832190053382'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/10/sur-la-bonne-voie.html' title='Sur la bonne voie??'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-6900259921210226471</id><published>2010-08-08T05:31:00.000-07:00</published><updated>2010-08-08T05:31:12.667-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gdd'/><category scheme='http://www.blogger.com/atom/ns#' term='Conjure'/><category scheme='http://www.blogger.com/atom/ns#' term='concept'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Design time!!</title><content type='html'>La traduction du document de conception élaborée par l’équipe de Conjure &lt;br /&gt;est terminée. Le but de l’opération était de produire un document en &lt;br /&gt;français et de bien saisir la nature du document et son utilité. En le &lt;br /&gt;traduisant, je l’ai étudié en détail et j’ai pu y déceler quelques &lt;br /&gt;lacunes que je tenterai d’améliorer plus tard. Le document est disponible &lt;br /&gt;&lt;a href="http://indie-darkange.blogspot.com/p/document-de-conception.html"&gt;ici &lt;/a&gt;sous un format PDF. J’y référerai sous l’acronyme GDD pour « game &lt;br /&gt;design document ».&lt;br /&gt;&lt;br /&gt;Mais, à quoi sert-il? Ce document sert de support à la conception du jeu. &lt;br /&gt;De cette façon, ceux qui devront travailler sur le jeu pourront toujours &lt;br /&gt;s’y rapporter et ainsi travailler dans le même sens des autres &lt;br /&gt;développeurs. Lorsque le projet est plus personnel et que le concept &lt;br /&gt;d’équipe se limite à une personne, le GDD permet au développeur de &lt;br /&gt;&lt;b&gt;demeurer sur la bonne voix et d’atteindre ces objectifs plus &lt;br /&gt;rapidement.&lt;/b&gt; Autrement dit, en mettant ces idées sur papier dès le &lt;br /&gt;départ, le développeur sera plus enclin à implémenter ce qui a été décidé &lt;br /&gt;au début du projet. Sans cela, il est facile d’avoir toutes sortes de « &lt;br /&gt;&lt;i&gt;bonnes&lt;/i&gt; » idées et de développer dans une direction puis dans une &lt;br /&gt;autre et finalement, n’aboutir à rien. De plus, en élaborant la &lt;br /&gt;conception tôt, on peut facilement évaluer si une idée tardive risque &lt;br /&gt;d’entrer en conflit avec ce qui a déjà été établit. Par exemple : Si je &lt;br /&gt;décide d’implanter un module d’invincibilité à mon vaisseau en fin de &lt;br /&gt;développement, est-ce que cette nouvelle capacité rendra les combats trop &lt;br /&gt;faciles? Est-ce que je devrai implémenter de nouvelles caractéristiques &lt;br /&gt;aux ennemis? Si oui, peut-être serait-il préférable d’en faire un « cheat &lt;br /&gt;»?&lt;br /&gt;&lt;br /&gt;Il est donc très important de bien penser la conception de son projet et &lt;br /&gt;de tout mettre par écrit. Ainsi, les risques de s’écarter et de perte de &lt;br /&gt;temps sont diminués. Aussi, les idées que l’on a déjà eu ne sont plus &lt;br /&gt;oubliées. C’est l’erreur que j’ai commise. Cela fait longtemps que ce &lt;br /&gt;projet me trotte dans la tête, j’ai une bonne idée de la mécanique du jeu &lt;br /&gt;mais en ce qui concerne l’histoire, les ennemis, les personnages, etc. &lt;br /&gt;C’est plutôt vague. J’ai eu des idées que j’ai notées par-ci par-là, mais &lt;br /&gt;je ne saurais les retrouver. Alors quand je pense à mon jeu, il m’arrive &lt;br /&gt;parfois d’avoir 2 ou 3 fois la même idée géniale. Si j’avais élaboré un &lt;br /&gt;bon GDD, je n’aurais probablement pas ces problèmes. Et je me serais &lt;br /&gt;probablement aperçu que certaines idées ne tenaient pas la route et que &lt;br /&gt;d’autres méritaient une attention plus approfondie. J’aurais pu aussi &lt;br /&gt;noter les musiques, les concepts de sprites, etc. sur le GDD au lieu de &lt;br /&gt;noter tout ça sur des post-it qui sont perdus depuis belle lurette. En &lt;br /&gt;fait, il s’agit d’organiser le travail afin d’éviter toute forme de perte &lt;br /&gt;de temps et de procrastination possible. Les problèmes techniques sont &lt;br /&gt;déjà pénibles en soit, ça ne sert à rien d’en rajouter avec des concepts &lt;br /&gt;qui n’existent que dans ma tête. C’est la paresse qui m’a mené dans cette &lt;br /&gt;situation de cafouillis. Car la tâche que représente l’élaboration du GDD &lt;br /&gt;est énorme.&lt;br /&gt;&lt;br /&gt;Certes, élaborer le GDD n’est pas facile. Si l’on en croit l’équipe de &lt;br /&gt;Conjure, il faudrait y mettre absolument tout ce qui concerne le jeu qui &lt;br /&gt;sera développé, avec le plus de détails possible. Je ne suis pas d’accord &lt;br /&gt;avec cette approche. Ils ont une vision trop stricte du GDD, à mon avis &lt;br /&gt;il faut que le jeu puisse évoluer. Évidemment, il est préférable de &lt;br /&gt;décider dès le début du type de jeu que l’on veut, dès règles qui &lt;br /&gt;régiront l’univers du jeu, des mécanismes de jouabilité, etc. Changer la &lt;br /&gt;moindre de ces petites choses en cours de développement risque d’avoir un &lt;br /&gt;impact important sur le reste des éléments constituants le jeu. Il faut &lt;br /&gt;prendre le temps de bien y penser pour ne pas regretter ses choix plus &lt;br /&gt;tard. Car si on efface et on recommence, c’est beaucoup de temps de &lt;br /&gt;perdu. Mais en même temps, il faut rester flexible. C’est au niveau &lt;br /&gt;conceptuel, justement, que l’on peut se laisser une plus grande marge de &lt;br /&gt;manœuvre. Une fois les règles et les mécanismes gérant le jeu bien &lt;br /&gt;établi, on peut concevoir le jeu avec un minimum de niveaux, quelques &lt;br /&gt;ennemis, une histoire écrite dans les grandes lignes, etc. Avec le temps, &lt;br /&gt;d’autres idées viendront et il sera facile de les intégrées en autant que &lt;br /&gt;l’on respecte les règles établies. Tout prévoir à l’avance est &lt;br /&gt;pratiquement infaisable. À moins de conserver les nouvelles idées pour &lt;br /&gt;une éventuelle suite. &lt;br /&gt;&lt;br /&gt;Et malgré que le GDD de Conjure me semble complet, j’ai trouvé que son &lt;br /&gt;organisation restait obscure. Le lecteur peut facilement s’y perdre, les &lt;br /&gt;mêmes éléments se retrouvent dans différentes catégories, par exemple on &lt;br /&gt;peut retrouver les personnages autant dans la catégorie histoire, que &lt;br /&gt;dans l’art ou la jouabilité. Peut être qu’un découpage en faisant de &lt;br /&gt;&lt;br /&gt;personnage une catégorie décrivant tout les points mentionnés serait plus &lt;br /&gt;lisible? J’ai aussi l’impression que le document pourrait avoir une ou &lt;br /&gt;deux sections de plus, tel que les obstacles à surmonter, les conflits en &lt;br /&gt;jeu, etc. Ou encore, inclure des modèles de conception de personnages, de &lt;br /&gt;niveaux, de ressources, etc. Les possibilités sont nombreuses. Justement, &lt;br /&gt;le danger est de rendre le document trop lourd. Trop lourd à produire, ce &lt;br /&gt;qui fait que le jeu sera trop difficile à développer et par conséquent, &lt;br /&gt;il ne verra probablement jamais la lumière au bout du tunnel. Toutefois, &lt;br /&gt;il est plus facile de ne pas implémenter une idée qui a été pensée &lt;br /&gt;qu’essayer d’ajouter une idée dont on n’a pas réfléchie aux conséquences &lt;br /&gt;qu’elle aurait sur le reste du jeu. Si une idée est rejetée, on n’a qu’à &lt;br /&gt;la noter comme étant rejetée et expliquer la raison.&lt;br /&gt;&lt;br /&gt;En fin de compte, pour un développeur seul, il faut apprendre à gérer son &lt;br /&gt;temps. En consacrer trop à la conception, c’est en consacrer moins à la &lt;br /&gt;production. Mais une idée notée, est une idée qui n’est pas oubliée.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-6900259921210226471?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/6900259921210226471/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/08/design-time.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/6900259921210226471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/6900259921210226471'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/08/design-time.html' title='Design time!!'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-7239049023300916517</id><published>2010-07-27T20:44:00.000-07:00</published><updated>2010-07-27T20:44:55.652-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gdd'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><title type='text'>Motivation - Part II</title><content type='html'>Le temps passe. L’été passe. Saleté d’été. Bien sur, pour la baignade, le BBQ, les belles soirées, ça baigne. Avec ce temps, mon ordinateur me dégoute quasiment. Mais l’été achève, les vacances aussi et le travail reprendra. Au début août, je retourne dans mon labo à jouer les chasseurs de fantômes. Au moins, la routine va revenir et j’aurai plus tendance à passer du temps devant mon ordi. D’ailleurs, le seul fait de devoir retourner gagner ma pitance, me pousse à continuer mon projet. J’ai l’impression d’avoir perdu du temps précieux et par conséquent, je dois redoubler d’effort. Je me suis donc remis à l’élaboration/traduction du document de conception. &lt;br /&gt;&lt;br /&gt;D’abord, le soir c’est difficile. Morphée vient me visiter à chaque fois. Et paradoxalement, je lézarde devant la télé jusqu’à minuit, 1h. Et bien, ma productivité et ma motivation va passer, je crois, par un changement d’horaire. Maintenant, je me couche plus tôt et je me lève en même temps que mon fils. Alors pendant qu’il écoute ces bonhommes, je pitonne. À date, ça marche pour moi.&lt;br /&gt;&lt;br /&gt;Mon objectif à court terme est de respecter cet horaire plus sain et de terminer la préparation du document de conception dans sa forme « modèle ». Ainsi, je pourrai utiliser ce document pour mettre sur papier la conception de mon jeu à partir de chez moi, ou d’ailleurs. En fait la seul tâche que je ne peux faire qu’avec mon ordi, est la programmation pure et dure. Parce que mon ordi est configurer avec tout un paquet de cossins qui m’aide au développement et j’utilise aussi un tas de librairies qui ne sont pas incluses dans le Java de base. Juste penser à programmer dans un nouvel environnement, me donne mal à la tête. Je n’ai donc pas vraiment de raisons de procrastiner dans les prochains jours, voir les prochaines semaines.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-7239049023300916517?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/7239049023300916517/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/07/motivation-part-ii.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7239049023300916517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/7239049023300916517'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/07/motivation-part-ii.html' title='Motivation - Part II'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-4599135414008531022</id><published>2010-05-23T22:59:00.001-07:00</published><updated>2010-05-26T10:10:09.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphisme'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>Motivation  – part 1</title><content type='html'>&lt;div class="Section1"&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;J'ai intitulé ce billet  «&amp;nbsp;Motivation – Part I&amp;nbsp;» parce que j'ai un sérieux manque  de motivation pour poursuivre mon projet et aussi, je sens que ce manque de  motivation va se pointer régulièrement. D'où le «&amp;nbsp;Part I&amp;nbsp;».  Tout de même, j'espère que ça n'arrivera pas trop souvent. Car, je  devrai alors me questionner sur mon désir réel de continuer la programmation et  la conception d'un jeu.&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Ce manque de motivation est en grande  partie dû à l'irrégularité du temps que je consacre sur mon projet ces  temps-ci. Il serait plus honnête de dire que je n'y travail presque plus.  La belle saison y est pour quelque chose. J'avais prévu d'autres  projets personnels (patio) au mois de Mai que j'ai à peine terminé.  Depuis le début du mois, tous mes temps libres ont été consacrés à la  réalisation de ce projet. Du matin jusqu'en fin de journée. Et comme  c'était assez physique, arrivé le soir, j'avais énormément de  difficulté à me concentrer sur l'écran de mon ordi. En plus, ont  m'a demandé d'interrompre encore une fois mon congé parental, ce  qui a mis nécessairement un frein à mon jeu. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Avant de travailler sur mon patio,  j'ai eu des problèmes techniques dans le passage à OpenGL dans le  développement de mon projet. Après avoir réussi à initialiser OpenGL  correctement dans mon jeu, je me suis attaqué à la gestion des inputs (i.e.  clavier, souris et manette de jeu). Cette étape c'est assez bien passé  quoique je suis conscient qu'il restera de l'optimisation à faire  plus tard. Il fallait que je règle le problème de la gestion des  entrées/sorties avant d'aller plus loin tout simplement pour pouvoir  arrêter le programme lors de mes tests. Sans gestions des inputs, je ne pouvais  même plus faire «&amp;nbsp;escape&amp;nbsp;» pour quitter. Suite à cette étape,  j'ai réécrits la classe de chargement des graphiques afin qu'elle  gère les textures qui sont requises par OpenGL. Lors des tests, ça n'a  pas fonctionné. Quelle surprise! Ne comprenant pas la raison de cette  défaillance, je suis retourné au programme de Sanglard sur lequel mon  algorithme est basé, afin de tester plus aisément le chargement des textures.  J'ai donc lancé son programme mais avec mes graphiques. Surprise, ça ne  marche pas non plus. Une de mes textures devait donc être la cause du bug.  Après investigations, j'ai découvert que le ciel étoilé que  j'utilise comme fond d'écran ne comporte pas de canal alpha (la  transparence). Ce qui veut dire que chaque pixel de l'image contient  trois canaux qui sont respectivement le rouge, le vert et le bleu (RGB). En terme  informatique, chaque pixel contient 3 octets. L'algorithme de chargement  demande obligatoirement que les images contiennent 4 octets, le quatrième étant  le canal alpha. Ceci étant établi, du moins en tant qu'hypothèse,  j'ai retravaillé l'image pour y inclure le fameux canal alpha. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Cette modification à l'image a réglé  ce problème, mais comble de malheur, l'apparence de l'image dans le  jeu n'était pas du tout ce que j'espérais. Mon ciel étoilé a été  conçu avec une dimension de 1024 x 768 pixels ce qui est la même taille que la  surface de jeu demandée. Je m'attendais donc à ce que le l'image  couvre le fond du jeu parfaitement, mais non. Pourquoi ça serait si  simple…. Il apparaît plus gros et en plus, il apparaît sous forme de  mosaïque à quatre sections. J'ai quelques pistes à explorer pour régler  ça, mais je n'ai pas encore eu le temps de m'y mettre sérieusement.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="FR-CA"&gt;Ce genre de problèmes inattendus me sape  complètement la motivation. Ça me fait ch… carrément. Surtout, j'ai  l'impression que je n'ai peut-être pas pris la meilleure avenue en  utilisant OpenGL pour régler mon problème de performance. J'aurais  peut-être dû investiguer ailleurs avant de prendre une décision précipitée.  Maintenant, tout mon code est chamboulé. Tant pis, il faut que je vivre avec  mes choix.&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Cambria&amp;quot;,&amp;quot;serif&amp;quot;;"&gt;(&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang="EN-US" style="font-family: &amp;quot;MS Mincho&amp;quot;;"&gt;◣&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Cambria&amp;quot;,&amp;quot;serif&amp;quot;;"&gt;_&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang="EN-US" style="font-family: &amp;quot;MS Mincho&amp;quot;;"&gt;◢&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Cambria&amp;quot;,&amp;quot;serif&amp;quot;;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;En terminant, j'ai apporté quelques modifications à la  structure du blog. Notamment une zone permanente comprenant les sections  majeures du blog. Tel que la section «&amp;nbsp;download, commentaires, suggestion  de livres, etc.&amp;nbsp;». Actuellement, la plupart des sections sont vides, mais  j'espère bien les remplir au fil du temps. La section qui risque de  rester vide le plus longtemps est sans conteste celle intitulée  «&amp;nbsp;Démo&amp;nbsp;»… Patience, patience, patience.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;-- Post via email.&lt;span lang="FR-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-4599135414008531022?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/4599135414008531022/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/motivation-part-1.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4599135414008531022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4599135414008531022'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/motivation-part-1.html' title='Motivation  – part 1'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-3262292255173600876</id><published>2010-05-22T19:34:00.001-07:00</published><updated>2010-05-22T19:34:24.689-07:00</updated><title type='text'>Jeux inspirants</title><content type='html'>&lt;div class=Section1&gt;  &lt;p class=MsoNormal&gt;&lt;span lang=FR-CA&gt;À venir.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-3262292255173600876?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/3262292255173600876/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/jeux-inspirants.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/3262292255173600876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/3262292255173600876'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/jeux-inspirants.html' title='Jeux inspirants'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-5011092241750965048</id><published>2010-05-22T19:31:00.001-07:00</published><updated>2010-05-22T19:31:43.076-07:00</updated><title type='text'>Commentaires</title><content type='html'>&lt;div class=Section1&gt;  &lt;p class=MsoNormal&gt;&lt;span lang=FR-CA&gt;Cet endroit est destiné à recevoir vos commentaires sur le blog en général. Je répondrai à tout les commentaires intelligents. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=MsoNormal&gt;&lt;span lang=FR-CA&gt;Vous pouvez également laisser vos suggestions ou vos idées concernant la conception du jeu.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-5011092241750965048?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/5011092241750965048/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/commentaires.html#comment-form' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5011092241750965048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5011092241750965048'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/commentaires.html' title='Commentaires'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-889874135688816892</id><published>2010-05-22T19:23:00.001-07:00</published><updated>2010-05-22T19:23:28.031-07:00</updated><title type='text'>Suggestion de livres</title><content type='html'>&lt;div class=Section1&gt;  &lt;p class=MsoNormal&gt;&lt;span lang=FR-CA&gt;À venir.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-889874135688816892?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/889874135688816892/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/suggestion-de-livres.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/889874135688816892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/889874135688816892'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/suggestion-de-livres.html' title='Suggestion de livres'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-4060703496769913829</id><published>2010-05-22T19:17:00.001-07:00</published><updated>2010-06-05T14:06:54.092-07:00</updated><title type='text'>To Do list</title><content type='html'>Cette section est une sorte de liste des tâches que je dois réaliser pour faire avancer mon projet. Certaine de ces tâches sont globales dans le sens qu’elles ne seront jamais vraiment terminées. Par exemple, le fait d’en apprendre toujours un peu sur les techniques de programmation. D’autres tâches sont pointues et représentent des objectifs clairs à atteindre dans un avenir plus ou moins rapproché.&lt;br/&gt;&lt;br /&gt;La liste est organisée alphabétiquement.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;h3&gt;Concevoir le document de conception de Kradius.&lt;/h3&gt;&lt;desc&gt;Le document de conception est la base sur laquelle le jeu sera conçu. Avant de plonger dans le gameplay et le scénario, un document de conception doit être fait afin de respecter une ligne directrice tout au long du développement.&lt;/desc&gt;&lt;br/&gt;&lt;br /&gt;&lt;priority&gt;Priorité : MOYENNE ----- Mise à jour le : 5 Juin 2010&lt;/priority&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;h3&gt;Dessiner, dessiner et dessiner&lt;/h3&gt;&lt;desc&gt;Sans pratique, le graphisme du jeu risque d’en souffrir sérieusement.&lt;/desc&gt;&lt;br/&gt;&lt;br /&gt;&lt;priority&gt;Priorité : MOYENNE ----- Mise à jour le : 5 Juin 2010&lt;/priority&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;h3&gt;Prendre un cours sur l’intelligence artificiel.&lt;/h3&gt;&lt;desc&gt;Cours à la TELUQ faisant partie du certificat en informatique. Son contenu devrait aider à l’élaboration des routines simulant l’intelligence des entités du jeu.&lt;/desc&gt;&lt;br/&gt;&lt;br /&gt;&lt;priority&gt;Priorité : MOYENNE ----- Mise à jour le : 5 Juin 2010&lt;/priority&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;h3&gt;Rédiger un outil d’interprétation des lectures de performance de java.&lt;/h3&gt;&lt;desc&gt;HPROF est un outil java qui donne un portrait des performances d’un programme. Toutefois sa compréhension est ardue puisque le rapport généré est sous forme de texte et donc peu visuel. À l’aide de Visual Basic et d’Excel, il serait possible de manipuler ce rapport ainsi que les informations des logs pour produire des graphiques de performances plus significatifs.&lt;/desc&gt;&lt;br/&gt;&lt;br /&gt;&lt;priority&gt;Priorité : BASSE ----- Mise à jour le : 5 Juin 2010&lt;/priority&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;h3&gt;Régler le problème d’affichage des textures via openGL.&lt;/h3&gt;&lt;desc&gt;Actuellement, les textures s’affichent déformées. Avant de pouvoir aller de l’avant dans la programmation, ce problème doit être résolu.&lt;/desc&gt;&lt;br/&gt;&lt;br /&gt;&lt;priority&gt;Priorité : HAUTE ----- Mise à jour le : 5 Juin 2010&lt;/priority&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-4060703496769913829?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/4060703496769913829/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/to-do-list.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4060703496769913829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4060703496769913829'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/05/to-do-list.html' title='To Do list'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-2159773280810136594</id><published>2010-04-18T08:05:00.000-07:00</published><updated>2010-04-18T08:06:36.165-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Slick2D'/><category scheme='http://www.blogger.com/atom/ns#' term='Fabien Sanglard'/><category scheme='http://www.blogger.com/atom/ns#' term='jogl'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>Happy or not API.</title><content type='html'>J’ai été tranquille sur le blog dernièrement. Nous sommes allés nous dorer la couaine au Lac. Il faisait au moins 50 à l’ombre. Certains palmiers commençaient à nous balancer des noix de cocos. Nous avons fait pleins de belles activités comme présenter Godzilla à son arrière Grand-père. Ces vacances m’ont fait du bien, car juste avant de partir, mon jeu m’a fortement contrarié. Et depuis ce temps, je me suis résigné à me tourner vers d’autres techniques. Alors, am I Happy or not API.&lt;br /&gt;Le problème : Tout allait bien dans mon jeu, j’avais atteint un nombre raisonnable d’entités à l’écran sans grande dégradation des performances. Pour pousser la machine un peu plus, j’ai voulu faire défiler mon décor à des vitesses ridicules. En situation de jeu on peut penser à des scènes ou le vaisseau du joueur tente de se sauver d’une base ennemie en train d’exploser. Alors là, tout va vite. Les ennemis sont rares ou absents, il n’y a que le décor qui pète de partout et qui se met inlassablement dans le chemin du joueur. Le tout défile à vitesse grand G afin de créer l’illusion que le joueur a poussé les réacteurs de sa machine à fond. Sauf que, techniquement ça ne vas pas. Quand le décor défile rapidement, il arrive un moment dans l’animation ou le décor n’est pas dessiner ou il devrait l’être. Il y a comme un effet de réfraction. La réfraction c’est ce que l’on observe quand on plonge une paille dans un vers d’eau et qu’elle semble plié au niveau de la surface. En termes de performance, cela ressemble à un phénomène de « hitching ». Autrement dit quand un objet arrête son mouvement momentanément et continue par la suite. Dans mon cas je soupçonne cette dégradation de performance être dû à l’action du « Garbage Collector » qui demande quand même pas mal de ressource en java. Et contrairement au C, on ne peut pas contrôler son action de façon programmatique et implicite. Je soupçonne aussi le fait d’utiliser des « BufferedImage » comme matière première au graphisme, d’être un choix mal approprié à des applications graphiques intenses. Quoique je n’en suis pas sûr, je présume que les actions sur les « BufferedImage » sont gérées au niveau du CPU et non du GPU. Le processeur graphique. Le CPU est le cœur de tout ordinateur, il est doué pour les calculs. Tandis que le GPU est la carte graphique du système que ce soit Radeon, ATI, AMD, etc. Ce dernier traite le graphisme de façon optimale. DirectX et OpenGL sont traités par le GPU laissant plus de ressources au CPU. &lt;br /&gt;&lt;br /&gt;En partant de là, j’ai effectué plusieurs tests pour modifier le comportement du « Garbage Collector », sans succès. Je me suis donc tourné vers OpenGL. Selon plusieurs commentaires dans les forums, il semblait très rapide au niveau de la performance. J’avais toujours cru que la technologie OpenGL n’était que pour le 3D, mais non, je me suis trompé. Sauf, que la programmation d’OpenGL est très différente de ce que je suis habitué. En GL, on travaille avec une seule instance globale pour tout le programme. Ça va un peu à l’encontre de la philosophie objet. J’avais quelques réticences à me lancer dans l’apprentissage de GL parce qu’en fait, je n’ai aucune certitudes que cela va régler mon problème. Car mon foutue problème peut être tout simplement dû à une erreur algorithmique… Et dans ce cas, aucune technologie miracle ne va m’aider. N’empêche qu’apprendre OpenGL, m’ouvre les portes aux principes de programmations plus modernes et à l’apprentissage du 3D. Et c’est exactement là que j’en suis. J’ai lu de la documentation sur OpenGL ainsi que des exemples de programmations que j’ai tenté de recréer. Pour utiliser OpenGL&amp;nbsp; en java, il faut passer par la bibliothèque de programmation (API) jogl. Jogl est une interface java qui fait le lien avec les fonctions natives d’OpenGL. Jogl respectent la syntaxe mot pour mot de OpenGL. Ceci rend les exemples en OpenGL facilement transportables en java. N’empêche, à cause de ma carte graphique qui diffère de celle des exemples et aussi&amp;nbsp; à cause des différentes versions d’OpenGL, j’ai eu beaucoup de difficultés à obtenir des résultats semblables à Davison pour ne citer que lui. Davison utilisait jogl 1, et moi j’ai utilisé la dernière version qui était la 2 quelque chose. J’ai fini par laisser tomber…&lt;br /&gt;&lt;br /&gt;J’ai alors essayé le jeu de &lt;a href="http://www.fabiensanglard.net/Prototyp/index.php"&gt;Fabien Sanglard&lt;/a&gt; que l’on peut trouver &lt;a href="http://www.fabiensanglard.net/Prototyp/prototyp.jnlp"&gt;ici&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;J’ai été impressionné. Après avoir téléchargé le code et que je l’ai fait rouler sur mon ordi, j’ai pu afficher 15000 entités avec détection des collisions et une performance acceptable de 30 fps. Vraiment, si OpenGL est derrière tout cela, son apprentissage en vaut la peine. Sauf que Sanglard est passé par l’api LWJGL ou light weight java game librairie. Il s’agit d’une librairie de classes java orienté jeu. Les concepteurs de cette API on voulu faire une bibliothèque ne contenant que le nécessaire à la programmation de jeu vidéo ce qui en fait une librairie assez simple. Remarquez que la simplicité est toujours relative. On peut avoir plus de classes spécifiques au développement de jeu en utilisant &lt;a href="http://slick.cokeandcode.com/index.php"&gt;Slick2D&lt;/a&gt; que je n’ai pas encore essayé et que je ne prévois pas nécessairement utiliser dans un avenir proche.&amp;nbsp; Je préfère développer mes propres outils afin de mieux comprendre leurs mécanismes. Quand j’aurai un jeu adéquat, je verrai ce que peut m’apporter &lt;a href="http://slick.cokeandcode.com/index.php"&gt;Slick2D&lt;/a&gt; ou pulpcore, qui contiennent déjà des classes spécifiques telles que les sprites ou les émetteurs de particules. LWJGL ce concentre vraiment sur l’affichage, OpenGL, l’interface avec l’usager (joystick), etc. C’est donc en me basant sur ce que Sanglard à fait que j’ai entamé la reconception de mes classes de gestions d’affichages, de chargements d’images, de sprites, etc. J’imagine que d’ici deux semaines je devrais être en mesure de tester à nouveau mon jeu. Et histoire de me compliquer la vie encore plus, il semble que les mises à jour de java 19 et 20 contiennent des bugs qui chargent les images&amp;nbsp; en AGBR plutôt qu’en RGBA. Ce qui rend le jeu exécrable. Voir le commentaire ici-bas de Sanglard : &lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue; font-size: small;"&gt;&lt;i&gt;April 5, 2010 : It seems there is an issue with the last JRE 1.6 on windows plateforms. ImageIO.read is loading PNGs as AGBR instead of RGBA. I am not sure if it's a JVM bug or if the PNG are not compliant and I lack time to investigate :/, if anyone have some time to investigate, feel free to email me !&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pour le moment je contourne le problème en spécifiant à la console java d’utiliser une version de la JRE antérieur à 19. Il faudra bien que je trouve une solution à ce problème un jour si je veux que mon jeu soit distribuable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-2159773280810136594?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/2159773280810136594/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/04/happy-or-not-api.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/2159773280810136594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/2159773280810136594'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/04/happy-or-not-api.html' title='Happy or not API.'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-6331745460705299939</id><published>2010-03-28T20:54:00.000-07:00</published><updated>2010-03-28T21:00:03.985-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shmup'/><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='Bullet Hell'/><category scheme='http://www.blogger.com/atom/ns#' term='Gradius'/><category scheme='http://www.blogger.com/atom/ns#' term='sprite'/><title type='text'>Bullet Hell</title><content type='html'>Cette semaine malgré la grippe et la gastro persistante de Godzilla, j’ai remanié mes sprites pour que leurs activités soient basées sur la géométrie vectorielle. Il me reste encore beaucoup de travail sur ce sujet. À partir de ma première implémentation de la classe Sprite, j’en ai fait une plus simple pour qu’elle puisse gérer les sprites sans animations. Avec une image en fait. Je voulais une sprite pouvant représenter un projectile simple et qu’il soit utilisable des milliers de fois à l’écran afin de pouvoir créer un « Bullet Hell » ou&amp;nbsp; &lt;a href="http://www.shmup.com/index.php?page=dico&amp;amp;id_affiche=26"&gt;"manic shooter".&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Avant de définir ce qu’est le « Bullet Hell », je dois expliquer à quel genre mon jeu appartient. Il s’agira d’un jeu basé sur &lt;a href="http://www.konami.com/screenshots/gradiusrebirth"&gt;Gradius&lt;/a&gt; de Konami. Dont voici une image : &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.konami.com/imgs/gradius-rebirth/screens/04.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="279" src="http://www.konami.com/imgs/gradius-rebirth/screens/04.jpg" width="400" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;On appel ce genre « 2D space shooter » ou « shoot’em up » ou encore « shmup ». Essentiellement, le joueur est représenté par un vaisseau spatial et il doit affronter vague après vague de d’engins ennemis. Le but étant de survivre jusqu’à la fin de la course. Pour survivre, le joueur doit détruire ses ennemis, ramasser les bonus laissés par ceux-ci et éviter le feu ennemi. Dépendamment du sous-genre, il y a des obstacles à éviter ce qui ajoute un élément de navigation. À la de chaque course, on rencontre un ennemi plus difficile à vaincre. Il s’agit du boss. Les « shmup » ce présentent généralement sous deux formes : avec action horizontale et action verticale. Ces formes réfèrent au défilement de l’action. Horizontale, le joueur progresse de gauche à droite et verticale, de haut en bas. J’ai choisi le mode horizontale parce qu’il offre plus de facilités pour la navigation entre les obstacles du terrain. Par contre, comme il y a plus d’obstacles à gérer, le système de détection de collision devient plus lourd ce qui peut limiter le nombre d’entités affichables à l’écran. Ceci, m’amène donc à parler du sous genre « Bullet Hell ».&lt;/div&gt;&lt;br /&gt;Un « Bullet Hell » est tout simplement un « shmup » où le joueur est littéralement submergé par le feu ennemi. Les projectiles sont déployés selon des patterns qui, à l’écran, donne un rendu presque artistique. Comme des feux d’artifices mettons. Le joueur doit ce frayer un chemin à travers cette pluie infernale et éliminer son adversaire. Cette vidéo montre exactement ce qu’est un « Bullet Hell ».&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/meegHdD0dAk&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/meegHdD0dAk&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Ce que l’on remarque d’abord, c’est que le gameplay est vertical. Cela semble faciliter la création de patterns pour les projectiles. C’est comme-ci elles formaient des fleurs ou des fractales. On remarque également qu’il y a très peu on pas d’obstacles ce qui facilite grandement la gestion des collisions. Le nombre d’entités actives autres que les projectiles, autrement dit les acteurs, est limité au joueur et son adversaire. Ce qui facilite encore le processus de collision. D’ailleurs dans la plupart des « Bullet Hell » que j’ai observés, le nombre de projectiles atteignait vraiment son maximum lors de combat avec les boss. Et en plus, il y a rarement des obstacles environnementaux pour compliquer la navigation. Certes, il y a des ennemis, mais ils ne sont pas calculés dans le système de collision avec leurs projectiles. Ce que je veux dire, c’est qu’on vérifie s’il y a collision entre le joueur et les ennemis et le feu ennemis. Mais pas entre les ennemis et le feu ennemis. Enfin, je ne sais pas trop comment l’expliquer, mais en regardant attentivement les vidéos, on peut voir que le feu ennemi passe à travers les autres ennemis. Ok, passons…&lt;br /&gt;&lt;br /&gt;En fait, on semble rechercher une chose. Maximiser le nombre de projectiles au détriment de l’environnement interactif. J’ai voulu essayer ce genre justement pour voir jusqu’à quel point je pouvais gérer une grande collection de projectiles, d’acteurs et d’obstacles. Si j’arrive à des résultats intéressant, je suis intimement persuadé que je pourrai faire n’importe quel autre jeu en 2D par la suite. &lt;br /&gt;&lt;br /&gt;À la suite de mes&amp;nbsp; recherches sur youtube pour trouver des démos de « Bullet Hell », j’ai trouvé également trouvé cette vidéo montrant le Gradius original remanié par un amateur.&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3guSWcma7VU&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3guSWcma7VU&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cette vidéo montre bien le gameplay original de Gradius. Par contre, l’auteur a voulu en faire un « Bullet Hell » et je ne crois pas qu’il a réussi. Comme je l’ai expliqué plus haut, le nombre de projectile devrait être beaucoup plus élevé, et à mon avis, on dépasse rarement la centaine. Par contre, l’auteur à implémenté un environnement navigable mais si vous regardez attentivement, vous verrez que les projectiles passent à travers les obstacles. Bien sur, il s’agit probablement d’un projet en cours de développement tout comme le mien. Mais quand l’auteur aura appliqué les fonctions de collisions de détections, les performances de son jeu ne seront plus les mêmes. Et il doit le faire, on ne peut pas permettre que les projectiles passent à travers les murs. S’il y a des murs, c’est pour aussi fournir au joueur une protection contre les balles.&lt;br /&gt;&lt;br /&gt;Revenons à nos moutons. Après plusieurs tests sur mon jeu, j’ai réussi à remplir mon écran avec des milliers de balles se déplaçant au hasard dans l’écran. Elles n’ont pas d’animations et ne gèrent pas les collisions. Voici une vidéo de mon jeu en action : &lt;br /&gt;&lt;br /&gt;Mon vidéo.&lt;br /&gt;&lt;object height="385" width="640"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FUsFXrCes78&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FUsFXrCes78&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;On voit d’abord la scène qui défile avec un arrière plan à thématique spatiale. L’avant plan est une série de briques qui forment l’environnement. Je les ai créées avec &lt;a href="http://tilestudio.sourceforge.net/"&gt;TileStudio&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Peu après, les premières balles apparaissent. J’en fais apparaître environ 2000 sans pertes de « frame rate ». À la fin, la scène en contient environ 10 000 avec un frame rate qui passe de 80 à 30. La scène est de 1000 x 600 pixels. On ne peut pas la voir en pleine grandeur avec le vidéo youtube. Il faut comprendre que c’est la première fois que je fais un "screencast" et le résultat est assez ordinaire. En réalité, l’animation est plus fluide et l’image plus claire. Par contre, je m’attendais à des résultats plus intéressants. J’aurais voulu atteindre au moins ce que Harbour a obtenu avec son démo de sprite mais sans succès. Il a pu afficher 10000 sprites sans problèmes apparents. Il n’y avait pas de statistiques affichées. Il faut dire que les conditions ne sont pas identiques. Son démo n’a pas d’arrière-plan, ni d’avant plan. Et ces sprites ne bougent pas. Toutefois, elles sont animées et plus grosses. À force de recherche sur le web, j’ai pu apporter quelques optimisation à la façon de faire le rendu de mes sprites, mais si je tiens à avoir une performance optimale, je crois que je devrai migrer mon programme vers JOGL qui est une API gérant OpenGL. Ça sera à voir. Pour le moment, je continue à développer avec les API standard de Java. Mais avec certaines optimisations et de bons choix de conception, je crois que je peux atteindre un résultat impressionnant.&lt;br /&gt;&lt;br /&gt;Parmi ces optimisations, je vais utiliser des managers pour les différentes catégories d’entités. Par exemple, j’ai créé la classe EnnemyFireManager qui contient une collection de 2000 balles. Le rôle du manager est de faire l’initialisation, la mise à jour du mouvement et les requêtes d’affichages de chaque balle. Le manager créé les objets balles à l’avance pour les utiliser plus rapidement. C’est lui aussi qui contient les images des projectiles. Il les affiches une fois que les balles ont été mises à jour. Ma classe est encore loin d’être optimale, mais j’ai l’impression que je suis sur la bonne voie.&lt;br /&gt;&lt;br /&gt;Il y a aussi des façons d’optimiser la vitesse des rendus dans java2D, mais ces optimisations sont au détriment de la qualité. Par exemple : une résolution plus faible. Ce qui implique moins de pixels à traiter, mais des images moins détaillées. Il y aura donc des compromis à faire. &lt;br /&gt;&lt;br /&gt;Au niveau du jeu, les situations vont décider de la quantité de balles qu’il sera possible d’afficher. Par exemple, dans l’introduction des courses. À la manière de Gradius, le joueur se trouve dans un environnement en plein espace, sans obstacles. Ces zones sont propices à plus d’acteurs ennemis, mais moins de balles puisque l’on est au début. Il faut respecter le tempo. Cela donne des situations ou le joueur doit détruire ses ennemis pour amasser un arsenal adéquat pour la suite. Il pourrait y avoir aussi des zones avec plus de terrains mais moins d’ennemis pour favoriser la navigation. Et quand sera venu le temps du « Bullet Hell » avec un joueur pleinement équipé, le terrain sera réduit au minimum ou carrément absent, avec peu d’ennemis et une tonne de balles. Tout est une question d’équilibre finalement.&lt;br /&gt;&lt;br /&gt;En terminant, voici un lien intéressant sur le genre « shoot’em up ». Il contient des jeux, des fiches techniques, un dictionnaire sur le monde du « shoot’em up » et plus encore. Mais attention, je soupçonne les jeux disponibles propices aux virus…&lt;br /&gt;&lt;a href="http://www.shmup.com/"&gt;http://www.shmup.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-6331745460705299939?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/6331745460705299939/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/bullet-hell.html#comment-form' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/6331745460705299939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/6331745460705299939'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/bullet-hell.html' title='Bullet Hell'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-5236846999537332725</id><published>2010-03-20T21:39:00.000-07:00</published><updated>2010-03-25T06:10:37.170-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulpcore'/><category scheme='http://www.blogger.com/atom/ns#' term='Jonathan Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='David Brackeen'/><category scheme='http://www.blogger.com/atom/ns#' term='Andrew Davison'/><category scheme='http://www.blogger.com/atom/ns#' term='sprite'/><title type='text'>Critique [Livre] – Advanced 2D Game Development, par Jonathan S. Harbour.</title><content type='html'>Cette semaine n’a pas été très productive. On a eu quelques épisodes de gastro dans la famille en plus de cette bonne vielle grippe qui est venue frapper à la porte. Heureusement, je suis vacciné contre le H1N1 et donc, je ne devrais pas mourir. Le monde a assez perdu de grands hommes comme ça!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Je dois dire que j’ai également perdu beaucoup de temps à repenser mon système de sprites. J’ai dû en effet, arrêter le développement du système de collision pour la simple et bonne raison que pour le tester, j’ai besoins de sprites. Hors, comme je l’ai déjà dit, elles n’étaient vraiment pas au point. J’ai effectué quelques recherches sur le web afin de trouver une bonne implémentation de sprite mais sans trop de succès. Ma meilleure référence vient du livre de &lt;a href="http://www.jharbour.com/"&gt;Harbour&lt;/a&gt;, Advanced 2D Game development. &lt;br /&gt;&lt;a href="http://img.amazon.ca/images/I/41S4YmKHiJL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU15_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://img.amazon.ca/images/I/41S4YmKHiJL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU15_.jpg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;L’auteur y présente une classe sprite de base pouvant être utilisée de différentes manières, dans différents contextes de jeu. L’approche est intéressante mais trop de base et en même temps, j’ai l’impression qu’elle est parfois trop complexe pour de simple sprites qui ne doivent qu’afficher qu’une image. Je me suis néanmoins basé sur sa méthode en intégrant celles de Davison, de &lt;a href="http://www.brackeen.com/"&gt;Brackeen&lt;/a&gt; et de la mienne évidemment. Quand j’aurai terminé mon système de sprites, j’en parlerai plus en profondeur. J’essairai également de mettre un vidéo des sprites en action.&lt;br /&gt;&lt;br /&gt;Revenons à mon intention de base : le livre de &lt;a href="http://www.jharbour.com/"&gt;Harbour&lt;/a&gt;. Il faut d’abord comprendre que comme je n’ai jamais suivi de formations en développement de jeu vidéo, une bonne librairie technique est primordiale. Je me suis donc procuré des livres sur le web en me basant sur leurs descriptions et sur les commentaires des utilisateurs. Dans le cas de celui de &lt;a href="http://www.jharbour.com/"&gt;Harbour&lt;/a&gt;, je me suis fait un tantinet avoir. &lt;br /&gt;&lt;br /&gt;Quand j’ai acheté ce livre, j’en cherchais un qui traitait du 2D. C’est sur le 2D que je désire travailler parce que je ne me sens pas capable de m’attaquer au sujet beaucoup plus complexe de la 3D. Non seulement au niveau de la logique, mais surtout au niveau du graphisme. Même, si mes dessins sont nuls, je peux tout de même les utiliser dans mes jeux 2D avec un résultat quand même intéressant. C’est donc en faisant mes recherche que je suis tombé sur le titre de &lt;a href="http://www.jharbour.com/"&gt;Harbour&lt;/a&gt; en prévente. Et comme c’était un livre « avancé », je me disais que c’était parfait parce que j’en avait déjà sur les notions de bases. Et Internet pouvait aussi combler quelques lacunes. D’ailleurs, je me suis vite aperçu que les livres d’introductions ne valent pas la peine parce que leurs contenus sont bien trop superficiels. Les explications sont souvent nulles, dans le sens où la théorie n’est pas expliqué et on doit alors se fier aveuglément au jugement de l’auteur. En plus, ce sont souvent des concepts qui vont de soi que l’on aurait pu facilement déduire par soi. Rien de neuf finalement. Dans cet optique, lorsque j’ai lu la description de&amp;nbsp; « Advanced 2D Game Development », je me suis dit : « Ça y est! C’est pile poil ce qu’il me faut. » Sauf que la description était basée sur des informations en prévente. Voici ce que l’on disait, grosso-modo : &lt;br /&gt;&lt;br /&gt;&lt;i&gt; "Advanced 2D Game Development" is a comprehensive guide to 2D game development for experienced game programmers who are comfortable working in the C++ language. The book covers every significant 2D game subject including animated sprites, tile-based scrolling, level editing, vector graphics, and physics, as well as the major game genres: real-time strategy, turn-based strategy, first-person shooter, scrolling platform, and role-playing. Readers will develop a complete, professional quality, real-time strategy (RTS) game through the exploration of game theory and techniques, from simple 2D topics to more advanced material such as pathfinding and enemy AI."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Et quand le livre a été en vente, la description est devenue beaucoup plus modeste : &lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Get ready to build a complete, professional-quality 2D game engine from start to finish! "Advanced 2D Game Development" is your comprehensive guide to 2D game development using DirectX in the C++ programming language. Each chapter of the book covers one major component of the game engine, including 2D and 3D rendering, DirectInput, FMOD audio, game math, multi-threading, Lua scripting, and more, and the game engine is built upon chapter by chapter. Through the creation of the game engine, you'll learn step by step how to write solid code for multiple compilers, adding to the code as you work through each chapter. And every chapter includes an example game that illustrates the new techniques being taught. Perfect for game programming students and professionals alike, this book is your ultimate guide to awesome 2D game development. "&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Je partage tout à fait l’&lt;a href="http://www.amazon.com/Advanced-Game-Development-Jonathan-Harbour/product-reviews/1598633422/ref=cm_cr_dp_hist_1?ie=UTF8&amp;amp;showViewpoints=0&amp;amp;filterBy=addOneStar"&gt;avis&lt;/a&gt; de cet utilisateur sur Amazon. Le livre est écrit pour des imbéciles. L’auteur nous prend vraiment pour des idiots en expliquant et en illustrant des concepts de façon bébêtes. Les sujets touchés sont tout ce qui a de plus basic. Il consacre pratiquement un chapitre à configurer son environnement de travail. Ce qui a mon sens relève bien plus de l’introduction que de concepts avancés. Les chapitres sont creux, dans le sens où les sujets traités sont à peine effleurés. Vraiment, ce livre aurait dû être appelé :&amp;nbsp; « Introduction 2D Game Development ». En fait, l’auteur rempli ces pages avec de longs listings de code qu’il réutilise abondamment dans d’autres sections même si peu de changements y ont été apportés. Pour vous donner une idée, 20 lignes de listing, prend environ une page du livre. En gardant le code au minimum, j’imagine que ce livre aurait pu avoir 100 à 150 pages en moins. Sur un total de 320 pages environ… J’appel cela du remplissage. Surtout qu’il y a un CD qui accompagne le volume avec l’ensemble du code en version mature. On a qu’à ouvrir les fichiers désirés et les imprimés, si notre conscience planétaire nous le permet, pour suivre les explications du livre.&lt;br /&gt;&lt;br /&gt;Malgré tout, comme je l’ai dit, ce livre m’est utile. La vie n’est pas que noir ou blanc. Je l’utilise pour établir des squelettes de classes. Et à partir de ces classes de bases, j’enlève ce qui m’est inutile et j’ajoute des éléments que je considère cruellement manquant dans son approche. En fait je prends le meilleur de son approche et je l’utilise selon mes besoins. En espérant que j’obtienne des résultats satisfaisants. &lt;br /&gt;&lt;br /&gt;En fait, avant de terminer ce billet, je suis allé voir l’API de développement web de &lt;a href="http://www.brackeen.com/"&gt;Brackeen&lt;/a&gt; que j’ai téléchargé &lt;a href="http://www.interactivepulp.com/pulpcore/"&gt;ici&lt;/a&gt;. Cette API s’appelle « pulpcore ». Elle contient une implémentation d’une sprite que j’ai étudié tout à l’heure. Ciel que je suis loin d’atteindre ce niveau. &lt;a href="http://www.brackeen.com/"&gt;Brackeen&lt;/a&gt; utilise entre autre des path svg pour les comportements des sprites au niveau des mouvements. Quelle excellente idée. Ça c’est complexe. Ça c’est avancé. Je me rends compte encore plus que ce que &lt;a href="http://www.jharbour.com/"&gt;Harbour&lt;/a&gt; à écrit, c’est pour les gamins du primaire… Et je suis gentil.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note finale : 5/10&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-5236846999537332725?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/5236846999537332725/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/critique-livre-advanced-2d-game.html#comment-form' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5236846999537332725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5236846999537332725'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/critique-livre-advanced-2d-game.html' title='Critique [Livre] – Advanced 2D Game Development, par Jonathan S. Harbour.'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-4056997751104009135</id><published>2010-03-14T21:33:00.000-07:00</published><updated>2010-03-16T19:20:53.876-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='racine carrée'/><category scheme='http://www.blogger.com/atom/ns#' term='concept'/><category scheme='http://www.blogger.com/atom/ns#' term='sprite'/><title type='text'>Création et optimisation.</title><content type='html'>Un jeu vidéo est un processus de création complexe qui demande des compétences dans un tas de domaines liés de près ou de loin. Ce n’est pas pour rien que les projets modernes sont conçus en équipes spécialisés, soit dans la programmation pure et dure, la physique, l’art, la musique, etc. Quand on le fait par passion et que l’on est seul, le découragement peut survenir à tout moment. Mais moi, cette solitude me stimule au contraire. C’est le défi qui me motive. Et cette semaine j’ai réalisé que j’étais loin de voir la lumière au bout du tunnel…&lt;br /&gt;&lt;br /&gt;Comme je l’ai mentionné dans mon premier billet, je travail sur les mathématiques vectoriels et matricielles. En fait, j’ai pas mal fini d’implanter les classes de ces deux concepts. Les vecteurs sont la base des mouvements dans un jeu vidéo. Ils représentent une position et une direction ce qui est en soit suffisant pour que l’ordinateur dessine une image à l’écran. Je ne parlerai pas des matrices, car j’avoue que leurs utilités me laissent perplexe pour le moment. Pour revenir au vecteurs, maintenant que leur implémentation est fini, il faut passer à la prochaine étape soit le mécanisme de collision entre les entités. Ça ne sera pas évident à faire car je dois complètement refaire mon système de sprites (élément de jeu, qui bouge généralement). La raison est que la première fois, je n’étais pas au courant de l’approche vectoriel et j’ai donc tout programmé avec des représentations bêtes de positions (x,y) à l’écran. Avec des entiers. Apparemment, ça ne fonctionne pas comme cela. Je dois donc refaire mes classes de sprites pour que leurs mouvements soient basés sur des manipulations de vecteurs. Et à chaque fois qu’une sprite bouge, le système doit vérifier s’il entre en collision avec une autre. Ce calcul devient vite fastidieux. S’il y a 1000 sprites à l’écran (remarquez qu’on a rarement 1000 sprites), cela représente 1000x1000 soit 1000000 de vérification par frame. Normalement on vise 60 frames par secondes pour que le jeu paraisse fluide. Donc 60 millions de calculs par secondes… Le CPU vient vite surchargé si le code n’est pas optimisé. Une fonction qui revient souvent dans le calcul vectoriel est la racine carrée d’un nombre puisque la géométrie vectorielle est basée sur le triangle droit et le théorème de Pythagore. Hors, nativement, la racine carrée est coûteuse en temps CPU. Heureusement on peut estimer la racine carrée plus rapidement avec assez de précision pour que l’optimisation en vaille la peine. J’ai basé mon algorithme sur la méthode des Babyloniens et de Bakhshali. J’ai trouvé tout cela sur Wikipedia, je suis loin d’être un génie. Voici donc mon code qui remplacera la racine carré native et le temps d’exécutions pour 100 millions d’opérations.&lt;br /&gt;&lt;br /&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;// Racine carré pour les nombres 0 à 99 inclusivement.&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final float[] cfaROOT =&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {0.0f, 1.0f, 1.4142135f, 1.7320508f, 2.0f, 2.236068f, 2.4494898f, 2.6457512f, 2.828427f, 3.0f,…etc&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;….&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp; Retourne la racine carrée d'un nombre. Il s'agit d'une approximation Babylonienne.&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp; Plus précise que la méthode Bakhshali.&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;Méthode préférée, précise et rapide.&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * &lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;Temps = 625ms/1000000it.&amp;nbsp; Comparé à 594ms pour Math.pow().&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @link http://en.wikipedia.org/wiki/Methods_of_computing_square_roots&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * &lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;Time javagame2d = 93203ms - Answer = 724.88336 , pour 100000000it, pour Math.pow()&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * &lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;Time javagame2d = 5547ms - Answer = 724.88336 , pour 100000000it, pour Math2D.squareRoot_Babylonian()&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static float squareRoot_Babylonian(float fNumber, int iIteration){&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (fNumber &amp;lt; 0) { return Float.NaN; } // Négatif.&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; float fRoot = 0;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (fNumber &amp;gt;= 1000000) { return Math2D.squareRoot(fNumber); }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 10000) { fRoot = cfaROOT[floor(fNumber / 10000)] * 100; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 100) { fRoot = cfaROOT[floor(fNumber / 100)] * 10; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 1) { fRoot = cfaROOT[floor(fNumber)]; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 0.01) { fRoot = cfaROOT[floor(fNumber * 100)] / 10; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 0.0001) { fRoot = cfaROOT[floor(fNumber * 10000)] / 100; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (fNumber &amp;gt;= 0.000001) { fRoot = cfaROOT[floor(fNumber * 1000000)] / 1000; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else { return Math2D.squareRoot(fNumber); }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; iIteration; i++) {&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fRoot = (fRoot + (fNumber / fRoot)) / 2;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return fRoot;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: orange; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Ici, je montre la méthode Babylonienne, c’est celle que j’ai adopté. Elle est précise et 17 fois plus rapide que la méthode native. Cette méthode est implémenté dans la boucle for. La difficulté que j’ai eu, était qu’il fallait fournir à la formule un estimé de la racine carré du nombre cherché. Alors j’ai utilisé une variable globale cfaROOT qui contient toute les racines carrées de 1 à 100. C’est à cela que sert la série de test if. Dépendamment du nombre, on trouve la racine carrée pré calculée dans cfaROOT, et on la modifie selon l’amplitude du nombre. Par exemple, la racine de 100 est 10. La racine de 10000 est de 100. Donc 10 fois plus. C’est ce que fait la série de tests, ils déterminent la racine approximative la plus près, et elle est utilisé dans le calcule Babylonien pour être précisé. Avec deux itérations de la méthode Babylonienne, j’obtiens une précision à 5 chiffres après le point. 17 fois plus rapidement, je le rappel.&lt;br /&gt;&lt;br /&gt;Ok, ça suffit. Je vous ai assez assommé avec des explications nébuleuses. Lorsque je travail sur mon projet, je partage mon temps en deux (je vous épargne les obligations parentale). Le matin, programmation. L’après-midi, création, graphisme, concept. Cette semaine j’ai donc sortie mes crayons et je me suis mis à gribouiller. J’avais dessiné une ébauche de scène où l’on voit deux personnages à la recherche d'un engin perdu. Un vaisseau de combat avec des possibilités de voyage dans le temps, enfin on verra. Dans le ciel, en avant de la lune, on voit la silhouette d’un vaisseau orbital qui fera office de base à mes protagonistes. J’ai planché sur ce vaisseau orbital. À force de zigonnage, j’en suis venu à ce concept : &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://fc02.deviantart.net/fs71/f/2010/073/5/d/Kradius_Project_CargoShip_WIP_by_leDarkAnge.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="345" src="http://fc02.deviantart.net/fs71/f/2010/073/5/d/Kradius_Project_CargoShip_WIP_by_leDarkAnge.gif" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ici on voit le vaisseau en deux positions. Contracté, il est en mode hyperespace. Étiré, il est en mode orbital. Je ne suis pas sûr encore de ces fonctions et du pourquoi de ces deux modes, mais en travaillant dessus des idées me sont venus quand à l’histoire globale du jeu. J’ai même pensé à faire de ce vaisseau le fleuron de l’ANUQ, l’armée des nations unifiées du Québec. Première force militaire mondiale…. Je vais y coller la fleur de lys en quelque part comme logo. J’aime autant ne pas trop en dire sur l’histoire pour le moment, ça change à toutes les deux secondes dans ma tête. Enfin, dites moi ce que vous en pensé. Vous pouvez aussi aller me voir sur mon compte Deviant Art.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-4056997751104009135?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/4056997751104009135/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/creation-et-optimisation.html#comment-form' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4056997751104009135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/4056997751104009135'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/creation-et-optimisation.html' title='Création et optimisation.'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1487914221330335184.post-5166444383144439298</id><published>2010-03-07T20:15:00.000-08:00</published><updated>2011-01-31T03:29:32.000-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='Andrew Davison'/><category scheme='http://www.blogger.com/atom/ns#' term='TÉLUQ'/><title type='text'>Il y a un début à tout...</title><content type='html'>J’écris cette première entrée avec ma fille dans les bras. Quand on est parent, c’est très difficile de se trouver du temps à soi pour faire ce que l’on aime. Des enfants, j’en ai deux, 4 ans et 4 mois. Je n’ai aucunement l’intention de bloguer sur les marmots. Je ne suis pas un père indigné en manque de pub… J’essaie juste d’expliquer le contexte dans lequel j’ai entreprit de développer un jeu vidéo il y a de ça 5 ans.&lt;br /&gt;&lt;br /&gt;Tout à commencer avec une passion qui remonte à mon enfance. J’ai grandi avec des compagnons virtuels jusqu’à tout récemment. Aujourd’hui avec la paternité, j’ai pratiquement tout arrêté. Par contre, certaines occasions et tournures d’évènements m’ont amené à complémenter mes compétences professionnelles avec des notions informatiques. C’est donc à tâtons que j’ai titillé avec la programmation, dans le cadre de mon travail, en utilisant Visual Basic. Afin de me donner des bases plus solides tout en étant conscient du temps que je pouvais y consacrer, j’ai entreprit un certificat en informatique à la TELUQ au rythme de deux cours par année. Parallèlement à cela, je me suis monté une bibliothèque technique relié au développement de jeux vidéo dont je me fais le devoir d’étudier à temps perdu. Je dois cette belle bibliothèque aux services impeccables qu’offre Amazon. 5 ans, ça fait donc beaucoup de temps pour peu de résultats… Enfin, à mon avis. Mais ces 5 ans ont surtout été consacré à l’apprentissage à temps partiel, le soir, la nuit, les yeux et le cerveau dans les brumes spectrales du sommeil. Et les nombreuses distractions du web…. &lt;br /&gt;&lt;br /&gt;Aujourd’hui, j’ai donc les bases d’un moteur de jeu 2d écrit en java. J’ai choisis Java parce que c’est le langage avec lequel que j’ai débuté à l’époque et que si le besoin se fait sentir, sa syntaxe est proche de celle du c++. La migration pourra donc se faire sans trop de difficultés. Enfin, c’est toujours ce que l’on se dit en info et on se retrouve avec des délais dépassant du double les prévisions. De plus, j’ai voulu utiliser Java pour démentir tout ceux qui prétendre que la vitesse d’exécution du langage n’est pas idéal pour les jeux. Ça, on verra. J’ai basé la plupart des concepts de bases de mon jeu sur ceux enseignés dans le livre "Killer game programming in java". Par le Dr. Andrew Davison.&amp;nbsp; Actuellement, mon jeu montre plusieurs couches de backgrounds bougeant à différentes vitesses, un système de gestion de briques et un paquet d’autres gogosses invisibles à l’écran. Je reviendrai tranquillement sur le détail de chaque fonction au fil du temps.&lt;br /&gt;&lt;br /&gt;Avec ce blog, j’entends faire une mise à jour mensuelle (au moins) sur l’état d’avancement de mon jeu et sur mon état mental, s’il le faut. Je prévois m’en servir comme un aide mémoire pour revenir sur les points que j’ai eu le plus de difficultés où que je me suis carrément planté. Tout ça, écrit dans un français lamentable, digne du web, parce que je suis trop vache pour me corriger. Je n’ai pas trop d’espoir d’être lu. Mais, si j’ai des commentaires, j’y répondrai. J’oubliais de dire que je veux utiliser ce blog pour mon dernier cours de certificat qui est un projet personnel qui, je vous le donne en mille, sera mon jeu.&lt;br /&gt;&lt;br /&gt;Je terminerai ce post en écrivant mes derniers développements. Les dernières semaines ont été consacrées, et ce n’est pas fini, à développer l’aspect mathématique et physique de mon programme. J’ai du replonger dans les vecteurs et matrices, et tout ça pour faire bouger des ti-bonhommes à l’écran… À suivre.&lt;br /&gt;&lt;br /&gt;P.S. : Ne vous inquiétez pas, il y aura des images pour mes lecteurs analpha_bêtes. &lt;br /&gt;&lt;br /&gt;David Gobeil, alias DarkAnge.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1487914221330335184-5166444383144439298?l=indie-darkange.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://indie-darkange.blogspot.com/feeds/5166444383144439298/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/il-y-un-debut-tout.html#comment-form' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5166444383144439298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1487914221330335184/posts/default/5166444383144439298'/><link rel='alternate' type='text/html' href='http://indie-darkange.blogspot.com/2010/03/il-y-un-debut-tout.html' title='Il y a un début à tout...'/><author><name>DarkAnge</name><uri>http://www.blogger.com/profile/11620960530439887580</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://2.bp.blogspot.com/_kfRWGl6zTyE/S95AMhLPP_I/AAAAAAAAAAY/mBJDvm_h7OY/S220/profil.jpg'/></author><thr:total>1</thr:total></entry></feed>
