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

483 lines
47 KiB
HTML
Raw Normal View History

2020-11-29 03:26:44 +00:00
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/img/icon.png" type="image/png">
<meta name="generator" content="Hugo 0.78.2" />
<meta property="og:title" content="ecco the dolphin" />
<meta property="og:description" content="Let&#39;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: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&#39;s recreate this weird effect from Ecco the Dolphin."/>
<title>ecco the dolphin - toasters rocks</title>
<link rel="stylesheet" href="/css/styles.css" />
<link rel="stylesheet" href="/css/syntax.css" />
<script src="https://kit.fontawesome.com/8ced65a629.js" crossorigin="anonymous"></script>
</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: #221e1b" class="fab fa-github"></i>
<span style="color: #221e1b">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) * 0.5833333333333334 - 3.5em)">
<h2 name="top">ecco the dolphin</h2>
<p>Let&#39;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>
// Ecco effect v2 by juju2143
// based on original code by foone
// https://github.com/foone/ecco-distortion-effect
// Licenced under GPL3
var shifts = "gDkZcB510pQ:3pSf]>4oLh\>41pS;nWd_@lYcB5oT;nJ82pSfCkH7nV<3oL82pN9nV<31pNh\c_?lH7nKiE6210000pOg\cB5oL82pN931pOg\>mWe^aA5110pO9nKh\bAlYdCkG7oL8nVe^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 c = createCanvas(320, 224);
c.parent('sketch-holder');
}
function draw() {
for (var i = 0; i < height; i++)
image(img, 0, i, width, 1, shifts.charCodeAt((i + frameCount) & 0xFF)-0x30, i, 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&#39;t look great here (THANKS, TWITTER)<br>but I&#39;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" charset="utf-8"></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 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 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 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 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 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 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 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 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 class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre 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 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 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 d = document, s = d.createElement('script'); s.async = true;
s.src = '//' + "juju2143" + '.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</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</footer>
</body>
</html>