<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
	<title>IAmNotDifferent</title>
	<link>https://whiteshoulders.fr/</link>
	<language>fr</language>
	<description>Whiteshoulders</description>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="https://whiteshoulders.fr/feed.php?rss" />
	<lastBuildDate>Wed, 26 Feb 2014 23:27:00 +0100</lastBuildDate>
	<generator>PluXml</generator>
	<item>
		<title>Whisper</title> 
		<link>https://whiteshoulders.fr/index.php?article167/whisper</link>
		<guid>https://whiteshoulders.fr/index.php?article167/whisper</guid>
		<description>&lt;audio preload=&quot;none&quot;&gt;
  &lt;source data-base=&quot;/source/ruperth/whisper/&quot; src=&quot;https://whiteshoulders.fr/source/ruperth/whisper/whisper.mp3&quot; type=&quot;audio/mp3&quot; /&gt;
  &lt;source data-base=&quot;/source/ruperth/whisper/&quot; src=&quot;https://whiteshoulders.fr/source/ruperth/whisper/whisper.ogg&quot; type=&quot;audio/ogg&quot; /&gt;  
&lt;/audio&gt;
&lt;div class=&quot;buttons&quot;&gt;
&lt;a class=&quot;download&quot; href=&quot;https://whiteshoulders.fr/source/ruperth/whisper/whisper.mp3&quot;&gt;[mp3]&lt;/a&gt;
&lt;a class=&quot;download&quot; href=&quot;https://whiteshoulders.fr/source/ruperth/whisper/whisper.ogg&quot;&gt;[ogg]&lt;/a&gt;
&lt;a class=&quot;download&quot; href=&quot;https://whiteshoulders.fr/source/ruperth/whisper/whisper.flac&quot;&gt;[flac]&lt;/a&gt;
&lt;!--&lt;a class=&quot;source&quot; href=&quot;https://whiteshoulders.fr/&quot;&gt;Voir les sources&lt;/a&gt;--&gt;
&lt;/div&gt;</description>
		<pubDate>Wed, 26 Feb 2014 23:27:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Synthèse vocale et JavaScript : Génération dynamique de sons</title> 
		<link>https://whiteshoulders.fr/index.php?article165/synthese-vocale-et-javascript</link>
		<guid>https://whiteshoulders.fr/index.php?article165/synthese-vocale-et-javascript</guid>
		<description>&lt;p&gt;
Le JavaScript offre beaucoup de possibilité, et avec les capacité d&#039;un navigateur, on peut en faire beaucoup. J&#039;ai décidé que parmi l&#039;ensemble des possibilités, mon attention allait se focaliser sur la synthèses vocale.
&lt;/p&gt;&lt;p&gt;
Le but : réaliser un synthétiseur vocal simple, comme ceux des &lt;a href=&quot;http://www.youtube.com/watch?v=Rm4ZCGgzeeU&quot;&gt;vieux comodore64.&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
Le première épisode de cette grande aventure humaine, riche en rebondissement et haute en couleurs portera sur &lt;strong&gt;la génération dynamique de sons&lt;/strong&gt; en JavaScript.
&lt;/p&gt;&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;
Pour pouvoir réaliser une application de synthèse vocale, il faut avant tout pouvoir générer un son.
&lt;/p&gt;
&lt;p&gt;
Malheureusement, il est impossible actuellement de générer avec JavaScript un son joué directement par le navigateur. &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/webaudio/intro/?redirect_from_locale=fr&quot;&gt;L&#039;API Web Sound&lt;/a&gt;, en cours de développement devrais à terme le permettre, mais pour le moment c&#039;est impossible.
&lt;/p&gt;
&lt;p&gt;
Alors quoi ? On arrête l&#039;article au bout de 5 lignes ? Non, car il existe une solution : générer un fichier son, puis de jouer ce fichier son. Les navigateurs récents en sont capables avec l’élément &amp;lt;audio&amp;gt;. On passe alors de la génération d&#039;un son à la génération d&#039;un fichier son.
&lt;/p&gt;
&lt;p&gt;
Les fichiers son les plus simple à produire sont les fichiers wav. Il s&#039;agit d&#039;un format brut, non compressé. Et pour pouvoir produire ce type de fichier, il faut connaître son format. 
&lt;/p&gt;
&lt;h3&gt;Son et echantillonnage&lt;/h3&gt;
&lt;p&gt;
Le son est une onde qui se transmet dans l&#039;air, depuis une source (un haut parleur, un violon, un bouche) jusqu’à un récepteur (un micro, une oreille). L&#039;onde se transmet sous la forme de variation de pression locale de l&#039;air. Ce sont ces variations de pressions qui atteignent nos oreille, et font vibrer nos tympans. On peut décrire cette onde comme une fonction du temps, qui varie de manière continue. 
&lt;/p&gt;
&lt;p&gt;
L&#039;informatique fonctionne de manière discrète. Toute les informations sont découpé en tranches, et codé sous forme binaire. Pour pouvoir décrire notre onde sonore, il va falloir la découper en tranche : c&#039;est &lt;a href=&quot;http://fr.wikipedia.org/wiki/%C3%89chantillonnage_%28signal%29&quot;&gt;l&#039;échantillonnage&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;img src=&quot;https://whiteshoulders.fr/data/images/sampling.png&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
La largeur des tranches défini ce que l&#039;on appel la fréquence d’échantillonnage. Plus les tranches sont étroite, plus on mesure précisément le signal. Si les tranches sont trop large, il peut arriver que l&#039;on sous-échantillonne le signal.
&lt;/p&gt;
&lt;p&gt;
La fréquence d&#039;échantillonnage joue un rôle clef, puisqu&#039;elle va permettre de savoir a quelle vitesse il faut lire les tranches pour retrouver le son d&#039;origine. 
&lt;/p&gt;
&lt;p&gt;
A chaque tranche va correspondre l&#039;amplitude de l&#039;onde en ce point. Ce nombre va être codé dans un format binaire, sur un certain nombre de bit. C&#039;est la &lt;a href=&quot;http://en.wikipedia.org/wiki/Audio_bit_depth&quot;&gt;résolution&lt;/a&gt; du son. Plus on alloue de bit pour coder chaque tranche, plus la résolution est grande, meilleur sera la qualité du son.
&lt;/p&gt;
&lt;h3&gt;Format WAV&lt;/h3&gt;
&lt;p&gt;
D&#039;après la &lt;a href=&quot;https://ccrma.stanford.edu/courses/422/projects/WaveFormat/&quot;&gt;définition du format&lt;/a&gt;, un fichier wav est composé de plusieurs morceaux de données binaires. La première partie du fichier est le header, qui donne les information nécessaire à la lecture du reste du fichier, en particulier la fréquence d&#039;échantillonnage. 
&lt;/p&gt;&lt;p&gt;
Plus précisément, le fichier contient dans un premier temps un bloc de déclaration d&#039;un fichier au format wave :
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une constante d&#039;identification sur 4 octets : &quot;RIFF&quot;&lt;/li&gt;
&lt;li&gt;La taille totale du fichier moins 8 octets codée sur 4 octets&lt;/li&gt;
&lt;li&gt;Une constante de format sur 4 octets : &quot;WAVE&quot;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
&lt;p&gt;Viens ensuite un bloc décrivant le format audio (toutes les caractéristiques du son numérisé) :
&lt;/p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une constante identifiant le début du bloc sur 4 octets : &quot;fmt &quot;&lt;/li&gt;
&lt;li&gt;La taille du bloc sur 4 octets&lt;/li&gt;
&lt;li&gt;Une constant identifiant le format de stockage (PCM, par exemple) dans le fichier sur 2 octets&lt;/li&gt;
&lt;li&gt;Le nombre de canaux&lt;/li&gt;
&lt;li&gt;La fréquence d&#039;échantillonnage sur 4 octets&lt;/li&gt;
&lt;li&gt;Le nombre d&#039;octets par seconde&lt;/li&gt;
&lt;li&gt;Le nombre d&#039;octets par bloc d&#039;échantillonage&lt;/li&gt;
&lt;li&gt;La résolution&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
&lt;p&gt;Enfin, on trouve le bloc des données :
&lt;/p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une constante identifiant le début du bloc sur 4 octets : &quot;data&quot;&lt;/li&gt;
&lt;li&gt;La taille du bloc de données moins 8 octets&lt;/li&gt;
&lt;li&gt;Les données&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;&lt;/p&gt;
&lt;h3&gt;Ecrire un wave en javascript&lt;/h3&gt;
&lt;p&gt;En respectant ce format, il est possible de générer le contenu du fichier. En utilisant les &lt;a href=&quot;http://www.alsacreations.com/article/lire/1439-data-uri-schema.html&quot;&gt;data URI&lt;/a&gt;, on peut facilement inclure le fichier ainsi écris dans le corps de la page, dans une balise audio.
&lt;/p&gt;
&lt;p&gt;
Voici le code du module qui permet de retourner la version base64 de donnée sonores qu&#039;il restera à générer :
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;pre class=&quot;brush: js&quot;&gt;
&amp;nbsp;
var app = {};&lt;/p&gt;
&lt;p&gt;(function() {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;app.utility = {

    /* js port of PHP function pack */
    pack : function (fmt) {
        var output = &#039;&#039;;

        var argi = 1;
        for (var i = 0; i &amp;lt; fmt.length; i++) {
            var c = fmt.charAt(i);
            var arg = arguments[argi];
            argi++;

            switch (c) {
                case &quot;a&quot;:
                    output += arg[0] + &quot;\0&quot;;
                    break;
                case &quot;A&quot;:
                    output += arg[0] + &quot; &quot;;
                    break;
                case &quot;C&quot;:
                case &quot;c&quot;:
                    output += String.fromCharCode(arg);
                    break;
                case &quot;n&quot;:
                    output += String.fromCharCode(
                        (arg &amp;gt;&amp;gt; 8) &amp;amp; 255, 
                        arg &amp;amp; 255
                    );
                    break;
                case &quot;v&quot;:
                    output += String.fromCharCode(
                        arg &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 8) &amp;amp; 255
                    );
                    break;
                case &quot;N&quot;:
                    output += String.fromCharCode(
                        (arg &amp;gt;&amp;gt; 24) &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 16) &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 8) &amp;amp; 255, 
                        arg &amp;amp; 255
                    );
                    break;
                case &quot;V&quot;:
                    output += String.fromCharCode(
                        arg &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 8) &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 16) &amp;amp; 255, 
                        (arg &amp;gt;&amp;gt; 24) &amp;amp; 255
                    );
                    break;
                case &quot;x&quot;:
                    argi--;
                    output += &quot;\0&quot;;
                    break;
                default:
                    throw new Error(&quot;Unknown pack format &#039;&quot;+c+&quot;&#039;&quot;);
            }
        }

        return output;
    }

}

/* Classic sound config : mono wav, 44100 Hz, 16 bit depth */
app.config = {
    channels : 1,
    sampleRate : 44100,
    bitsPerSample : 16,
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}());&lt;/p&gt;
&lt;p&gt;(function(){&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;var pack = app.utility.pack;
var cf = app.config;

// constructor
app.wave = function (_data) {
    this.data = _data;
};

app.wave.prototype = {

    // Generate the wave content by concatenation, and encode it to base64.
    generate : function () {
        var chunk1 = this.makeChunk1(); // format chunk
        var chunk2 = this.makeChunk2(); // data chunk
        var header = this.makeHeader(chunk1.length, chunk2.length);
        var out = header + chunk1 + chunk2;
        return &quot;data:audio/wav;base64,&quot; + btoa(out);
    },

    // Generate the content of the audio format chunk
    makeChunk1 : function () {
        var chunk1 = [
            &quot;fmt &quot;,
            pack(&quot;V&quot;, 16), // Chunk length for PCM
            pack(&quot;v&quot;, 1), // linear PCM
            pack(&quot;v&quot;, cf.channels),
            pack(&quot;V&quot;, cf.sampleRate),
            pack(&quot;V&quot;, cf.sampleRate * cf.channels * cf.bitsPerSample / 8), // ByteRate
            pack(
                &quot;v&quot;, 
                cf.channels * cf.bitsPerSample / 8
            ), // BlockAlign
            pack(&quot;v&quot;, cf.bitsPerSample)
        ];
        return chunk1.join(&#039;&#039;);
    },

    // Generate the content of the data chunk
    makeChunk2 : function () {
        var data = this.data;

        var chunk2 = [
            &quot;data&quot;, // chunk ID
            pack(&quot;V&quot;, data.samples * cf.channels * cf.bitsPerSample / 8), // Chunk length
            data.raw
        ];
        return chunk2.join(&#039;&#039;);
    },

    // Generate the header chunk
    makeHeader : function () {
        var data = this.data;

        var dataSize = data.samples * cf.channels * cf.bitsPerSample / 8;
        var block1 = (8 + 16);
        var block2 = (8 + dataSize);
        var header = [
            &quot;RIFF&quot;,
            pack(
            &quot;V&quot;, 4 + block1 + block2), // total lenght
            &quot;WAVE&quot;
        ];
        return header.join(&#039;&#039;);
    }

};&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}());
&amp;nbsp;
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Démonstration&lt;/h3&gt;
&lt;p&gt;
On va générer les données d&#039;un fichier wav à partir d&#039;une simple sinusoïde à 440Hz. Un beau la bien pur.
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;pre class=&quot;brush: js&quot;&gt;
&amp;nbsp;
var frequency = 440;
var duration = 1;
var volume = Math.floor(65535 / 2);&lt;/p&gt;
&lt;p&gt;var raw = [];
var samples = 0;&lt;/p&gt;
&lt;p&gt;for(var i = 0; i &amp;lt;= app.config.sampleRate * duration; i++) {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;for(var c = 0; c &amp;amp;lt; app.config.channels; c++) {
    var v = volume * Math.sin(2 * Math.PI * frequency * i/app.config.sampleRate);
    raw.push(app.utility.pack(&quot;v&quot;, v));
    samples++;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}
var data = {raw: raw.join(&#039;&#039;), samples: samples};&lt;/p&gt;
&lt;p&gt;var wave = new app.wave(data);
var base64wave = wave.generate();
var audio = document.getElementById(&quot;demo&quot;);
var source = document.createElement(&quot;source&quot;);
source.setAttribute(&quot;src&quot;, base64wave);
audio.appendChild(source);
&amp;nbsp;
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
Le résultat du code, c&#039;est cette balise audio, avec un la de très belle facture, d&#039;une seconde.
&lt;/p&gt;
&lt;p&gt;&lt;audio id=&quot;demo&quot; class=&quot;noAudioJs&quot; controls autobuffer&gt;
&lt;/audio&gt;
&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;
Maintenant que l&#039;on est capable d&#039;écrire n&#039;importe quelle fichier audio pour le faire lire par le browser, il ne &quot;reste plus&quot; qu&#039;a générer les données sonores correspondant à une voix de synthèse.
&lt;/p&gt;&lt;p&gt;
La prochaine étape sera de générer des voyelles, avant de passer aux consonnes, puis à un convertisseur de texte en phonèmes.
&lt;/p&gt;
&lt;script&gt;
var app = {};

(function() {

    app.utility = {

        /* js port of PHP function pack */
        pack : function (fmt) {
            var output = &#039;&#039;;
            
            var argi = 1;
            for (var i = 0; i &lt; fmt.length; i++) {
                var c = fmt.charAt(i);
                var arg = arguments[argi];
                argi++;
                
                switch (c) {
                    case &quot;a&quot;:
                        output += arg[0] + &quot;\0&quot;;
                        break;
                    case &quot;A&quot;:
                        output += arg[0] + &quot; &quot;;
                        break;
                    case &quot;C&quot;:
                    case &quot;c&quot;:
                        output += String.fromCharCode(arg);
                        break;
                    case &quot;n&quot;:
                        output += String.fromCharCode(
                            (arg &gt;&gt; 8) &amp; 255, 
                            arg &amp; 255
                        );
                        break;
                    case &quot;v&quot;:
                        output += String.fromCharCode(
                            arg &amp; 255, 
                            (arg &gt;&gt; 8) &amp; 255
                        );
                        break;
                    case &quot;N&quot;:
                        output += String.fromCharCode(
                            (arg &gt;&gt; 24) &amp; 255, 
                            (arg &gt;&gt; 16) &amp; 255, 
                            (arg &gt;&gt; 8) &amp; 255, 
                            arg &amp; 255
                        );
                        break;
                    case &quot;V&quot;:
                        output += String.fromCharCode(
                            arg &amp; 255, 
                            (arg &gt;&gt; 8) &amp; 255, 
                            (arg &gt;&gt; 16) &amp; 255, 
                            (arg &gt;&gt; 24) &amp; 255
                        );
                        break;
                    case &quot;x&quot;:
                        argi--;
                        output += &quot;\0&quot;;
                        break;
                    default:
                        throw new Error(&quot;Unknown pack format &#039;&quot;+c+&quot;&#039;&quot;);
                }
            }
            
            return output;
        }

    }

    /* Classic sound config : mono wav, 44100 Hz, 16 bit depth */
    app.config = {
        channels : 1,
        sampleRate : 44100,
        bitsPerSample : 16,
    }

}());

(function(){

    var pack = app.utility.pack;
    var config = app.config;

    // constructor
    app.wave = function (_data) {
        this.data = _data;
    };

    app.wave.prototype = {

        // Generate the wave content by concatenation, and encode it to base64.
        generate : function () {
            var chunk1 = this.makeChunk1(); // format chunk
            var chunk2 = this.makeChunk2(); // data chunk
            var header = this.makeHeader(chunk1.length, chunk2.length);
            var out = header + chunk1 + chunk2;
            return &quot;data:audio/wav;base64,&quot; + btoa(out);
        },

        // Generate the content of the audio format chunk
        makeChunk1 : function () {
            var chunk1 = [
                &quot;fmt &quot;,
                pack(&quot;V&quot;, 16), // Chunk length for PCM
                pack(&quot;v&quot;, 1), // linear PCM
                pack(&quot;v&quot;, config.channels),
                pack(&quot;V&quot;, config.sampleRate),
                pack(&quot;V&quot;, config.sampleRate * config.channels * config.bitsPerSample / 8), // ByteRate
                pack(&quot;v&quot;, config.channels * config.bitsPerSample / 8), // BlockAlign
                pack(&quot;v&quot;, config.bitsPerSample)
            ];
            return chunk1.join(&#039;&#039;);
        },

        // Generate the content of the data chunk
        makeChunk2 : function () {
            var data = this.data;

            var chunk2 = [
                &quot;data&quot;, // chunk ID
                pack(&quot;V&quot;, data.samples * config.channels * config.bitsPerSample / 8), // Chunk length
                data.raw
            ];
            return chunk2.join(&#039;&#039;);
        },

        // Generate the header chunk
        makeHeader : function () {
            var data = this.data;

            var header = [
                &quot;RIFF&quot;,
                pack(&quot;V&quot;, 4 + (8 + 16) + (8 + data.samples * config.channels * config.bitsPerSample / 8)), // total lenght
                &quot;WAVE&quot;
            ];
            return header.join(&#039;&#039;);
        }

    };

}());

var frequency = 440;
var duration = 1;
var volume = Math.floor(65535 / 2);

var raw = [];
var samples = 0;

for(var i = 0; i &lt;= app.config.sampleRate * duration; i++) {
    for(var c = 0; c &lt;app.config.channels; c++) {
        var v = volume * Math.sin(2 * Math.PI * frequency * i/app.config.sampleRate);
        raw.push(app.utility.pack(&quot;v&quot;, v));
        samples++;
    }
}
var data = {raw: raw.join(&#039;&#039;), samples: samples};

var wave = new app.wave(data);
var base64wave = wave.generate();
var audio = document.getElementById(&quot;demo&quot;);
var source = document.createElement(&quot;source&quot;);
source.setAttribute(&quot;src&quot;, base64wave);
audio.appendChild(source);

&lt;/script&gt;</description>
		<pubDate>Wed, 19 Feb 2014 19:03:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Broqen I</title> 
		<link>https://whiteshoulders.fr/index.php?article164/broqen-i</link>
		<guid>https://whiteshoulders.fr/index.php?article164/broqen-i</guid>
		<description>&lt;img src=&quot;http://whiteshoulders.fr/data/images/noir/broqen_i.tb.png&quot; alt=&quot;image&quot;/&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/noir/broqen_i.png&quot; alt=&quot;image&quot;/&gt;</description>
		<pubDate>Thu, 23 Jan 2014 16:09:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Rpg.js v0.2</title> 
		<link>https://whiteshoulders.fr/index.php?article163/rpg-js-v0-2</link>
		<guid>https://whiteshoulders.fr/index.php?article163/rpg-js-v0-2</guid>
		<description>&lt;p&gt;
Il y a bientôt 5 mois, j&#039;avais présenté ici la première pierre posée à l&#039;édification d&#039;un mini RPG en JavaScript. Il est temps de poser la seconde, pour laquelle j&#039;ai tout refait, parce que le code précédent était impossible à relire, pas commenté, spaghettiesque.
&lt;/p&gt;
&lt;p&gt;
Et pour l&#039;occasion, j&#039;ai ajouté pleins de choses (dont certaines ne se voient pas).
&lt;/p&gt;&lt;p&gt;Avant le long paragraphe sur les dedans de la bête, voici la bête en question !&lt;/p&gt;
&lt;style&gt;
    @font-face {
        font-family: &#039;pixel&#039;;
        src: url(&#039;/data/documents/rpg.js_v0.2/font/uni0553-webfont.eot&#039;);
        src: url(&#039;/data/documents/rpg.js_v0.2/font/uni0553-webfont.eot?#iefix&#039;) format(&#039;embedded-opentype&#039;),
             url(&#039;/data/documents/rpg.js_v0.2/font/uni0553-webfont.woff&#039;) format(&#039;woff&#039;),
             url(&#039;/data/documents/rpg.js_v0.2/font/uni0553-webfont.ttf&#039;) format(&#039;truetype&#039;);
        font-weight: normal;
        font-style: normal;
    }
    @font-face {
        font-family: &#039;pixel&#039;;
        src: url(&#039;/data/documents/rpg.js_v0.2/font/uni0563-webfont.eot&#039;);
        src: url(&#039;/data/documents/rpg.js_v0.2/font/uni0563-webfont.eot?#iefix&#039;) format(&#039;embedded-opentype&#039;),
             url(&#039;/data/documents/rpg.js_v0.2/font/uni0563-webfont.woff&#039;) format(&#039;woff&#039;),
             url(&#039;/data/documents/rpg.js_v0.2/font/uni0563-webfont.ttf&#039;) format(&#039;truetype&#039;);
        font-weight: bold;
        font-style: normal;
    }

    #assets{
      display:none;
    }
    #canvasBloc{
      height:512px;
      width:512px;
      position:relative;
    }
    #canvasBloc canvas{
      position:absolute;
    }
/*#############################################
### DIALOG BOX 
#############################################*/

    #dialogBox{
      position:absolute;
      z-index:100;
      background-color: rgba(255,255,255,0.6);
      margin:0 20px;
      padding:5px;
      font-family: &quot;pixel&quot;;
      font-size:14px;
      padding-right:30px;
    }
    #dialogBox:before{
      content: &quot;&quot;;
      position: absolute;
      display: block;
      width: 0;
      border-style: solid;
    }
    #dialogBox.left {
      margin-left:30px;
    }
    #dialogBox.left:before{
      top:10px;
      bottom: auto;
      left: -10px;
      border-width: 5px 10px 5px 0;
      border-color: transparent rgba(255,255,255,0.6);
    }
    #dialogBox.right {
      margin-right:30px;
    }
    #dialogBox.right:before{
      top:10px;
      bottom: auto;
      right: -10px;
      border-width: 5px 0 5px 10px;
      border-color: transparent rgba(255,255,255,0.6);
    }
    #dialogBox:after{
      content:&quot;\2193\00a0&quot;;
      font-weight:bold;
      font-size:18px;
      position:absolute;
      bottom:5px;
      width:100%;
      margin-left:-5px;
      display:block;
      text-align:right;
      overflow:hidden;
      opacity:0;
      transition-property:opacity;
      transition-duration:0.2s;
      animation:moveContinue 0.5s linear 0s infinite alternate;
      -webkit-animation:moveContinue 1s linear 0s infinite alternate;
    }
    #dialogBox.continue:after{
      opacity:1;
    }

    @keyframes moveContinue {
      0% { bottom: 5px; }
      100% { bottom: 8px; }
    }
    @-webkit-keyframes moveContinue {
      0% { bottom: 5px; }
      100% { bottom: 8px; }
    }


#canvasContener{
width:512px;
margin:25px auto;
}
&lt;/style&gt;
&lt;div id=&quot;canvasContener&quot;&gt;
  &lt;div id=&quot;canvasBloc&quot;&gt;
    &lt;canvas id=&quot;cMap_1a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cPlayer_1a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cMap_2a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cPlayer_2a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cMap_3a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cPlayer_3a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;cMap_4a&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;transition&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;span id=&quot;dialogBox&quot; class=&quot;left&quot;&gt;this is the classical &lt;strong&gt;dialog box&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
&lt;p&gt;&lt;/div&gt;&lt;/p&gt;
&lt;div id=&quot;assets&quot;&gt;
  &lt;img id=&quot;tileset&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.2/sprite/tileset.png&quot;&gt;
  &lt;img id=&quot;charaset&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.2/sprite/charset.png&quot;&gt;
  &lt;code&gt;&lt;pre id=&quot;blockMap&quot;&gt;
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
  &lt;/pre&gt;&lt;/code&gt;
  &lt;code&gt;&lt;pre id=&quot;map&quot;&gt;{
    &quot;tableTile&quot;:[[[4,308,0,0,0,0],[5,307,0,0,0,0],[4,306,0,0,0,0],[5,309,0,0,0,0],[5,308,0,0,0,0],[4,309,0,0,0,0],[5,0,0,285,0,0],[4,0,0,286,0,0],[5,287,0,0,0,0],[4,307,0,0,265,0],[4,0,0,0,266,0],[4,0,0,0,267,0],[5,0,0,0,268,0],[5,0,0,0,269,0],[4,0,0,0,270,0],[4,0,0,0,267,0],[5,0,0,268,0,0],[4,0,0,269,245,0],[4,0,0,0,246,0],[5,0,0,0,247,0],[5,0,0,0,248,0],[5,0,0,226,0,0],[4,0,0,227,205,0],[5,0,0,0,206,0]],[[44,328,0,0,0,0],[44,327,0,0,0,0],[44,330,0,0,0,0],[4,329,0,0,0,0],[45,328,0,0,0,0],[5,329,0,0,0,0],[4,327,0,305,0,0],[4,0,0,308,0,0],[5,310,0,0,0,0],[4,309,0,0,285,0],[4,0,0,0,286,0],[4,0,0,0,287,0],[45,0,0,0,289,0],[5,0,0,0,288,0],[4,0,0,0,289,0],[4,0,0,0,287,0],[5,0,0,288,0,0],[4,0,0,289,265,0],[5,0,0,0,266,0],[4,0,0,0,267,0],[4,0,0,0,268,0],[4,0,0,246,0,0],[4,0,0,247,205,0],[4,0,0,0,226,0]],[[44,348,0,0,0,0],[44,347,0,0,0,0],[45,348,0,0,0,0],[44,349,0,0,0,0],[44,350,0,0,0,0],[44,347,0,0,0,0],[44,347,0,0,0,0],[44,0,0,326,0,0],[45,0,0,328,0,0],[24,329,0,0,305,0],[44,0,0,0,306,0],[45,0,0,307,101,0],[45,0,0,309,102,0],[45,0,0,308,103,0],[45,0,0,0,310,0],[45,0,0,0,307,0],[45,0,0,308,0,0],[4,0,0,309,285,0],[65,0,0,0,286,0],[5,0,0,0,287,0],[4,0,0,0,288,0],[5,0,0,266,0,0],[4,0,0,267,245,0],[4,0,0,0,246,0]],[[44,368,0,0,0,0],[44,367,0,0,0,0],[44,368,0,0,0,0],[44,369,0,0,0,0],[44,370,0,0,0,0],[25,367,0,0,0,0],[45,367,0,0,0,0],[44,0,346,0,0,0],[44,0,348,0,0,0],[44,349,0,0,0,0],[44,0,0,326,0,0],[44,0,0,327,121,0],[45,0,0,329,122,0],[44,0,0,328,123,0],[45,0,0,330,0,0],[44,0,0,327,0,0],[44,0,0,328,0,0],[65,0,0,329,305,0],[64,0,0,0,306,0],[65,0,0,0,307,0],[5,0,0,0,308,0],[4,0,0,286,0,0],[4,0,0,287,265,0],[5,0,0,0,266,0]],[[44,7,0,0,0,0],[45,8,0,0,0,0],[44,8,0,0,0,0],[45,7,0,0,0,0],[44,8,0,0,0,0],[45,8,0,0,0,0],[44,9,0,0,0,0],[25,366,0,0,0,0],[44,368,0,0,0,0],[24,369,0,0,0,0],[45,0,346,0,0,0],[45,0,347,0,141,0],[24,0,349,0,142,0],[44,0,348,0,143,0],[45,0,350,0,0,0],[44,0,347,0,0,0],[65,0,350,0,0,0],[45,0,347,0,0,0],[65,0,0,326,0,0],[65,0,0,327,0,0],[65,0,0,328,0,0],[5,0,0,306,0,0],[4,0,0,307,285,0],[5,0,0,0,206,0]],[[44,40,0,0,0,0],[44,60,0,0,0,0],[44,40,0,0,0,0],[44,41,0,0,0,0],[44,61,0,0,0,0],[44,61,0,0,0,0],[44,47,0,0,0,0],[44,8,0,0,0,0],[25,9,0,0,0,0],[44,0,0,0,0,0],[44,366,0,0,0,0],[44,367,0,0,0,0],[44,367,0,162,0,0],[44,368,0,0,0,0],[45,370,0,0,0,0],[65,367,0,0,0,0],[65,370,0,0,0,0],[65,369,0,0,0,0],[65,0,346,0,0,0],[64,0,347,0,0,0],[65,0,348,0,0,0],[65,0,0,326,0,0],[5,0,0,327,205,0],[5,0,0,0,226,0]],[[44,68,0,0,0,0],[44,68,0,0,0,0],[44,67,0,0,0,0],[25,68,0,0,0,0],[44,28,0,0,0,0],[45,60,0,0,0,0],[44,61,0,0,0,3],[44,60,0,0,0,0],[44,29,0,0,0,0],[44,0,0,0,0,0],[25,0,0,0,0,0],[44,0,0,0,0,0],[44,0,182,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[45,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[65,366,0,0,0,0],[65,367,0,0,0,0],[65,368,0,0,0,0],[65,0,346,0,0,0],[5,0,347,0,225,0],[5,0,0,0,246,0]],[[44,0,0,0,170,0],[44,0,0,0,167,0],[44,0,0,0,169,0],[44,0,0,0,170,0],[25,66,0,0,172,0],[45,67,0,0,0,0],[45,28,0,0,0,0],[44,61,0,0,0,0],[45,47,0,0,0,0],[44,9,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[65,202,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,23,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[65,366,0,0,0,0],[65,369,0,0,245,0],[64,0,0,0,266,0]],[[4,0,0,0,191,0],[5,0,0,0,187,0],[44,0,0,0,248,0],[44,0,0,0,230,0],[44,0,0,0,191,0],[44,0,0,0,172,0],[45,26,0,0,0,2],[44,61,0,0,0,0],[44,41,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[45,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[44,63,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,265,0],[44,0,0,0,206,0]],[[5,0,0,0,247,0],[4,0,0,0,269,0],[44,0,0,0,250,0],[44,0,0,0,250,0],[45,0,0,0,211,0],[45,0,0,0,192,0],[25,26,0,0,0,0],[44,61,0,0,0,0],[44,61,0,0,0,0],[44,29,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,43,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[45,0,0,0,225,0],[64,0,0,0,228,0]],[[5,0,0,0,267,0],[5,0,0,0,268,0],[45,0,0,0,269,0],[44,0,0,0,270,0],[44,0,0,0,191,0],[45,0,0,0,232,0],[44,46,0,0,0,0],[44,60,0,0,0,0],[25,61,0,0,0,0],[44,49,0,0,0,0],[45,0,0,0,0,0],[64,0,0,0,0,1],[45,0,0,0,0,0],[64,0,0,0,0,0],[65,22,0,0,0,0],[65,62,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[24,0,0,0,0,0],[64,0,0,0,245,0],[45,0,0,0,266,0]],[[4,0,0,0,207,0],[4,0,0,0,208,0],[25,0,0,0,209,0],[44,0,0,0,210,0],[44,0,0,0,251,0],[45,0,0,0,252,0],[45,46,0,0,0,0],[44,61,0,0,0,0],[44,60,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[64,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,166,0],[65,0,0,0,266,0],[65,0,0,0,206,0]],[[5,0,0,0,227,0],[44,0,0,0,228,0],[44,0,0,0,229,0],[44,0,0,0,230,0],[44,0,0,0,271,0],[44,0,0,0,272,0],[25,26,0,0,0,0],[44,60,0,0,0,0],[44,41,0,0,0,0],[45,49,0,0,0,0],[44,0,0,0,0,0],[45,42,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[45,0,0,0,0,0],[65,63,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[65,62,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,185,0],[65,0,0,0,186,0],[5,0,0,0,206,0],[4,0,0,0,207,0]],[[44,0,0,0,247,0],[44,0,0,0,248,0],[44,0,0,0,249,0],[45,0,0,0,250,0],[44,0,0,0,211,0],[44,0,0,0,212,0],[25,46,0,0,0,0],[45,61,0,0,0,0],[44,61,0,0,0,0],[45,29,0,0,0,0],[45,0,0,0,0,0],[45,0,0,0,0,0],[45,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,205,0],[65,0,0,0,206,0],[5,0,0,0,207,0],[4,0,0,0,208,0]],[[5,0,0,0,267,0],[44,0,0,0,269,0],[44,0,0,0,269,0],[25,0,0,270,0,0],[44,0,0,0,231,0],[24,0,0,0,232,0],[45,66,0,0,0,0],[44,28,0,0,0,0],[44,60,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[24,0,0,0,0,0],[24,0,0,0,0,0],[5,0,0,0,0,0],[45,0,0,0,0,0],[24,0,0,0,0,0],[24,62,0,0,0,0],[64,23,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[45,0,0,0,225,0],[64,0,0,0,226,0],[4,0,0,0,227,0],[4,0,0,0,228,0]],[[44,0,0,0,287,0],[44,0,0,0,288,0],[45,0,0,0,289,0],[25,0,0,290,0,0],[45,0,0,0,291,0],[44,0,0,0,292,0],[45,0,0,0,0,0],[44,26,0,0,0,0],[45,60,0,0,0,0],[44,47,0,0,0,0],[25,7,0,0,0,0],[44,8,0,0,0,0],[44,9,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,245,0],[64,0,0,0,246,0],[4,0,0,0,247,0],[4,0,0,0,248,0]],[[5,0,0,307,0,0],[44,0,0,308,0,0],[44,0,0,309,0,0],[44,0,0,310,0,0],[44,0,0,311,0,0],[44,312,0,0,0,0],[44,0,0,0,0,0],[24,46,0,0,0,0],[24,60,0,0,0,0],[44,60,0,0,0,0],[44,60,0,0,0,0],[44,60,0,0,0,0],[44,29,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,63,0,0,0,0],[64,0,0,0,0,0],[44,0,0,0,0,0],[65,0,0,0,0,0],[65,0,0,0,0,0],[64,0,0,0,265,0],[65,0,0,0,266,0],[5,0,0,0,267,0],[4,0,0,0,268,0]],[[44,0,0,327,0,0],[44,0,0,328,0,0],[45,0,0,329,0,0],[24,0,330,0,0,0],[25,0,331,0,0,0],[24,332,0,0,0,0],[44,0,0,0,0,0],[44,66,0,0,0,0],[45,68,0,0,0,0],[25,67,0,0,0,0],[24,28,0,0,0,0],[44,60,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,0,0],[64,0,0,0,185,0],[64,0,0,0,186,0],[64,0,0,0,206,0],[5,0,0,0,207,0],[4,0,0,0,208,0]],[[44,0,347,0,0,0],[44,0,348,0,0,0],[44,0,349,0,0,0],[44,0,350,0,0,0],[44,351,1,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,66,0,0,0,0],[44,28,0,0,0,0],[44,29,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[64,0,0,0,166,0],[65,0,0,0,186,0],[64,0,0,0,188,0],[64,0,0,0,226,0],[4,0,0,0,227,0],[5,0,0,0,228,0]],[[4,367,0,0,0,0],[44,368,0,0,0,0],[24,369,0,0,0,0],[44,370,0,0,0,0],[44,371,0,0,0,0],[45,0,0,0,0,0],[25,0,0,0,0,0],[24,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,46,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,185,0],[5,0,0,0,186,0],[4,0,0,0,187,0],[4,0,0,0,250,0],[5,0,0,0,246,0],[5,0,0,0,247,0],[5,0,0,0,248,0]],[[4,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[24,0,0,0,0,0],[45,0,0,0,0,0],[44,46,0,0,0,0],[44,49,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[5,0,0,0,285,0],[4,0,0,0,206,0],[4,0,0,0,228,0],[5,0,0,0,207,0],[4,0,0,0,208,0],[4,0,0,0,209,0],[5,0,0,0,210,0]],[[5,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,66,0,0,0,0],[44,69,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,185,0],[5,0,0,0,266,0],[5,0,0,0,226,0],[4,0,0,0,227,0],[4,0,0,0,228,0],[4,0,0,0,229,0],[5,0,0,0,230,0],[5,0,0,0,231,0]],[[4,0,0,0,0,0],[44,0,0,0,0,0],[25,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[24,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,185,0],[44,0,0,0,186,0],[4,0,0,0,206,0],[4,0,0,0,246,0],[5,0,0,0,247,0],[5,0,0,0,248,0],[4,0,0,0,249,0],[4,0,0,0,250,0],[5,0,0,0,251,0]],[[4,0,0,0,0,0],[5,0,0,0,0,0],[44,0,0,0,0,0],[24,6,0,0,0,0],[44,7,0,0,0,0],[44,7,0,0,0,0],[44,8,0,0,0,0],[44,7,0,0,0,0],[24,9,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,205,0],[44,0,0,0,206,0],[4,0,0,0,226,0],[5,0,0,0,227,0],[4,0,0,0,266,0],[4,0,0,0,267,0],[5,0,0,0,268,0],[5,0,0,0,269,0],[4,0,0,0,271,0]],[[5,0,0,0,0,0],[4,6,0,0,0,0],[44,7,0,0,0,0],[44,48,0,0,0,0],[44,40,0,0,0,0],[45,41,0,0,0,0],[44,27,0,0,0,0],[45,67,0,0,0,0],[44,69,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,0,0],[24,0,0,0,0,0],[44,0,0,0,0,0],[44,0,0,0,225,0],[4,0,0,0,226,0],[4,0,0,0,246,0],[4,0,0,0,247,0],[5,0,0,0,207,0],[5,0,0,0,208,0],[4,0,0,0,209,0],[4,0,0,0,210,0],[5,0,0,0,211,0]],[[5,8,0,0,0,0],[4,48,0,0,0,0],[4,60,0,0,0,0],[24,41,0,0,0,0],[45,60,0,0,0,0],[24,27,0,0,0,0],[45,69,0,0,0,0],[44,0,0,0,0,0],[24,0,0,0,0,0],[24,0,0,0,0,0],[24,0,0,0,0,0],[44,0,0,0,166,0],[44,0,0,0,169,0],[25,0,0,0,167,0],[24,0,0,0,168,0],[24,0,0,0,186,0],[44,0,0,0,187,0],[4,0,0,0,266,0],[5,0,0,0,267,0],[5,0,0,0,226,0],[4,0,0,0,227,0],[4,0,0,0,228,0],[5,0,0,0,229,0],[4,0,0,0,230,0]],[[24,60,0,0,0,0],[24,41,0,0,0,0],[24,40,0,0,0,0],[24,27,0,0,0,0],[44,67,0,0,0,0],[25,69,0,0,0,0],[44,0,0,0,0,0],[45,0,0,0,0,0],[24,0,0,0,166,0],[45,0,0,0,169,0],[24,0,0,0,170,0],[24,0,0,0,186,0],[24,0,0,0,189,0],[45,0,0,0,187,0],[24,0,0,0,188,0],[24,0,0,0,206,0],[45,0,0,0,207,0],[4,0,0,0,226,0],[5,0,0,0,227,0],[4,0,0,0,247,0],[4,0,0,0,248,0],[5,0,0,0,249,0],[4,0,0,0,250,0],[5,0,0,0,251,0]],[[24,41,0,0,0,0],[45,60,0,0,0,0],[24,60,0,0,0,0],[45,49,0,0,0,0],[44,0,0,0,0,0],[24,0,0,0,0,0],[24,0,0,0,0,0],[24,0,0,0,185,0],[24,0,0,0,186,0],[44,0,0,0,189,0],[44,0,0,0,190,0],[24,0,0,0,206,0],[44,0,0,0,207,0],[24,0,0,0,208,0],[45,0,0,0,209,0],[24,0,0,0,210,0],[24,0,0,0,246,0],[4,0,0,0,247,0],[4,0,0,0,248,0],[4,0,0,0,249,0],[5,0,0,0,250,0],[5,0,0,0,251,0],[5,0,0,0,248,0],[4,0,0,0,249,0]],[[24,67,0,0,0,0],[24,67,0,0,0,0],[24,68,0,0,0,0],[44,69,0,0,0,0],[24,0,0,0,0,0],[25,0,0,0,0,0],[24,0,0,0,0,0],[25,0,0,0,205,0],[45,0,0,0,206,0],[24,0,0,0,209,0],[45,0,0,0,210,0],[44,0,0,0,227,0],[24,0,0,0,228,0],[45,0,0,0,229,0],[25,0,0,0,230,0],[45,0,0,0,271,0],[24,0,0,0,266,0],[5,0,0,0,267,0],[5,0,0,0,268,0],[4,0,0,0,269,0],[4,0,0,0,270,0],[4,0,0,0,271,0],[5,0,0,0,266,0],[5,0,0,0,267,0]],[[24,0,0,0,167,0],[24,0,0,0,168,0],[24,0,0,0,169,0],[25,0,0,0,170,0],[24,0,0,0,167,0],[24,0,0,0,168,0],[44,0,0,0,169,0],[24,0,0,0,186,0],[44,0,0,0,226,0],[24,0,0,0,229,0],[24,0,0,0,230,0],[25,0,0,0,247,0],[24,0,0,0,248,0],[24,0,0,0,249,0],[45,0,0,0,250,0],[24,0,0,0,291,0],[24,0,0,0,206,0],[4,0,0,0,207,0],[5,0,0,0,208,0],[4,0,0,0,209,0],[5,0,0,0,210,0],[5,0,0,0,211,0],[4,0,0,0,206,0],[5,0,0,0,207,0]],[[24,0,0,0,187,0],[24,0,0,0,188,0],[45,0,0,0,189,0],[44,0,0,0,190,0],[24,0,0,0,187,0],[45,0,0,0,188,0],[24,0,0,0,189,0],[25,0,0,0,206,0],[24,0,0,0,246,0],[25,0,0,0,249,0],[44,0,0,0,250,0],[24,0,0,0,267,0],[45,0,0,0,268,0],[24,0,0,0,269,0],[45,0,0,0,270,0],[45,0,0,0,226,0],[24,0,0,0,227,0],[5,0,0,0,228,0],[4,0,0,0,229,0],[4,0,0,0,230,0],[4,0,0,0,231,0],[5,0,0,0,208,0],[5,0,0,0,209,0],[5,0,0,0,210,0]],[[24,0,0,0,207,0],[24,0,0,0,208,0],[45,0,0,0,209,0],[24,0,0,0,210,0],[45,0,0,0,207,0],[44,0,0,0,208,0],[45,0,0,0,209,0],[44,0,0,0,210,0],[24,0,0,0,266,0],[24,0,0,0,269,0],[24,0,0,0,270,0],[24,0,0,0,207,0],[45,0,0,0,208,0],[24,0,0,0,209,0],[24,0,0,0,210,0],[45,0,0,0,228,0],[45,0,0,0,229,0],[45,0,0,0,230,0],[4,0,0,0,231,0],[4,0,0,0,226,0],[5,0,0,0,227,0],[5,0,0,0,228,0],[4,0,0,0,229,0],[5,0,0,0,230,0]]],
    &quot;tileset&quot;: &quot;tileset.png&quot;,
    &quot;borderMap&quot; : [{
        &quot;mapName&quot; : &quot;map1&quot;, 
        &quot;cardDir&quot; : &quot;west&quot;,
        &quot;index&quot; : 0
    }]
  }&lt;/pre&gt;&lt;/code&gt;
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.2/lib/Transplan.js&quot;&gt; &lt;/script&gt;
&lt;h3&gt;Le visible&lt;/h3&gt;
&lt;h4&gt;Les événements&lt;/h4&gt;
&lt;p&gt;
Premières choses : désormais, il y a des événements ! Ce sont ces carrés bleus, qui vont déclencher un script dans différentes conditions. Certains se déclenchent au passage, d&#039;autre lorsqu&#039;on est dessus et qu&#039;on appuie sur une touche.
&lt;/p&gt;
&lt;p&gt;
Le script de l&#039;événement est une bête fonction JavaScript, mais qui a accès à tous les objets du jeu (le joueur, la map, les ennemis quand ils arriveront ...). De cette manière, la fonction est appelée à chaque passage sur la case, mais elle n&#039;effectuera une action qu&#039;a certaine conditions, explicitée dans le corps de la fonction (par exemple, ne se déclencher que si la touche espace est pressée) et cette action peut cibler n&#039;importe quoi, par exemple immobiliser le joueur durant l&#039;affichage d&#039;un texte. Lorsqu&#039;un événement est déclenché, il bloque tous les autres, pour éviter qu&#039;un second événement se lance durant le premier.
&lt;/p&gt;
&lt;h4&gt;La boite de dialogue&lt;/h4&gt;
&lt;p&gt;
Les événements amènent à une deuxième avancée : la boite de dialogue. Elle suit le joueur où qu&#039;il aille, en s&#039;adaptant à sa position (passage à droite ou à gauche, là ou il y a le plus de places) et permet d&#039;afficher une suite de texte, en passant au suivant à l&#039;appui sur la touche espace. Le tout est en HTML/CSS, parce que pour formater du texte, c&#039;est quand même le plus simple.
&lt;/p&gt;
&lt;p&gt;
Elle est capable de gérer une file de texte à afficher, et peut déclencher une fonction lorsque la file est vide. De cette manière, on peut déclencher une action à la fin d&#039;un phase de dialogue. De plus, on ne peut passer au texte suivant qu&#039;une seconde après sont affichage, pour éviter les validations intempestives (oups, je suis resté appuyé trop longtemps sur espace !)
&lt;/p&gt;
&lt;h4&gt;La gestion de profondeur&lt;/h4&gt;
&lt;p&gt;
Dans la première version, une partie de la map était dessinée sous le héros, puis le héros, puis la seconde partie de la map. De cette manière, certains objets pouvaient occulter le héros. Le souci, c&#039;est que le héros fait 3 tiles de haut. Lorsque le héros avance vers le sud et se retrouve face à un arbre, il doit apparaitre au-dessus de l&#039;arbre. Mais s&#039;il arrive depuis le sud, il doit apparaitre derrière !
&lt;/p&gt;
&lt;p&gt;
Pour pouvoir le faire passer correctement derrière un tronc d&#039;arbre, il a fallu découper le joueur en 3 tranches, et l&#039;afficher sur 3 niveaux différents. De la même manière, le terrain à été découpé en tranches (5 en tout). L&#039;idée étant qu&#039;il y aura une partie affichée sous les pieds du héros (tranche 1), sous le buste (tranche 2) et sous la tête (tranche 3).
&lt;/p&gt;
&lt;h3&gt;L&#039;invisible&lt;/h3&gt;
&lt;h4&gt;Chargement des maps&lt;/h4&gt;
&lt;p&gt;
Dans la première version, je disposais d&#039;un objet énorme, qui contenait toutes les maps du jeu. Le souci étant qu&#039;il allait falloir charger un fichier contenant les données de cet objet, et que ça forçait un temps d&#039;attente avant de lancer le jeu
&lt;/p&gt;
&lt;p&gt;
Pour changer ça, j&#039;ai stocké les maps séparément, chacune dans son objet, mais avec un pointeur vers les maps voisines. Lorsque le héros rentre dans une map, on déclenche le chargement des maps voisines (ajax est mon ami). De cette manière la transition entre les maps sera fluide, sans pour autant devoir charger l&#039;intégralité du jeu.
&lt;/p&gt;
&lt;h4&gt;Gestion interne&lt;/h4&gt;
&lt;p&gt;
Dans la version 0.1, des fonctions étaient appelées dans une grande boucle, qui appelaient d&#039;autres fonctions, selon les touches enfoncées au moment précis, qui à leurs tours appelaient d&#039;autres fonctions. C&#039;était le plus simple à mettre en place, mais ça a mené à du code imbuvable, avec des conditions partout et des fonctions de 1500 lignes de long.
&lt;/p&gt;
&lt;p&gt;
Pour remédier à ça, j&#039;ai adopté un modèle évènementiel. L&#039;appui sur une touche déclenche un événement, cet événement va déclencher plusieurs fonctions qui pourront, selon les cas, déclencher d&#039;autres évènements. On peut voir les événements déclenchés en ouvrant la console JavaScript (ils sont loggés)
&lt;/p&gt;
&lt;h4&gt;Chargement du code&lt;/h4&gt;
&lt;p&gt;
Précédemment, le code, contenu dans plusieurs petits fichiers, était intégralement linké pour lancer le jeu. Comme le chargement de script est bloquant, chaque script était chargé à son tour. Outre la lourdeur du code avec ses 15 balises &amp;lt;script&amp;gt;, il fallait prier pour que le script se lance lorsque tout était bien chargé.
&lt;/p&gt;
&lt;p&gt;
Désormais, on n&#039;inclue qu&#039;un seul script dans la page, qui se chargera de récupérer le reste. Puis, quand tout sera chargé, le jeu sera lancé.
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/p&gt;
&lt;h3&gt;En bref&lt;/h3&gt;
&lt;p&gt;
J&#039;ai passé pas mal de temps à tout réécrire proprement, et visiblement ça a payé, puisque l&#039;implémentation de nouvelles fonctionnalités (événements, par exemple) a été très rapide.
&lt;/p&gt;
&lt;p&gt;
Maintenant, va falloir s&#039;attaquer au prochain gros morceau, les ennemis, les IA, la gestion du combat. Mais j&#039;ai pleins d&#039;autre petite idée à ajouter et/ou tester. Par exemple, rajouter un calque qui permettrait de faire varier la luminosité et la teinte de l&#039;ensemble, pour faire des jeux de lumière. En bref, du fun en perspective !
&lt;/p&gt;</description>
		<pubDate>Wed, 30 Oct 2013 12:27:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Glitch</title> 
		<link>https://whiteshoulders.fr/index.php?article162/glitch</link>
		<guid>https://whiteshoulders.fr/index.php?article162/glitch</guid>
		<description>&lt;p&gt;J&#039;aime bien les glitch, j&#039;aime le javascript. Donc j&#039;ai mixé les deux, pour un résultat des plus approximatif. L&#039;idée étant que ça ressemble à l&#039;image d&#039;une VHS qui a moisi trop longtemps.&lt;/p&gt;&lt;p&gt;Résultat : Choisissez une bien belle image sur votre disque dur (de préférence pas plus grande que 400x400, histoire que ça ne mouline pas trop) et déposez la sur le cadre gris ou choisissez-en une à droite, réglez le niveau de glitchiness, et glitchez moi ça.&lt;/p&gt;
&lt;style&gt;
    #glitch_wrapper{
        margin:40px auto;
        width:530px;
    }
    canvas{
        background-color:#BBB;
        float:left;
    }
     #controls{
        clear:both;
     }
    #controls button{
        float:left;
        margin-left:30px
    }

    #controls p{
        float:left;
        margin:0;
        padding:4px;
    }
    #imSelect{
        float:left;
        margin-top:-20px;
    }
    #imSelect img{
        padding:5px;
        margin-left:20px;
    }
    &lt;/style&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;div id=&quot;glitch_wrapper&quot;&amp;gt;
    &amp;lt;canvas id=&quot;glitched&quot; height=&quot;400&quot; width=&quot;400&quot;&amp;gt;&amp;lt;/canvas&amp;gt;
    &amp;lt;div id=&quot;imSelect&quot;&amp;gt;
        &amp;lt;img id=&quot;im1&quot; src=&quot;/data/images/glitch/im1_t.png&quot; /&amp;gt;&amp;lt;br/&amp;gt;
        &amp;lt;img id=&quot;im2&quot; src=&quot;/data/images/glitch/im2_t.png&quot; /&amp;gt;&amp;lt;br/&amp;gt;
        &amp;lt;img id=&quot;im3&quot; src=&quot;/data/images/glitch/im3_t.png&quot; /&amp;gt;&amp;lt;br/&amp;gt;
        &amp;lt;img id=&quot;im4&quot; src=&quot;/data/images/glitch/im4_t.png&quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id=&quot;controls&quot;&amp;gt;
        &amp;lt;p&amp;gt;GLITCHINESS: &amp;lt;input id=&quot;glitchiness&quot; type=&quot;range&quot; value=&quot;10&quot; max=&quot;20&quot; min=&quot;0&quot;&amp;gt;&amp;lt;/input&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;button id=&quot;glitch&quot;&amp;gt;Glitch !&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    var glitchness = 0.5;
    var canvas = document.getElementById(&quot;glitched&quot;);
    var context = canvas.getContext(&quot;2d&quot;);
    var img = document.createElement(&quot;img&quot;);
    var button = document.getElementById(&quot;glitch&quot;);
    var slider = document.getElementById(&#039;glitchiness&#039;)

    context.font = &#039;normal 20pt Calibri&#039;;
    context.fillText(&quot;Deposez une image&quot;, 100, 185);
    context.fillText(&quot;ou choisissez-en une&quot;, 95, 215);

    var im1 = document.getElementById(&quot;im1&quot;);
    var im2 = document.getElementById(&quot;im2&quot;);
    var im3 = document.getElementById(&quot;im3&quot;);
    var im4 = document.getElementById(&quot;im4&quot;);
    im1.onclick = function(){
        img.src = &quot;/data/images/glitch/im1.png&quot;;
    }

    im2.onclick = function(){
        img.src = &quot;/data/images/glitch/im2.png&quot;;
    }

    im3.onclick = function(){
        img.src = &quot;/data/images/glitch/im3.png&quot;;
    }

    im4.onclick = function(){
        img.src = &quot;/data/images/glitch/im4.png&quot;;
    }   

    canvas.addEventListener(&quot;dragover&quot;, function(evt){
        evt.preventDefault();
    }, false);

    canvas.addEventListener(&quot;drop&quot;, function(evt){
        var files = evt.dataTransfer.files;
        if(files.length&amp;gt;0){
            var file = files[0];
            if(typeof FileReader !== &quot;undefined&quot; &amp;amp;amp;&amp;amp;amp; file.type.indexOf(&quot;image&quot; != -1)){
                var reader = new FileReader();
                reader.onload = function(evt){
                    img.src = evt.target.result;
                }
                reader.readAsDataURL(file);
            }
        }
        evt.preventDefault();
    }, false);

    img.addEventListener(&quot;load&quot;, function(){
        canvas.width = img.width;
        canvas.height = img.height;
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(img, 0, 0); 
        stackBlurCanvasRGB(&quot;glitched&quot;, 0, 0, canvas.width, canvas.height,1);
    })

    button.addEventListener(&quot;click&quot;, function(){
        glitchness = slider.value/20;
        var canvasWidth = canvas.width;
        var canvasHeight = canvas.height;
        context.drawImage(img, 0, 0); 
        var imData = context.getImageData(0, 0, canvasWidth, canvasHeight);
        var data = imData.data;
        var dataOriginal = JSON.parse(JSON.stringify(data));

        var aleat = Math.pow(0.9999, glitchness);
        var aleat1 = Math.pow(0.999, glitchness);

        var fact1 = 1;
        var fact2 = 1;
        var decalX = 0;
        var deform = false;
        var freq = 10;
        var amp = 0;
        var red = glitchness*Math.random()+1;
        var green = glitchness*Math.random()+1;
        var blue = glitchness*Math.random()+1;
        var reverseX = Math.random()&amp;gt;0.5;
        var reverseY = Math.random()&amp;gt;0.5;
        var minX = 0;
        var maxX = 0;
        var c1 = 1;
        var c2 = 1;
        var c3 = 1;

        var d1 = 0.7+0.3*Math.random()*glitchness;
        var d2 = 0.7+0.3*Math.random()*glitchness;
        var d3 = 0.7+0.3*Math.random()*glitchness;

        var r = (glitchness === 0) ? 0 : Math.floor(Math.random()*3);
        var v = (glitchness === 0) ? 1 : Math.floor(Math.random()*3);
        var b = (glitchness === 0) ? 2 : Math.floor(Math.random()*3);

        for (var yd = 0; yd &amp;lt; canvasHeight; yd += 1) {
            for (var xd = 0; xd &amp;lt; canvasWidth; xd += 1) {
                if(reverseY){
                    y = canvasWidth-yd-1;
                }else{
                    y = yd;
                }

                if(reverseX){
                    x = canvasWidth-xd-1;
                }else{
                    x = xd;
                }

                var index1 = (y * canvasWidth + x) * 4;
                var variation = 0.000001*(Math.floor(Math.random()*2)*2-1);
                if(deform){
                    fact1 += variation*Math.random();
                    fact2 += variation*Math.random();
                }
                if(fact1&amp;gt;1 || !deform){
                    fact1 = 1;
                }
                if(fact2&amp;gt;1 || !deform){
                    fact2 = 1;
                }

                if(Math.random()&amp;gt;aleat){
                    decalX = (Math.floor(Math.random()*2)-1)*50*Math.random()*glitchness;
                    minX = Math.floor(canvasWidth/2*Math.random());
                    maxX = canvasWidth/2+Math.floor(canvasWidth/2*Math.random());
                }
                if(x&amp;gt;minX &amp;amp;amp;&amp;amp;amp; x&amp;lt;maxX){
                    x+=Math.floor(decalX);
                }

                var index2 = Math.floor((y*fact1 * canvasWidth + (x+decalX)*fact2) * 4);
                if(Math.random()&amp;gt;aleat1){
                    var freq = (Math.random())*100;
                    var amp = (Math.random())*50*glitchness;
                }
                index2 = index2 + Math.floor(Math.sin(y/freq)*amp);

                if(Math.random()&amp;gt;aleat){
                    deform = !deform;
                    fact1 = 1;
                    fact2 = 1;
                }

                index2 = Math.floor(index2*glitchness + (1-glitchness)*index1);
                index3 = Math.floor((y * canvasWidth + x+decalX) * 4);

                if(Math.random()&amp;gt;aleat){
                     c1 = Math.random()*glitchness;
                     c2 = Math.random()*glitchness;
                     c3 = Math.random()*glitchness;
                }
                data[index1+0] = Math.floor((dataOriginal[index2+0]*red + (1 + c1-glitchness)*dataOriginal[index3+0])/(2+c1) - Math.random()*50*glitchness);
                data[index1+1] = Math.floor((dataOriginal[index2+1]*green + (1 + c2-glitchness)*dataOriginal[index3+1])/(2+c1) - Math.random()*50*glitchness);
                data[index1+2] = Math.floor((dataOriginal[index2+2]*blue + (1 + c3-glitchness)*dataOriginal[index3+2] )/(2+c1) - Math.random()*50*glitchness);

                var blackBand = Math.pow(Math.sin(y),4)*2;
                data[index1+0] = (d1*data[index1+0] + (1-d1)*dataOriginal[index1+r])*Math.pow(blackBand,glitchness);
                data[index1+1] = (d2*data[index1+1] + (1-d2)*dataOriginal[index1+v])*Math.pow(blackBand,glitchness);
                data[index1+2] = (d3*data[index1+2] + (1-d3)*dataOriginal[index1+b])*Math.pow(blackBand,glitchness);
            }
        }
        context.putImageData(imData, 0, 0);
        stackBlurCanvasRGB(&quot;glitched&quot;, 0, 0, canvas.width, canvas.height,1+Math.pow(Math.random(),2)*4*glitchness);
    }, false);&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;/&lt;em&gt;
StackBlur - a fast almost Gaussian Blur For Canvas&lt;/p&gt;
&lt;p&gt;Version:    0.5
Author:     Mario Klingemann
Contact:    mario@quasimondo.com
Website:    &lt;a href=&quot;http://www.quasimondo.com/StackBlurForCanvas&quot;&gt;&lt;a href=&quot;http://www.quasimondo.com/StackBlurForCanvas&amp;lt;/a&quot;&gt;http://www.quasimondo.com/StackBlurForCanvas&amp;lt;/a&lt;/a&gt;&gt;
Twitter:    @quasimondo
In case you find this class useful - especially in commercial projects -
I am not totally unhappy for a small donation to my PayPal account
mario@quasimondo.de
Or support me on flattr: 
&lt;a href=&quot;https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript&quot;&gt;&lt;a href=&quot;https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript&amp;lt;/a&quot;&gt;https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript&amp;lt;/a&lt;/a&gt;&gt;
Copyright (c) 2010 Mario Klingemann
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the &quot;Software&quot;), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
&lt;/em&gt;/
var mul_table = [512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,&lt;/p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,
482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,
437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,
497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,
320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,
446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,
329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,
505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,
399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,
324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,
268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,
451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,
385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,
332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,
289,287,285,282,280,278,275,273,271,269,267,265,263,261,259];&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;var shg_table = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, &lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 ];&amp;lt;/code&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;function stackBlurImage( imageID, canvasID, radius, blurAlphaChannel )
{&lt;/p&gt;
&lt;p&gt;var img = document.getElementById( imageID );
var w = img.naturalWidth;
var h = img.naturalHeight;&lt;/p&gt;
&lt;p&gt;var canvas = document.getElementById( canvasID );&lt;/p&gt;
&lt;p&gt;canvas.style.width  = w + &quot;px&quot;;
canvas.style.height = h + &quot;px&quot;;
canvas.width = w;
canvas.height = h;&lt;/p&gt;
&lt;p&gt;var context = canvas.getContext(&quot;2d&quot;);
context.clearRect( 0, 0, w, h );
context.drawImage( img, 0, 0 );&lt;/p&gt;
&lt;p&gt;if ( isNaN(radius) || radius &amp;lt; 1 ) return;&lt;/p&gt;
&lt;p&gt;if ( blurAlphaChannel )&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;stackBlurCanvasRGBA( canvasID, 0, 0, w, h, radius );&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;else &lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;stackBlurCanvasRGB( canvasID, 0, 0, w, h, radius );&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}function stackBlurCanvasRGBA( id, top_x, top_y, width, height, radius )
{&lt;/p&gt;
&lt;p&gt;if ( isNaN(radius) || radius &amp;lt; 1 ) return;
radius |= 0;&lt;/p&gt;
&lt;p&gt;var canvas  = document.getElementById( id );
var context = canvas.getContext(&quot;2d&quot;);
var imageData;&lt;/p&gt;
&lt;p&gt;try {
try {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;imageData = context.getImageData( top_x, top_y, width, height );&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;} catch(e) {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;// NOTE: this part is supposedly only needed if you want to work with local files
// so it might be okay to remove the whole try/catch block and just use
// imageData = context.getImageData( top_x, top_y, width, height );
try {
    netscape.security.PrivilegeManager.enablePrivilege(&quot;UniversalBrowserRead&quot;);
    imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
    alert(&quot;Cannot access local image&quot;);
    throw new Error(&quot;unable to access local image data: &quot; + e);
    return;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}
} catch(e) {
alert(&quot;Cannot access image&quot;);
throw new Error(&quot;unable to access image data: &quot; + e);
}&lt;/p&gt;
&lt;p&gt;var pixels = imageData.data;&lt;/p&gt;
&lt;p&gt;var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, 
r_out_sum, g_out_sum, b_out_sum, a_out_sum,
r_in_sum, g_in_sum, b_in_sum, a_in_sum, 
pr, pg, pb, pa, rbs;&lt;/p&gt;
&lt;p&gt;var div = radius + radius + 1;
var w4 = width &amp;lt;&amp;lt; 2;
var widthMinus1  = width - 1;
var heightMinus1 = height - 1;
var radiusPlus1  = radius + 1;
var sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2;&lt;/p&gt;
&lt;p&gt;var stackStart = new BlurStack();
var stack = stackStart;
for ( i = 1; i &amp;lt; div; i++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;stack = stack.next = new BlurStack();
if ( i == radiusPlus1 ) var stackEnd = stack;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}
stack.next = stackStart;
var stackIn = null;
var stackOut = null;&lt;/p&gt;
&lt;p&gt;yw = yi = 0;&lt;/p&gt;
&lt;p&gt;var mul_sum = mul_table[radius];
var shg_sum = shg_table[radius];&lt;/p&gt;
&lt;p&gt;for ( y = 0; y &amp;lt; height; y++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0;

r_out_sum = radiusPlus1 * ( pr = pixels[yi] );
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1] );
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2] );
a_out_sum = radiusPlus1 * ( pa = pixels[yi+3] );

r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
a_sum += sumFactor * pa;

stack = stackStart;

for( i = 0; i &amp;lt; radiusPlus1; i++ )
{
    stack.r = pr;
    stack.g = pg;
    stack.b = pb;
    stack.a = pa;
    stack = stack.next;
}

for( i = 1; i &amp;lt; radiusPlus1; i++ )
{
    p = yi + (( widthMinus1 &amp;lt; i ? widthMinus1 : i ) &amp;lt;&amp;lt; 2 );
    r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i );
    g_sum += ( stack.g = ( pg = pixels[p+1])) * rbs;
    b_sum += ( stack.b = ( pb = pixels[p+2])) * rbs;
    a_sum += ( stack.a = ( pa = pixels[p+3])) * rbs;

    r_in_sum += pr;
    g_in_sum += pg;
    b_in_sum += pb;
    a_in_sum += pa;

    stack = stack.next;
}

stackIn = stackStart;
stackOut = stackEnd;
for ( x = 0; x &amp;lt; width; x++ )
{
    pixels[yi+3] = pa = (a_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    if ( pa != 0 )
    {
        pa = 255 / pa;
        pixels[yi]   = ((r_sum * mul_sum) &amp;gt;&amp;gt; shg_sum) * pa;
        pixels[yi+1] = ((g_sum * mul_sum) &amp;gt;&amp;gt; shg_sum) * pa;
        pixels[yi+2] = ((b_sum * mul_sum) &amp;gt;&amp;gt; shg_sum) * pa;
    } else {
        pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0;
    }

    r_sum -= r_out_sum;
    g_sum -= g_out_sum;
    b_sum -= b_out_sum;
    a_sum -= a_out_sum;

    r_out_sum -= stackIn.r;
    g_out_sum -= stackIn.g;
    b_out_sum -= stackIn.b;
    a_out_sum -= stackIn.a;

    p =  ( yw + ( ( p = x + radius + 1 ) &amp;lt; widthMinus1 ? p : widthMinus1 ) ) &amp;lt;&amp;lt; 2;

    r_in_sum += ( stackIn.r = pixels[p]);
    g_in_sum += ( stackIn.g = pixels[p+1]);
    b_in_sum += ( stackIn.b = pixels[p+2]);
    a_in_sum += ( stackIn.a = pixels[p+3]);

    r_sum += r_in_sum;
    g_sum += g_in_sum;
    b_sum += b_in_sum;
    a_sum += a_in_sum;

    stackIn = stackIn.next;

    r_out_sum += ( pr = stackOut.r );
    g_out_sum += ( pg = stackOut.g );
    b_out_sum += ( pb = stackOut.b );
    a_out_sum += ( pa = stackOut.a );

    r_in_sum -= pr;
    g_in_sum -= pg;
    b_in_sum -= pb;
    a_in_sum -= pa;

    stackOut = stackOut.next;

    yi += 4;
}
yw += width;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( x = 0; x &amp;lt; width; x++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0;

yi = x &amp;lt;&amp;lt; 2;
r_out_sum = radiusPlus1 * ( pr = pixels[yi]);
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1]);
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2]);
a_out_sum = radiusPlus1 * ( pa = pixels[yi+3]);

r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;
a_sum += sumFactor * pa;

stack = stackStart;

for( i = 0; i &amp;lt; radiusPlus1; i++ )
{
    stack.r = pr;
    stack.g = pg;
    stack.b = pb;
    stack.a = pa;
    stack = stack.next;
}

yp = width;

for( i = 1; i &amp;lt;= radius; i++ )
{
    yi = ( yp + x ) &amp;lt;&amp;lt; 2;

    r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i );
    g_sum += ( stack.g = ( pg = pixels[yi+1])) * rbs;
    b_sum += ( stack.b = ( pb = pixels[yi+2])) * rbs;
    a_sum += ( stack.a = ( pa = pixels[yi+3])) * rbs;

    r_in_sum += pr;
    g_in_sum += pg;
    b_in_sum += pb;
    a_in_sum += pa;

    stack = stack.next;

    if( i &amp;lt; heightMinus1 )
    {
        yp += width;
    }
}

yi = x;
stackIn = stackStart;
stackOut = stackEnd;
for ( y = 0; y &amp;lt; height; y++ )
{
    p = yi &amp;lt;&amp;lt; 2;
    pixels[p+3] = pa = (a_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    if ( pa &amp;gt; 0 )
    {
        pa = 255 / pa;
        pixels[p]   = ((r_sum * mul_sum) &amp;gt;&amp;gt; shg_sum ) * pa;
        pixels[p+1] = ((g_sum * mul_sum) &amp;gt;&amp;gt; shg_sum ) * pa;
        pixels[p+2] = ((b_sum * mul_sum) &amp;gt;&amp;gt; shg_sum ) * pa;
    } else {
        pixels[p] = pixels[p+1] = pixels[p+2] = 0;
    }

    r_sum -= r_out_sum;
    g_sum -= g_out_sum;
    b_sum -= b_out_sum;
    a_sum -= a_out_sum;

    r_out_sum -= stackIn.r;
    g_out_sum -= stackIn.g;
    b_out_sum -= stackIn.b;
    a_out_sum -= stackIn.a;

    p = ( x + (( ( p = y + radiusPlus1) &amp;lt; heightMinus1 ? p : heightMinus1 ) * width )) &amp;lt;&amp;lt; 2;

    r_sum += ( r_in_sum += ( stackIn.r = pixels[p]));
    g_sum += ( g_in_sum += ( stackIn.g = pixels[p+1]));
    b_sum += ( b_in_sum += ( stackIn.b = pixels[p+2]));
    a_sum += ( a_in_sum += ( stackIn.a = pixels[p+3]));

    stackIn = stackIn.next;

    r_out_sum += ( pr = stackOut.r );
    g_out_sum += ( pg = stackOut.g );
    b_out_sum += ( pb = stackOut.b );
    a_out_sum += ( pa = stackOut.a );

    r_in_sum -= pr;
    g_in_sum -= pg;
    b_in_sum -= pb;
    a_in_sum -= pa;

    stackOut = stackOut.next;

    yi += width;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;context.putImageData( imageData, top_x, top_y );&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;}
function stackBlurCanvasRGB( id, top_x, top_y, width, height, radius )
{
if ( isNaN(radius) || radius &amp;lt; 1 ) return;
radius |= 0;&lt;/p&gt;
&lt;p&gt;var canvas  = document.getElementById( id );
var context = canvas.getContext(&quot;2d&quot;);
var imageData;&lt;/p&gt;
&lt;p&gt;try {
try {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;imageData = context.getImageData( top_x, top_y, width, height );&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;} catch(e) {&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;// NOTE: this part is supposedly only needed if you want to work with local files
// so it might be okay to remove the whole try/catch block and just use
// imageData = context.getImageData( top_x, top_y, width, height );
try {
    netscape.security.PrivilegeManager.enablePrivilege(&quot;UniversalBrowserRead&quot;);
    imageData = context.getImageData( top_x, top_y, width, height );
} catch(e) {
    alert(&quot;Cannot access local image&quot;);
    throw new Error(&quot;unable to access local image data: &quot; + e);
    return;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}
} catch(e) {
alert(&quot;Cannot access image&quot;);
throw new Error(&quot;unable to access image data: &quot; + e);
}&lt;/p&gt;
&lt;p&gt;var pixels = imageData.data;&lt;/p&gt;
&lt;p&gt;var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum,
r_out_sum, g_out_sum, b_out_sum,
r_in_sum, g_in_sum, b_in_sum,
pr, pg, pb, rbs;&lt;/p&gt;
&lt;p&gt;var div = radius + radius + 1;
var w4 = width &amp;lt;&amp;lt; 2;
var widthMinus1  = width - 1;
var heightMinus1 = height - 1;
var radiusPlus1  = radius + 1;
var sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2;&lt;/p&gt;
&lt;p&gt;var stackStart = new BlurStack();
var stack = stackStart;
for ( i = 1; i &amp;lt; div; i++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;stack = stack.next = new BlurStack();
if ( i == radiusPlus1 ) var stackEnd = stack;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}
stack.next = stackStart;
var stackIn = null;
var stackOut = null;&lt;/p&gt;
&lt;p&gt;yw = yi = 0;&lt;/p&gt;
&lt;p&gt;var mul_sum = mul_table[radius];
var shg_sum = shg_table[radius];&lt;/p&gt;
&lt;p&gt;for ( y = 0; y &amp;lt; height; y++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0;

r_out_sum = radiusPlus1 * ( pr = pixels[yi] );
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1] );
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2] );

r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;

stack = stackStart;

for( i = 0; i &amp;lt; radiusPlus1; i++ )
{
    stack.r = pr;
    stack.g = pg;
    stack.b = pb;
    stack = stack.next;
}

for( i = 1; i &amp;lt; radiusPlus1; i++ )
{
    p = yi + (( widthMinus1 &amp;lt; i ? widthMinus1 : i ) &amp;lt;&amp;lt; 2 );
    r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i );
    g_sum += ( stack.g = ( pg = pixels[p+1])) * rbs;
    b_sum += ( stack.b = ( pb = pixels[p+2])) * rbs;

    r_in_sum += pr;
    g_in_sum += pg;
    b_in_sum += pb;

    stack = stack.next;
}

stackIn = stackStart;
stackOut = stackEnd;
for ( x = 0; x &amp;lt; width; x++ )
{
    pixels[yi]   = (r_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    pixels[yi+1] = (g_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    pixels[yi+2] = (b_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;

    r_sum -= r_out_sum;
    g_sum -= g_out_sum;
    b_sum -= b_out_sum;

    r_out_sum -= stackIn.r;
    g_out_sum -= stackIn.g;
    b_out_sum -= stackIn.b;

    p =  ( yw + ( ( p = x + radius + 1 ) &amp;lt; widthMinus1 ? p : widthMinus1 ) ) &amp;lt;&amp;lt; 2;

    r_in_sum += ( stackIn.r = pixels[p]);
    g_in_sum += ( stackIn.g = pixels[p+1]);
    b_in_sum += ( stackIn.b = pixels[p+2]);

    r_sum += r_in_sum;
    g_sum += g_in_sum;
    b_sum += b_in_sum;

    stackIn = stackIn.next;

    r_out_sum += ( pr = stackOut.r );
    g_out_sum += ( pg = stackOut.g );
    b_out_sum += ( pb = stackOut.b );

    r_in_sum -= pr;
    g_in_sum -= pg;
    b_in_sum -= pb;

    stackOut = stackOut.next;

    yi += 4;
}
yw += width;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( x = 0; x &amp;lt; width; x++ )
{&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0;

yi = x &amp;lt;&amp;lt; 2;
r_out_sum = radiusPlus1 * ( pr = pixels[yi]);
g_out_sum = radiusPlus1 * ( pg = pixels[yi+1]);
b_out_sum = radiusPlus1 * ( pb = pixels[yi+2]);

r_sum += sumFactor * pr;
g_sum += sumFactor * pg;
b_sum += sumFactor * pb;

stack = stackStart;

for( i = 0; i &amp;lt; radiusPlus1; i++ )
{
    stack.r = pr;
    stack.g = pg;
    stack.b = pb;
    stack = stack.next;
}

yp = width;

for( i = 1; i &amp;lt;= radius; i++ )
{
    yi = ( yp + x ) &amp;lt;&amp;lt; 2;

    r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i );
    g_sum += ( stack.g = ( pg = pixels[yi+1])) * rbs;
    b_sum += ( stack.b = ( pb = pixels[yi+2])) * rbs;

    r_in_sum += pr;
    g_in_sum += pg;
    b_in_sum += pb;

    stack = stack.next;

    if( i &amp;lt; heightMinus1 )
    {
        yp += width;
    }
}

yi = x;
stackIn = stackStart;
stackOut = stackEnd;
for ( y = 0; y &amp;lt; height; y++ )
{
    p = yi &amp;lt;&amp;lt; 2;
    pixels[p]   = (r_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    pixels[p+1] = (g_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;
    pixels[p+2] = (b_sum * mul_sum) &amp;gt;&amp;gt; shg_sum;

    r_sum -= r_out_sum;
    g_sum -= g_out_sum;
    b_sum -= b_out_sum;

    r_out_sum -= stackIn.r;
    g_out_sum -= stackIn.g;
    b_out_sum -= stackIn.b;

    p = ( x + (( ( p = y + radiusPlus1) &amp;lt; heightMinus1 ? p : heightMinus1 ) * width )) &amp;lt;&amp;lt; 2;

    r_sum += ( r_in_sum += ( stackIn.r = pixels[p]));
    g_sum += ( g_in_sum += ( stackIn.g = pixels[p+1]));
    b_sum += ( b_in_sum += ( stackIn.b = pixels[p+2]));

    stackIn = stackIn.next;

    r_out_sum += ( pr = stackOut.r );
    g_out_sum += ( pg = stackOut.g );
    b_out_sum += ( pb = stackOut.b );

    r_in_sum -= pr;
    g_in_sum -= pg;
    b_in_sum -= pb;

    stackOut = stackOut.next;

    yi += width;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;context.putImageData( imageData, top_x, top_y );&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;}
function BlurStack()
{
this.r = 0;
this.g = 0;
this.b = 0;
this.a = 0;
this.next = null;
}
&lt;/script&gt;&lt;/p&gt;</description>
		<pubDate>Tue, 01 Oct 2013 19:55:00 +0200</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Cards Against Humanity</title> 
		<link>https://whiteshoulders.fr/index.php?article161/cards-against-humanity</link>
		<guid>https://whiteshoulders.fr/index.php?article161/cards-against-humanity</guid>
		<description>&lt;p&gt;Dans la catégorie &quot;useless, but fun&quot;, je vous présente &lt;a href=&quot;http://cardsagainsthumanity.com/&quot;&gt;Cards Against Humanity&lt;/a&gt;, javascript édition : un petit programme javascript pour jouer tout seul à un jeu qui n&#039;est amusant qu&#039;a plusieurs. Oui, c&#039;est inutile.&lt;/p&gt;&lt;style&gt;
@font-face {
    font-family: &#039;swanseabold&#039;;
    src: url(&#039;/data/documents/CAH.js/swanse_b-webfont.eot&#039;);
    src: url(&#039;/data/documents/CAH.js/swanse_b-webfont.eot?#iefix&#039;) format(&#039;embedded-opentype&#039;),
         url(&#039;/data/documents/CAH.js/swanse_b-webfont.woff&#039;) format(&#039;woff&#039;),
         url(&#039;/data/documents/CAH.js/swanse_b-webfont.ttf&#039;) format(&#039;truetype&#039;),
         url(&#039;/data/documents/CAH.js/swanse_b-webfont.svg#swanseabold&#039;) format(&#039;svg&#039;);
    font-weight: normal;
    font-style: normal;

}
#game p{margin:0; padding:0; text-align:left}
#game{
	font-size: 16px;
	font-family : swanseabold, sans-serif;	
}
.cards{
	box-shadow: 0em 0em 0.5em #000;
	border-radius: 0.5em;
	width : 8em;
	height: 12em;
	padding:1em;
	margin:0.5em;
	position:relative;
}
.question{
	background-color: #2d2c2e;
	color:#FFF;
	float:left;
}
#hand {
	clear:both;
}
#board{
	float:left;
	height:auto;
}
#pos{
	float:left;
}
#board:after{
  content: &quot;&quot;; 
  display: table;
  clear: both;
}
#selected{
	animation-name: selected;
	animation-duration: 1.5s;
	animation-iteration-count: infinite;
}

@keyframes selected {
	0%{	box-shadow: 0em 0em 0.5em 0em #000;}
	50%{ box-shadow: 0em 0em 1.5em 0em #000;}
	100%{ box-shadow: 0em 0em 0.5em 0em #000;}
}

#prePos{
	animation-name: clignote;
	animation-duration: 1.5s;
	animation-iteration-count:infinite;	
}

#valid{
	float:left;
	position:absolute;
	background-color: rgba(153, 153, 153, 0.5);
	z-index:10;
	width:12em;
	height:5em;
	margin:5em;
	box-shadow: 0em 0em 5em 5em rgba(153, 153, 153, 0.5);
	border-radius: 0.5em;
	opacity : 0;
	display:none;
	animation-name: clignote;
	animation-duration: 1.5s;
	animation-iteration-count:infinite;
}

@keyframes clignote {
	0%{opacity : 0;}
	50%{opacity: 0.1}
	100%{opacity : 0;}
}

#valid:hover{
	transition-property:opacity;
	transition-duration:0.5s;
	opacity: 1;
	animation-name: none;
}

#valid p{
	background-color:#FFF;
	box-shadow: 0em 0em 1em #000;
	margin:1.5em 3em;
	display:block;
	height:2em;
	width:6em;
	line-height: 2em;
	text-align:center;
	border-radius: 0.5em;
}
#hand .answer{
	background-color: #FFF;
	float:left;
	margin:0.5em 0.5em 0.5em -8em;
	transition-property:margin;
	transition-duration:0.5s;
}
#board .answer{
	background-color: #FFF;
	float:left;
}
#hand .answer:first-child{
	margin-left:0.5em;
}
#hand .answer:hover + .answer{
	margin-left: 0.5em;
}
.logo{
	float:left;
}
p.content{
	font-size:0.8em;
}
#game .cards p.foot{
	position:absolute;
	margin-left:-1em;
	bottom: 1em;
	font-size:0.5em;
	line-height: 32px;
}
#game .cards p.foot:before{
	content:&quot;&quot;;
	display:inline-block;
	background : url(&quot;/data/documents/CAH.js/logo.svg&quot;);
	width:32px;
	height:32px;
	position:relative;
	top:12px;
}
#game .cards p.draw{
	text-transform:uppercase;
	position:absolute;
	margin-left:-1em;
	bottom: 1em;
	right:1em;
	text-align: right;
	font-size:0.7em;
}
#game .cards p.pick{
	text-transform:uppercase;
	position:absolute;
	margin-left:-1em;
	bottom: 3em;
	right:1em;
	text-align: right;
	font-size:0.7em;
}

.num{
	display:inline-block;
	width:1.4em;
	height:1.4em;
	border-radius: 0.7em;
	background-color:#FFF;
	color:#2d2c2e;
	line-height: 1.4em;
	text-align: center;
	margin-left:0.3em;
}
&lt;/style&gt;
&lt;p&gt;Le jeu n&#039;est pas fourni du tout, juste quelques question et quelques réponse. C’était plus pour le fun qu&#039;autre chose. Le code source de la chose et disponible &lt;a href=&quot;https://whiteshoulders.fr/data/documents/CAH.js/CAH.js&quot;&gt;ici&lt;/a&gt;&lt;/p&gt; 
	&lt;div id=&quot;game&quot;&gt;
		&lt;div id=&quot;board&quot;&gt;
		&lt;div id=&quot;valid&quot;&gt;
			&lt;p&gt;Valider&lt;/p&gt;
		&lt;/div&gt;
		&lt;/div&gt;
		&lt;div id=&quot;pos&quot;&gt;
		&lt;/div&gt;
		&lt;div id=&quot;hand&quot;&gt;
		&lt;/div&gt;
	&lt;/div&gt;&lt;br style=&quot;clear:both&quot;/&gt;
&lt;script src = &quot;/data/documents/CAH.js/CAH.js&quot;&gt;&lt;/script&gt;</description>
		<pubDate>Wed, 07 Aug 2013 21:10:00 +0200</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Ruperth</title> 
		<link>https://whiteshoulders.fr/index.php?article160/ruperth</link>
		<guid>https://whiteshoulders.fr/index.php?article160/ruperth</guid>
		<description>&lt;img src=&quot;http://whiteshoulders.fr/data/images/autres/ruperth.tb.png&quot;  alt=&quot;image&quot;/&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/autres/ruperth.png&quot; alt=&quot;image&quot; /&gt;</description>
		<pubDate>Wed, 26 Jun 2013 21:20:00 +0200</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Rpg.js v0.1</title> 
		<link>https://whiteshoulders.fr/index.php?article159/rpg-js-v0-1</link>
		<guid>https://whiteshoulders.fr/index.php?article159/rpg-js-v0-1</guid>
		<description>&lt;p&gt;Après &lt;a href=&quot;http://whiteshoulders.fr/index.php?article157/atoll-c-est-fini&quot;&gt;Atoll&lt;/a&gt;, j&#039;ai eu envie de faire d&#039;autres petit jeu. Comme j&#039;avais envie d&#039;apprendre le javascript, j&#039;ai pensé aux jeux HTML5. Et je me suis mis en tête de faire le mien.&lt;/p&gt;
&lt;p&gt;C&#039;est donc la fleur au fusil que j&#039;ai choisi de faire un mini RPG&lt;/p&gt;&lt;p&gt;Pour l&#039;instant, c&#039;est vraiment quelque chose de mini-mini. A peine un prototype. Les déplacements du personnage sont là, selon 8 directions.&lt;/p&gt;
&lt;style&gt;
    #assets{
      display:none;
    }
    #canvasBloc{
      height:512px;
      width:512px;
    }
    #canvasBloc canvas{
      float:left;
      position:absolute;
    }
    #fpscount{
      display: block;
      width: 440px;
      text-align: right;
      position:relative;
      top:480px;
      font-weight:bold;
    }
#canvasContener{
width:512px;
margin:25px auto;
}
&lt;/style&gt;
&lt;div id=&quot;assets&quot;&gt;
  &lt;img id=&quot;tileset&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/sprite/tileset.png&quot;&gt;
  &lt;img id=&quot;charset&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/sprite/charset.png&quot;&gt;
  &lt;code&gt;&lt;pre id=&quot;blockMap&quot;&gt;
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  &lt;/pre&gt;&lt;/code&gt;
  &lt;code&gt;&lt;pre id=&quot;worldMap&quot;&gt;
[{&quot;map_1A&quot;:[[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,24,4,4,4,4,4],[4,4,4,4,4,4,4,25,4,4,4,4,4,4,4,24,4,4,4,4],[4,4,4,4,4,4,4,44,4,4,4,4,4,4,4,44,24,24,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,44,24,4,4,4],[24,44,4,4,4,4,4,4,4,4,4,4,4,64,65,64,25,25,4,4],[25,45,64,4,4,4,4,4,4,4,4,64,64,65,64,45,45,25,4,4],[4,45,44,64,4,4,4,4,4,4,65,64,65,45,64,44,25,4,4,4],[4,24,45,45,64,65,64,64,65,64,65,64,45,45,45,45,24,4,4,4],[4,4,25,44,45,64,45,64,45,64,64,45,45,24,4,25,4,4,4,4],[4,4,24,24,25,45,45,45,44,45,24,25,24,4,4,4,4,4,4,4],[4,4,4,4,4,24,25,24,25,24,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4]],&quot;map_1B&quot;:[[0,0,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,43,0,0,42,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,262,0,0],[0,0,24,24,63,0,0,0,0,24,42,0,0,0,24,24,24,262,0,0],[0,24,44,44,24,24,139,0,0,62,24,24,24,24,44,44,44,24,0,0],[24,44,76,77,44,24,24,162,24,24,44,44,24,65,74,75,44,24,0,0],[0,24,96,97,52,44,24,182,24,44,65,51,86,87,94,95,44,24,0,0],[0,0,116,117,72,73,64,44,65,65,70,71,106,107,114,115,24,262,0,0],[0,0,0,137,92,93,86,87,88,89,90,91,126,127,134,0,0,262,0,0],[0,0,0,157,112,113,106,107,108,109,110,111,146,147,154,0,0,262,0,0],[0,0,0,0,132,133,126,127,128,129,130,131,0,105,0,0,0,262,0,0],[0,0,23,0,0,153,146,147,148,149,150,105,105,0,0,0,0,262,0,0],[0,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,62,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,62,62,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,62,0,262,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0]],&quot;map_2A&quot;:[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,78,79,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,98,101,102,103,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,120,121,122,123,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,141,142,143,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],&quot;map_2B&quot;:[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],&quot;map_event&quot;:[[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:2,&quot;up&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0,&quot;down&quot;:5},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}],[{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0},{&quot;type&quot;:0}]],&quot;borderTransition&quot;:{&quot;up&quot;:0,&quot;down&quot;:0,&quot;left&quot;:0,&quot;right&quot;:0}}]
  &lt;/pre&gt;&lt;/code&gt;
&lt;/div&gt;
&lt;div id=&quot;canvasContener&quot;&gt;
  &lt;div id=&quot;canvasBloc&quot;&gt;
    &lt;canvas id=&quot;canvasMap_Lvl1&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;canvasPlayer_Lvl1&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;canvasMap_Lvl2&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;canvasPlayer_Lvl2&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;
    &lt;p id=&quot;fpscount&quot;&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;p&gt;&lt;/div&gt;&lt;/p&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/transplan.js&quot;&gt; &lt;/script&gt; 
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/tileset.js&quot;&gt; &lt;/script&gt; 
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/map.js&quot;&gt; &lt;/script&gt; 
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/player.js&quot;&gt; &lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/eventhandler.js&quot;&gt; &lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/blockMapEditor.js&quot;&gt; &lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/layerEditor.js&quot;&gt; &lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://whiteshoulders.fr/data/documents/rpg.js_v0.1/lib/main.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;De manière générale pour les déplacements, je me suis inspiré de &quot;Zelda: A Link To The Past&quot;, avec un déplacement libre entre les &quot;cases&quot;, et en utilisant le &lt;a href=&quot;http://home.comcast.net/~jpittman2/pacman/pacmandossier.html#CH2_Cornering&quot;&gt;cornering&lt;/a&gt; lors des collisions. On obtient ainsi un mouvement assez fluide, malgré quelques bugs (arriver en diagonale sur un obstacle lui aussi en diagonale, comme une partie de la falaise)&lt;/p&gt;
&lt;p&gt;Une gestion de la &quot;profondeur&quot; est également présente (personnage devant/derrière l&#039;arbre), en utilisant plusieurs calques pour dessiner la map. A terme, il sera également possible de mettre en place des ponts, donc des zone où l&#039;on passera au dessus du tile ou en dessous, selon notre déplacement.&lt;/p&gt;
&lt;p&gt;Pour ce jeu, j&#039;ai aussi bossé sur le scrolling dans la map et sur les transitions au bord de la map. Ici, la transition se fait entre la map et elle même, parce que je n&#039;ai fait qu&#039;une seule map pour le moment.&lt;/p&gt;
&lt;p&gt;J&#039;ai aussi commencé à mettre en place une gestion de certains événements, qui va s&#039;étoffer à terme, avec la possibilité de sauter, depuis le haut de la falaise.&lt;/p&gt;
&lt;p&gt;Pour l&#039;occasion, et vu que c&#039;est un projet qui va avoir plus d&#039;ampleur que tout ce que j&#039;ai pu produire jusqu’à maintenant, j&#039;ai commencé à utiliser &lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt;. Je ne saurais pas encore dire si c&#039;est gadget vu que je développe tout seul, l&#039;avenir me le dira.&lt;/p&gt;</description>
		<pubDate>Sat, 25 May 2013 22:25:00 +0200</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>The War</title> 
		<link>https://whiteshoulders.fr/index.php?article158/the-war</link>
		<guid>https://whiteshoulders.fr/index.php?article158/the-war</guid>
		<description>&lt;img src=&quot;http://whiteshoulders.fr/data/images/noir/thewar.tb.png&quot;  alt=&quot;image&quot;/&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/noir/thewar.png&quot; alt=&quot;image&quot;/&gt;</description>
		<pubDate>Mon, 25 Mar 2013 21:54:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Atoll - C&#039;est fini</title> 
		<link>https://whiteshoulders.fr/index.php?article157/atoll-c-est-fini</link>
		<guid>https://whiteshoulders.fr/index.php?article157/atoll-c-est-fini</guid>
		<description>&lt;p&gt;Ayé, Atoll est fini. J&#039;ai passé ma soutenance, le projet est achevé. J&#039;ai essayé d&#039;en faire un truc jouable avec une interface propre, quitte à ce que le jeu soit moins étoffé que prévu. J&#039;aurais au moins inclus ma &lt;a href=&quot;http://whiteshoulders.fr/index.php?article151/atoll-generation-aleatoire&quot;&gt;génération de map aléatoire&lt;/a&gt;, et ça, ça me tenais vraiment à cœur.&lt;/p&gt;&lt;p&gt;J&#039;aurais bien aimé ajouter bien des choses. J&#039;aurais bien aimé essayer de généraliser le jeu pour plus de deux joueurs. Il aurait fallut modifier un peu les règles, agrandir la map, et pourquoi pas ajouter des bonus (comme la possibilité de convertir un pont adverse), mais pourquoi pas ?&lt;/p&gt;
&lt;p&gt;J&#039;aurais bien aimé programmer une IA pour jouer contre l&#039;ordinateur aussi. Ça aurait été faisable sans que ça soit trop compliqué conceptuellement, mais ça aurait pris du temps. Et de la motivation. Phase descendante, tout ça ...&lt;/p&gt;
&lt;p&gt;Par contre la musique qu&#039;on ne peut pas couper, c&#039;est normal, c&#039;est prévu, c&#039;est juste mon coté sadique. Amusez-vous bien.&lt;/p&gt;
&lt;p style=&quot;text-align:center;  margin:32px;&quot;&gt;&lt;a href=&quot;http://whiteshoulders.fr/data/documents/atoll.zip&quot; style=&quot;padding:10px;&quot;&gt;Télécharger Atoll.zip [7.84 Mo]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;L&#039;archive contient un .exe, qui peut rendre votre antivirus nerveux, mais croix-de-bois-croix-de-fer, si y&#039;a un virus, j&#039;vais en enfer. Il faut juste lancer le-dit .exe, et pouf, profitez.&lt;br /&gt;
Si vous tombez sur des bugs, ou des trucs louches, des erreurs, des problèmes, des gaffes, des bévues, des boulettes, ou n&#039;importe quoi d&#039;autres, faites m&#039;en part.&lt;/p&gt;</description>
		<pubDate>Tue, 05 Mar 2013 01:05:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Atoll - Quelques nouvelles</title> 
		<link>https://whiteshoulders.fr/index.php?article156/atoll-quelques-nouvelles</link>
		<guid>https://whiteshoulders.fr/index.php?article156/atoll-quelques-nouvelles</guid>
		<description>&lt;p&gt;Mon petit projet de jeu avance plutôt bien. Le cœur du jeu est terminé, avec toutes les règles du jeu, les bonus, etc ... &lt;br /&gt;
Maintenant je travaille sur l&#039;interface. Comme on pouvait s&#039;y attendre en voyant les &lt;a href=&quot;https://whiteshoulders.fr/index.php?article151/atoll-generation-aleatoire&quot; &gt;map générées aléatoirement&lt;/a&gt;, ça ne sera que du gros pixel, pour mon plus grand plaisir.&lt;/p&gt;&lt;img style=&quot;margin:24px 30px;&quot; src =&quot;http://whiteshoulders.fr/data/images/screenshot.png&quot;&gt;&lt;/p&gt;

&lt;p&gt; Pour le moment la carte n&#039;est pas dynamique, c&#039;est juste une image sur laquelle je dessine les ponts. Mais à terme, pourquoi ne pas faire &quot;bouger&quot; la mer, avec un bruit dynamique ?&lt;/p&gt;</description>
		<pubDate>Wed, 13 Feb 2013 00:21:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Si tôt</title> 
		<link>https://whiteshoulders.fr/index.php?article155/si-tot</link>
		<guid>https://whiteshoulders.fr/index.php?article155/si-tot</guid>
		<description>&lt;audio preload=&quot;none&quot;&gt;
  &lt;source data-base=&quot;/source/goodmorninglemings/sitot/&quot; src=&quot;https://whiteshoulders.fr/source/goodmorninglemings/sitot/sitot.mp3&quot; type=&quot;audio/mp3&quot; /&gt;
&lt;/audio&gt;
&lt;div class=&quot;buttons&quot;&gt;
&lt;a class=&quot;download&quot; href=&quot;https://whiteshoulders.fr/source/goodmorninglemings/sitot/sitot.mp3&quot;&gt;[mp3]&lt;/a&gt;
&lt;/div&gt;</description>
		<pubDate>Wed, 06 Feb 2013 16:30:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Atoll - Generation aléatoire</title> 
		<link>https://whiteshoulders.fr/index.php?article151/atoll-generation-aleatoire</link>
		<guid>https://whiteshoulders.fr/index.php?article151/atoll-generation-aleatoire</guid>
		<description>&lt;p&gt;
Atoll, c&#039;est un petit projet de jeu en C++, inspiré d&#039;un jeu de plateau : &lt;a href=&quot;http://fr.wikipedia.org/wiki/Kahuna_(jeu)&quot;&gt;Kahuna&lt;/a&gt;. L&#039;idée était de proposer un jeu simple, jouable rapidement, et sur lequel je puisse développer un IA assez simple.
&lt;/p&gt;
&lt;p&gt;
Comme dans kahuna, le plateau de jeu est un archipel d&#039;iles, entre lesquelles chaque joueurs peut construire un pont. En construisant plus de la moitié des ponts d&#039;une ile, les joueurs deviennent propriétaires des iles, le but du jeu étant de posséder le plus d&#039;ile possible.
&lt;/p&gt;&lt;p&gt;
Là ou le jeu devient stratégique, c&#039;est que lorsqu&#039;un joueur prend la propriété d&#039;une ile, il détruit tout les ponts de son adversaire partant de cette ile. De cette manière, il peut faire perdre la propriété des iles voisine à son adversaire. A ceci s&#039;ajoute la possibilité de placer des bombes sur certains ponts, ou de piéger les liens non construit entre les iles. Ces bonus seront gagnés aléatoirement lors de la prise d&#039;une ile.
&lt;/p&gt;
&lt;p&gt;
Dans ce projet, ce qui me tenais vraiment à cœur, c&#039;était la génération aléatoire d&#039;une carte de jeu. La carte étant un graphe, où les iles sont des nœuds et les liens des arêtes, il faut se plonger un chouilla dans la théorie.
&lt;/p&gt;
&lt;h3&gt;Théorie des graphes&lt;/h3&gt;
&lt;p&gt;
La carte de jeu doit présenter environ une dizaine de nœuds, et ils doivent être reliés aléatoirement a d&#039;autres nœuds, de manière à ne pas croiser d&#039;autres arêtes. En théorie des graphe, on dit que ce graphe est &lt;a href=&quot;http://fr.wikipedia.org/wiki/Graphe_planaire&quot;&gt;planaire&lt;/a&gt;. Donc il faut que je soit capable de générer un graphe planaire.
&lt;/p&gt;
&lt;p&gt;
Mais il faut aussi que les ils ne soit pas trop proche d&#039;autres iles, ou d&#039;autres liens (un lien doit passer dans la mer, pas au dessus d&#039;une ile). Ce qu&#039;il faut réaliser, c&#039;est une &lt;a href=&quot;http://fr.wikipedia.org/wiki/Triangulation_de_Delaunay&quot;&gt;triangulation de Delaunay&lt;/a&gt;. On relie les iles de manière à réaliser un maillage ou les triangles sont les moins plats possible. De cette manière, les noeuds sont les plus éloignés possible des arêtes.
&lt;/p&gt;
&lt;p&gt;
Sachant que le nombre de noeud restera petit, il est possible d&#039;implémenter un algorithme simple, sans se soucier de son efficacité : &lt;a href=&quot;http://fr.wikipedia.org/wiki/Triangulation_de_Delaunay#Incr.C3.A9mentation&quot;&gt;la méthode incrémentale&lt;/a&gt;. On obtient alors de jolies triangulations.
&lt;/p&gt;
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/triangulation.png&quot;/&gt;&lt;/p&gt;
&lt;h3&gt;Dessiner les iles&lt;/h3&gt;
&lt;p&gt;Pour dessiner les iles, il faut ruser un peu. On pourrait dessiner un cercle autour de chaque point, mais il ne faut pas que les iles se superposent. Donc il faut que le rayon soit plus petit que la moitié du plus petit lien. Mais on aura des iles toutes de la même taille, ce qui n&#039;est pas très esthétique.&lt;/p&gt;
&lt;p&gt;
La solution retenue est la suivante. Pour chaque point à l&#039;intérieur d&#039;un triangle, on cherche le sommet dont il est le plus proche, et on traduit ses coordonnées en coordonnées barycentriques par rapport à ce sommet. Puis, en fonction de ces valeurs, je colorie le pixel en bleu si il est éloigné du sommet, ou en jaune si il est proche. J&#039;aurais ainsi autour des iles des portions de cercles plus ou moins grand selon la taille du triangle dans lequel il se trouve.
&lt;/p&gt;
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/archipel-v0.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Pour colorier l&#039;extérieur du graphe, il a fallu ajouter des points en dehors de l&#039;image, pour que les triangles couvrent toute l&#039;image.&lt;/p&gt;
&lt;p&gt;Maintenant, je peux ajouter un peu de bruit, pour déformer le contour de mes iles. Le &lt;a href=&quot;http://fr.wikipedia.org/wiki/Bruit_de_valeur&quot;&gt;bruit de valeur&lt;/a&gt; est le candidat idéal. Je multiplie la valeur de la distance en coordonnées barycentrique trouvée précédemment pour un pixel par la valeur du bruit en ce pixel. On obtient un visuel beaucoup plus réaliste.
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/archipel.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Il reste quelques artefacts, comme ces grandes lignes droite dans la mer, mais la carte est satisfaisante.&lt;/p&gt;
&lt;p&gt;La carte se génère en moins d&#039;une seconde, ce qui est suffisamment rapide. On pourrait tout optimiser, mais ce n&#039;est pas le but recherché pour le moment&lt;/p&gt;</description>
		<pubDate>Sat, 02 Feb 2013 00:50:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>Atoll</title> 
		<link>https://whiteshoulders.fr/index.php?article152/atoll</link>
		<guid>https://whiteshoulders.fr/index.php?article152/atoll</guid>
		<description>&lt;img src=&quot;http://whiteshoulders.fr/data/images/work/title.tb.png&quot; alt=&quot;image&quot;/&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/work/title.png&quot; alt=&quot;image&quot;/&gt;</description>
		<pubDate>Tue, 29 Jan 2013 18:20:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
	<item>
		<title>For Fist</title> 
		<link>https://whiteshoulders.fr/index.php?article148/for-fist</link>
		<guid>https://whiteshoulders.fr/index.php?article148/for-fist</guid>
		<description>&lt;img src=&quot;http://whiteshoulders.fr/data/images/sketchbook/for-fist.tb.jpg&quot;  alt=&quot;image&quot;/&gt;&lt;img src=&quot;http://whiteshoulders.fr/data/images/sketchbook/for-fist.jpg&quot; alt=&quot;image&quot; /&gt;</description>
		<pubDate>Wed, 09 Jan 2013 22:16:00 +0100</pubDate>
		<dc:creator>Whiteshoulders</dc:creator>
	</item>
</channel>
</rss>