toasters.rocks/ecco-the-dolphin/index.html

332 lines
43 KiB
HTML
Raw Normal View History

<!doctype html><html lang=en><head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel="shortcut icon" href=/img/icon.png type=image/png>
<meta name=generator content="Hugo 0.91.2">
<meta property="og:title" content="ecco the dolphin">
<meta property="og:description" content="Let's recreate this weird effect from Ecco the Dolphin.">
<meta property="og:type" content="article">
<meta property="og:url" content="http://toasters.rocks/ecco-the-dolphin/"><meta property="og:image" content="http://toasters.rocks/images/2019/11/background.png"><meta property="article:section" content>
<meta property="article:published_time" content="2019-11-29T02:47:27+00:00">
<meta property="article:modified_time" content="2019-12-01T06:13:10+00:00">
<meta name=twitter:card content="summary_large_image">
<meta name=twitter:image content="http://toasters.rocks/images/2019/11/background.png">
<meta name=twitter:title content="ecco the dolphin">
<meta name=twitter:description content="Let's recreate this weird effect from Ecco the Dolphin.">
<meta name=theme-color content="#660066">
<title>ecco the dolphin - toasters rocks</title>
<link rel=stylesheet href=http://toasters.rocks/css/toastersrocks.min.css>
</head><body>
<header><img src=/img/icon.png><h1>toasters rocks</h1></header>
<main>
<aside><nav>
<a href=/>
<i class="fas fa-home"></i>
Home
</a><br>
<a href=http://juju2143.ca/>
<i class="fas fa-user"></i>
About
</a><br>
<a href=/fr/>
<i class="fas fa-globe"></i>
Français
</a><br>
<a href=https://yukiis.moe/>
<i class="far fa-comment"></i>
Comics
</a><br>
<a href=https://codewalr.us/>
<i class="far fa-folder-open"></i>
Forums
</a><br>
</nav>
<br>
<nav>
<a title="Twitter " href=https://twitter.com/juju2143>
<i style=color:#4da7de class="fab fa-twitter"></i>
<span style=color:#4da7de>Twitter</span>
</a><br>
<a title="Discord " href=https://discord.gg/cuZcfcF>
<i style=color:#7289da class="fab fa-discord"></i>
<span style=color:#7289da>Discord</span>
</a><br>
<a title="GitHub " href=https://github.com/juju2143>
<i style=color:#fafafa class="fab fa-github"></i>
<span style=color:#fafafa>GitHub</span>
</a><br>
<a title="Patreon " href=https://patreon.com/juju2143>
<i style=color:#f96854 class="fab fa-patreon"></i>
<span style=color:#f96854>Patreon</span>
</a><br>
<a title="YouTube " href=https://youtube.com/user/julosoft>
<i style=color:#e02a20 class="fab fa-youtube"></i>
<span style=color:#e02a20>YouTube</span>
</a><br>
<a title="YouTube 2 " href=https://youtube.com/c/juju2143>
<i style=color:#e02a20 class="fab fa-youtube"></i>
<span style=color:#e02a20>YouTube 2</span>
</a><br>
<a title="Twitch " href=https://twitch.tv/juju2143>
<i style=color:#6441a5 class="fab fa-twitch"></i>
<span style=color:#6441a5>Twitch</span>
</a><br>
<a title="Instagram " href=https://instagram.com/j.p.savard>
<i style=color:#d6249f class="fab fa-instagram"></i>
<span style=color:#d6249f>Instagram</span>
</a><br>
<a title="DeviantArt " href=https://deviantart.com/juju2143>
<i style=color:#c5d200 class="fab fa-deviantart"></i>
<span style=color:#c5d200>DeviantArt</span>
</a><br>
<a title="SoundCloud " href=https://soundcloud.com/juju2143>
<i style=color:#fe3801 class="fab fa-soundcloud"></i>
<span style=color:#fe3801>SoundCloud</span>
</a><br>
</nav></aside>
<article style=background-image:url(/images/2019/11/background.png)>
<div class=metadata style="height:calc((var(--height) - 2em) * .5833333333333334 - 3.5em)">
<h2 name=top>ecco the dolphin</h2>
<p>Let's recreate this weird effect from Ecco the Dolphin.</p>
<i class="far fa-calendar-alt"></i>
<time datetime=2019-11-29>November 29, 2019</time><br>
<i class="fas fa-tags"></i>
#<a class="btn btn-sm btn-outline-dark tag-btn" href=http://toasters.rocks/tags/experiments>Experiments</a>
#<a class="btn btn-sm btn-outline-dark tag-btn" href=http://toasters.rocks/tags/p5.js>p5.js</a>
<br>
<i class="fas fa-hourglass"></i> ~6 minutes
</div>
<script src=https://unpkg.com/p5@^0.10/lib/p5.min.js></script>
<script>var shifts="gDkZcB510pQ:3pSf]>4oLh>41pS;nWd_@lYcB5oT;nJ82pSfCkH7nV<3oL82pN9nV<31pNhc_?lH7nKiE6210000pOgcB5oL82pN931pOg>mWe^aA5110pO9nKhAlYdCkG7oL8nVe^a`@5oL82pSf>lXd^?lX=3oM9nV<31pNhEjF6oL8nJiEjF6oU;310pQ:3pSfC6oU;mW=41pN9nK8nJ8nV;nV<310000pPgD6oUe]>4oL9nVe^a`@";function preload(){img=loadImage('/images/2019/11/background.png')}function setup(){var a=createCanvas(320,224);a.parent('sketch-holder')}function draw(){for(var a=0;a<height;a++)image(img,0,a,width,1,shifts.charCodeAt(a+frameCount&255)-48,a,width,1)}</script>
<p> </p>
<div id=sketch-holder></div>
<p>Welcome to the second installment of my code experiments! This time we&rsquo;re gonna look into the weird effect used in the background of messages in Ecco the Dolphin for the Sega Genesis (or MegaDrive, if you&rsquo;re asking someone outside the Americas). I got the idea from Twitter user @Foone who helpfully reverse engineered the game ROM (with Twitter user @Reaper_man02) to figure out how it works and wrote an implementation in Python. Then I went ahead and adapted it in p5.js.</p>
<p><blockquote class=twitter-tweet><p lang=en dir=ltr>it won't look great here (THANKS, TWITTER)<br>but I've finished reverse engineering the Ecco the Dolphin background distortion effect.<br>This is the output of the script provided here:<a href=https://t.co/oPUb3tJJAC>https://t.co/oPUb3tJJAC</a> <a href=https://t.co/UQtW4ZyTKu>pic.twitter.com/UQtW4ZyTKu</a></p>&mdash; foone (@Foone) <a href="https://twitter.com/Foone/status/1199590443538796549?ref_src=twsrc%5Etfw">November 27, 2019</a></blockquote>
<script async src=https://platform.twitter.com/widgets.js></script>
Read the replies for some explanations.</p>
<p>Turns out it&rsquo;s pretty simple: there&rsquo;s a table in ROM, it&rsquo;s basically how much each line should be shifted in the x axis. Then for each frame we shift the values around so it looks like it&rsquo;s scrolling.</p>
<p><img src=/images/2019/11/background.png alt>
Base image.</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt> 1
</span><span class=lnt> 2
</span><span class=lnt> 3
</span><span class=lnt> 4
</span><span class=lnt> 5
</span><span class=lnt> 6
</span><span class=lnt> 7
</span><span class=lnt> 8
</span><span class=lnt> 9
</span><span class=lnt>10
</span><span class=lnt>11
</span><span class=lnt>12
</span><span class=lnt>13
</span><span class=lnt>14
</span><span class=lnt>15
</span><span class=lnt>16
</span><span class=lnt>17
</span><span class=lnt>18
</span><span class=lnt>19
</span><span class=lnt>20
</span><span class=lnt>21
</span><span class=lnt>22
</span><span class=lnt>23
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=kd>function</span> <span class=nx>generate_for_offsets</span><span class=p>(</span><span class=nx>offset</span><span class=p>)</span> <span class=p>{</span>
<span class=kd>var</span> <span class=nx>SCREEN_SHIFTS</span> <span class=o>=</span> <span class=p>[</span>
<span class=mi>55</span><span class=p>,</span> <span class=mi>20</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>42</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>33</span><span class=p>,</span> <span class=mi>10</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>45</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span>
<span class=mi>28</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>52</span><span class=p>,</span> <span class=mi>47</span><span class=p>,</span> <span class=mi>16</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>41</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span>
<span class=mi>63</span><span class=p>,</span> <span class=mi>36</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>24</span><span class=p>,</span> <span class=mi>7</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span>
<span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>47</span><span class=p>,</span> <span class=mi>15</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>24</span><span class=p>,</span>
<span class=mi>7</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span> <span class=mi>57</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span>
<span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>61</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>17</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span>
<span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>50</span><span class=p>,</span> <span class=mi>17</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>41</span><span class=p>,</span> <span class=mi>52</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>23</span><span class=p>,</span> <span class=mi>7</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span>
<span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>48</span><span class=p>,</span> <span class=mi>16</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>40</span><span class=p>,</span>
<span class=mi>52</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>15</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>40</span><span class=p>,</span> <span class=mi>13</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>29</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>58</span><span class=p>,</span>
<span class=mi>22</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>57</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>58</span><span class=p>,</span> <span class=mi>22</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>33</span><span class=p>,</span>
<span class=mi>10</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>61</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>13</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span>
<span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>32</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>20</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span>
<span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>45</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>48</span><span class=p>,</span> <span class=mi>16</span>
<span class=p>]</span>
<span class=kd>var</span> <span class=nx>output_shifts</span> <span class=o>=</span> <span class=p>[];</span>
<span class=k>for</span> <span class=p>(</span><span class=kd>var</span> <span class=nx>current_line</span> <span class=o>=</span> <span class=mi>0</span><span class=p>;</span> <span class=nx>current_line</span> <span class=o>&lt;</span> <span class=nx>height</span><span class=p>;</span> <span class=nx>current_line</span><span class=o>++</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>output_shifts</span><span class=p>[</span><span class=nx>current_line</span><span class=p>]</span> <span class=o>=</span> <span class=nx>SCREEN_SHIFTS</span><span class=p>[(</span><span class=nx>current_line</span> <span class=o>+</span> <span class=nx>offset</span><span class=p>)</span> <span class=o>&amp;</span> <span class=mh>0xFF</span><span class=p>];</span>
<span class=p>}</span>
<span class=k>return</span> <span class=nx>output_shifts</span><span class=p>;</span>
<span class=p>}</span>
</code></pre></td></tr></table>
</div>
</div><p>p5.js code for the above canvas, part 1</p>
<p>This function basically computes a table of offsets for the current frame by adding the line number with the frame number, mod 256. Then a bit of initialization code:</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt>1
</span><span class=lnt>2
</span><span class=lnt>3
</span><span class=lnt>4
</span><span class=lnt>5
</span><span class=lnt>6
</span><span class=lnt>7
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=kd>function</span> <span class=nx>preload</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>img</span> <span class=o>=</span> <span class=nx>loadImage</span><span class=p>(</span><span class=s1>&#39;https://toasters.rocks/images/2019/11/background.png&#39;</span><span class=p>);</span>
<span class=p>}</span>
<span class=kd>function</span> <span class=nx>setup</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>createCanvas</span><span class=p>(</span><span class=mi>320</span><span class=p>,</span> <span class=mi>224</span><span class=p>);</span>
<span class=p>}</span>
</code></pre></td></tr></table>
</div>
</div><p>p5.js code for the above canvas, part 2</p>
<p>And now this is where it gets interesting. For each line we call the <code>image</code> function which crops a 320x1 portion of the image with the appropriate x offset we calculated earlier. Note that the original image is 384x224.</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt>1
</span><span class=lnt>2
</span><span class=lnt>3
</span><span class=lnt>4
</span><span class=lnt>5
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=kd>function</span> <span class=nx>draw</span><span class=p>()</span> <span class=p>{</span>
<span class=kd>var</span> <span class=nx>adjusts</span> <span class=o>=</span> <span class=nx>generate_for_offsets</span><span class=p>(</span><span class=nx>frameCount</span><span class=p>);</span>
<span class=k>for</span> <span class=p>(</span><span class=kd>var</span> <span class=nx>i</span> <span class=o>=</span> <span class=mi>0</span><span class=p>;</span> <span class=nx>i</span> <span class=o>&lt;</span> <span class=nx>height</span><span class=p>;</span> <span class=nx>i</span><span class=o>++</span><span class=p>)</span>
<span class=nx>image</span><span class=p>(</span><span class=nx>img</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=nx>adjusts</span><span class=p>[</span><span class=nx>i</span><span class=p>],</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>);</span>
<span class=p>}</span>
</code></pre></td></tr></table>
</div>
</div><p>p5.js code for the above canvas, part 3</p>
<p>We can also completely forego the <code>generate_for_offsets</code> function and make it simpler:</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt> 1
</span><span class=lnt> 2
</span><span class=lnt> 3
</span><span class=lnt> 4
</span><span class=lnt> 5
</span><span class=lnt> 6
</span><span class=lnt> 7
</span><span class=lnt> 8
</span><span class=lnt> 9
</span><span class=lnt>10
</span><span class=lnt>11
</span><span class=lnt>12
</span><span class=lnt>13
</span><span class=lnt>14
</span><span class=lnt>15
</span><span class=lnt>16
</span><span class=lnt>17
</span><span class=lnt>18
</span><span class=lnt>19
</span><span class=lnt>20
</span><span class=lnt>21
</span><span class=lnt>22
</span><span class=lnt>23
</span><span class=lnt>24
</span><span class=lnt>25
</span><span class=lnt>26
</span><span class=lnt>27
</span><span class=lnt>28
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=kd>var</span> <span class=nx>shifts</span> <span class=o>=</span> <span class=p>[</span>
<span class=mi>55</span><span class=p>,</span> <span class=mi>20</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>42</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>33</span><span class=p>,</span> <span class=mi>10</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>45</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span>
<span class=mi>28</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>52</span><span class=p>,</span> <span class=mi>47</span><span class=p>,</span> <span class=mi>16</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>41</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span>
<span class=mi>63</span><span class=p>,</span> <span class=mi>36</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>24</span><span class=p>,</span> <span class=mi>7</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span>
<span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>47</span><span class=p>,</span> <span class=mi>15</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>24</span><span class=p>,</span>
<span class=mi>7</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span> <span class=mi>57</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>51</span><span class=p>,</span> <span class=mi>18</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span>
<span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>61</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>17</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span>
<span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>31</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>50</span><span class=p>,</span> <span class=mi>17</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>41</span><span class=p>,</span> <span class=mi>52</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>59</span><span class=p>,</span> <span class=mi>23</span><span class=p>,</span> <span class=mi>7</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span>
<span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>48</span><span class=p>,</span> <span class=mi>16</span><span class=p>,</span> <span class=mi>5</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>44</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>40</span><span class=p>,</span>
<span class=mi>52</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>15</span><span class=p>,</span> <span class=mi>60</span><span class=p>,</span> <span class=mi>40</span><span class=p>,</span> <span class=mi>13</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>29</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>56</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>58</span><span class=p>,</span>
<span class=mi>22</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>57</span><span class=p>,</span> <span class=mi>21</span><span class=p>,</span> <span class=mi>58</span><span class=p>,</span> <span class=mi>22</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>33</span><span class=p>,</span>
<span class=mi>10</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>35</span><span class=p>,</span> <span class=mi>54</span><span class=p>,</span> <span class=mi>19</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>61</span><span class=p>,</span> <span class=mi>39</span><span class=p>,</span> <span class=mi>13</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>30</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>27</span><span class=p>,</span>
<span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>26</span><span class=p>,</span> <span class=mi>8</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>11</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>12</span><span class=p>,</span> <span class=mi>3</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>64</span><span class=p>,</span> <span class=mi>32</span><span class=p>,</span> <span class=mi>55</span><span class=p>,</span> <span class=mi>20</span><span class=p>,</span> <span class=mi>6</span><span class=p>,</span>
<span class=mi>63</span><span class=p>,</span> <span class=mi>37</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>45</span><span class=p>,</span> <span class=mi>14</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>63</span><span class=p>,</span> <span class=mi>28</span><span class=p>,</span> <span class=mi>9</span><span class=p>,</span> <span class=mi>62</span><span class=p>,</span> <span class=mi>38</span><span class=p>,</span> <span class=mi>53</span><span class=p>,</span> <span class=mi>46</span><span class=p>,</span> <span class=mi>49</span><span class=p>,</span> <span class=mi>48</span><span class=p>,</span> <span class=mi>16</span>
<span class=p>]</span>
<span class=kd>function</span> <span class=nx>preload</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>img</span> <span class=o>=</span> <span class=nx>loadImage</span><span class=p>(</span><span class=s1>&#39;https://toasters.rocks/images/2019/11/background.png&#39;</span><span class=p>);</span>
<span class=p>}</span>
<span class=kd>function</span> <span class=nx>setup</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>createCanvas</span><span class=p>(</span><span class=mi>320</span><span class=p>,</span> <span class=mi>224</span><span class=p>);</span>
<span class=p>}</span>
<span class=kd>function</span> <span class=nx>draw</span><span class=p>()</span> <span class=p>{</span>
<span class=k>for</span> <span class=p>(</span><span class=kd>var</span> <span class=nx>i</span> <span class=o>=</span> <span class=mi>0</span><span class=p>;</span> <span class=nx>i</span> <span class=o>&lt;</span> <span class=nx>height</span><span class=p>;</span> <span class=nx>i</span><span class=o>++</span><span class=p>)</span>
<span class=nx>image</span><span class=p>(</span><span class=nx>img</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=nx>shifts</span><span class=p>[(</span><span class=nx>i</span> <span class=o>+</span> <span class=nx>frameCount</span><span class=p>)</span> <span class=o>&amp;</span> <span class=mh>0xFF</span><span class=p>],</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>);</span>
<span class=p>}</span>
</code></pre></td></tr></table>
</div>
</div><p>p5.js code for the above canvas, version 2</p>
<p>Now that huge array is a bit unwieldy, maybe you can compress it? Sure thing.</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt>1
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=nb>String</span><span class=p>.</span><span class=nx>fromCharCode</span><span class=p>(...</span><span class=nx>shifts</span><span class=p>.</span><span class=nx>map</span><span class=p>(</span><span class=nx>x</span> <span class=p>=&gt;</span> <span class=nx>x</span> <span class=o>+</span> <span class=mh>0x30</span><span class=p>)));</span>
</code></pre></td></tr></table>
</div>
</div><p>Let&rsquo;s transform that stupid array into something better</p>
<div class=highlight><div class=chroma>
<table class=lntable><tr><td class=lntd>
<pre tabindex=0 class=chroma><code><span class=lnt> 1
</span><span class=lnt> 2
</span><span class=lnt> 3
</span><span class=lnt> 4
</span><span class=lnt> 5
</span><span class=lnt> 6
</span><span class=lnt> 7
</span><span class=lnt> 8
</span><span class=lnt> 9
</span><span class=lnt>10
</span><span class=lnt>11
</span><span class=lnt>12
</span><span class=lnt>13
</span><span class=lnt>14
</span></code></pre></td>
<td class=lntd>
<pre tabindex=0 class=chroma><code class=language-js data-lang=js><span class=kd>var</span> <span class=nx>shifts</span> <span class=o>=</span> <span class=s2>&#34;gDkZcB510pQ:3pSf]&gt;4oLh\&gt;41pS;nWd_@lYcB5oT;nJ82pSfCkH7nV&lt;3oL82pN9nV&lt;31pNh\c_?lH7nKiE6210000pOg\cB5oL82pN931pOg\&gt;mWe^aA5110pO9nKh\bAlYdCkG7oL8nVe^a`@5oL82pSf\&gt;lXd^?lX=3oM9nV&lt;31pNhEjF6oL8nJiEjF6oU;310pQ:3pSfC6oU;mW=41pN9nK8nJ8nV;nV&lt;310000pPgD6oUe]&gt;4oL9nVe^a`@&#34;</span><span class=p>;</span>
<span class=kd>function</span> <span class=nx>preload</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>img</span> <span class=o>=</span> <span class=nx>loadImage</span><span class=p>(</span><span class=s1>&#39;https://toasters.rocks/images/2019/11/background.png&#39;</span><span class=p>);</span>
<span class=p>}</span>
<span class=kd>function</span> <span class=nx>setup</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>createCanvas</span><span class=p>(</span><span class=mi>320</span><span class=p>,</span> <span class=mi>224</span><span class=p>);</span>
<span class=p>}</span>
<span class=kd>function</span> <span class=nx>draw</span><span class=p>()</span> <span class=p>{</span>
   <span class=k>for</span> <span class=p>(</span><span class=kd>var</span> <span class=nx>i</span> <span class=o>=</span> <span class=mi>0</span><span class=p>;</span> <span class=nx>i</span> <span class=o>&lt;</span> <span class=nx>height</span><span class=p>;</span> <span class=nx>i</span><span class=o>++</span><span class=p>)</span>
       <span class=nx>image</span><span class=p>(</span><span class=nx>img</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=nx>shifts</span><span class=p>.</span><span class=nx>charCodeAt</span><span class=p>((</span><span class=nx>i</span> <span class=o>+</span> <span class=nx>frameCount</span><span class=p>)</span> <span class=o>&amp;</span> <span class=mh>0xFF</span><span class=p>)</span><span class=o>-</span><span class=mh>0x30</span><span class=p>,</span> <span class=nx>i</span><span class=p>,</span> <span class=nx>width</span><span class=p>,</span> <span class=mi>1</span><span class=p>);</span>
<span class=p>}</span>
</code></pre></td></tr></table>
</div>
</div><p>p5.js code for the above canvas, version 3</p>
<p>From there, there&rsquo;s a lot of tricks to compress your code so it goes a bit faster. With that much code, we went from something that looks complex into something simple, which is pretty cool. Well, that&rsquo;s all for today, hope you learned a bit with that :)</p>
<p>All content owned by their respective owners: game, data and assets by <a href=https://en.wikipedia.org/wiki/Appaloosa_Interactive>Novotrade International</a>, code by Foone and adapted by myself licenced under GPL3.</p>
</article>
<ul class=pagination>
<li class=page-item>
<a class=previous href=http://toasters.rocks/commissions/>« commissions</a>
</li>
<li class=page-item>
<a class=next href=http://toasters.rocks/horse-life-98/>Horse Life 98 »</a>
</li>
</ul>
<article>
<div id=disqus_thread></div>
<script type=application/javascript>var disqus_config=function(){};(function(){if(["localhost","127.0.0.1"].indexOf(window.location.hostname)!=-1){document.getElementById('disqus_thread').innerHTML='Disqus comments not available by default when the website is previewed locally.';return}var b=document,a=b.createElement('script');a.async=!0,a.src='//juju2143.disqus.com/embed.js',a.setAttribute('data-timestamp',+new Date),(b.head||b.body).appendChild(a)})()</script>
<noscript>Please enable JavaScript to view the <a href=https://disqus.com/?ref_noscript>comments powered by Disqus.</a></noscript>
<a href=https://disqus.com class=dsq-brlink>comments powered by <span class=logo-disqus>Disqus</span></a>
</article>
</main>
<footer>Copyright © 2020 J.P. Savard - Theme by <a href=https://github.com/juju2143/hugo-theme-toastersrocks>J. P. Savard</a> - Powered by Hugo 0.91.2</footer>
</body>
</html>