<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Proof of concept &#8211; INCD021</title>
	<atom:link href="https://incd021.com/category/proof-of-concept/feed/" rel="self" type="application/rss+xml" />
	<link>https://incd021.com</link>
	<description>Programming, thoughts, life  and art.</description>
	<lastBuildDate>Tue, 01 Apr 2025 18:40:30 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>
	<item>
		<title>Implementing simple L-System in Kotlin</title>
		<link>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/</link>
					<comments>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 27 Oct 2024 17:58:44 +0000</pubDate>
				<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[L-System]]></category>
		<guid isPermaLink="false">https://incd021.com/?p=773</guid>

					<description><![CDATA[Intro L-systems were introduced and developed by Aristid Lindenmayer back in 1968 and are often used to produce fractals or images of flowers, as the repeating nature of some flowers....]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Intro</h3>



<p>L-systems were introduced and developed by Aristid Lindenmayer back in 1968 and are often used to produce fractals or images of flowers, as the repeating nature of some flowers is very easy to reproduce using L-systems. L-systems consist of four parts: <strong>variables</strong>, <strong>constants</strong>, <strong>Axiom</strong>, and <strong>rules</strong>. The rules describe how the axiom, or start expression, evolves from iteration to iteration.</p>



<h3 class="wp-block-heading">Let’s look at a classical example:</h3>



<ul class="wp-block-list">
<li>Variables: <strong>L</strong></li>



<li>Constants: <strong>+</strong>, <strong>−</strong></li>



<li>Axiom: <strong>L</strong></li>



<li>Rules: <strong>L =&gt; L-L++L-L</strong></li>
</ul>



<p>How the different symbols are interpreted is entirely up to us, but in this example, we define:</p>



<ul class="wp-block-list">
<li><strong>L</strong> to mean &#8220;draw line forward&#8221;</li>



<li><strong>+</strong> to mean &#8220;turn left&#8221;</li>



<li><strong>−</strong> to mean &#8220;turn right&#8221;</li>
</ul>



<p>So the algorithm is a simple search and replace. We go through the axiom or start string L and replace it according to the rule, resulting in the following strings:</p>



<ul class="wp-block-list">
<li><em>Iteration 1</em>: L =&gt; <strong>L-L++L-L </strong></li>



<li><em>Iteration 2</em>: L-L++L-L =&gt; <strong>L-L++L-L-L-L++L-L++L-L++L-L-L-L++L-L </strong></li>



<li><em>Iteration 3</em>: L-L++L-L-L-L++L-L++L-L++L-L-L-L++L-L =&gt; <strong>L-L++L-L-L-L++L-L++L-L++L-L-L-L …</strong></li>
</ul>



<p>and we can keep going for as many iterations as we like, but as we can already see, the resulting string grows very raptly because of the “long” rule for <strong>L</strong>. If the rule for <strong>L</strong> was simpler, the resulting string of cause wouldn’t grow as fast.<br></p>



<p>Repeatedly applying the rules increases structure and complexity.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://incd021.com/wp-content/uploads/2024/09/L-System-Iterations-1.png" alt="L-System Iterations" class="wp-image-164"/><figcaption class="wp-element-caption">Basic L-System iterations</figcaption></figure>



<p>But enough theory; If you want more information, you can read an in-depth explanation of <a href="https://en.wikipedia.org/wiki/L-system">L-systems on Wikipedia</a>.</p>



<h2 class="wp-block-heading">Implementing the L-system.</h2>



<p>We’ll be use strings for variables, constants, and axiom, a <strong>StringBuilder</strong> for building up the result, and a simple <strong>Map&lt;string, string&gt;</strong> for the rule(s), defining the string to search for and what to replace it with.</p>



<p>First we define the <strong>RuleSet</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="@Serializable
data class RuleSet(val rules: Map&lt;String, String&gt;, val axiom: String)" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #97E1F1; font-style: italic">@Serializable</span></span>
<span class="line"><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">RuleSet</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> rules: </span><span style="color: #97E1F1; font-style: italic">Map</span><span style="color: #F6F6F4">&lt;</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">&gt;, </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> axiom: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<p>As simple as can be, simple data class containing the axiom and the Map containing the rules.<br>We need the annotation @Serializable as we will be reading the rules from a JSON file.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">JSON</span><span role="button" tabindex="0" data-code="{
  &quot;rules&quot;: {
    &quot;L&quot;: &quot;L-L++L-L&quot;
  },
  &quot;axiom&quot;: &quot;L&quot;
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">rules</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">L</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">L-L++L-L</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">  },</span></span>
<span class="line"><span style="color: #F6F6F4">  </span><span style="color: #97E2F2">&quot;</span><span style="color: #97E1F1">axiom</span><span style="color: #97E2F2">&quot;</span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">L</span><span style="color: #DEE492">&quot;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>This is the simple rule for creating the image displayed above.</p>



<p>The simple constructor for the <strong>LSystem</strong> class is only taking a <strong>RuleSet</strong> as parameter:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="class LSystem(private val ruleSet: RuleSet)" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">LSystem</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> ruleSet: </span><span style="color: #97E1F1; font-style: italic">RuleSet</span><span style="color: #F6F6F4">)</span></span></code></pre></div>



<p><br>The <strong>generate</strong> function takes in the number of iterations to run and calls the <strong>generateExpression</strong> that number of time. It also times how long each generation takes in nanoseconds.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="fun generate(iterations: Int) {
    expression.append(ruleSet.axiom)
    
    var startTime: Long
    var endTime: Long
    
    for (i in 0 until iterations) {
        startTime = System.nanoTime()
        expression = generateExpression(expression)
    
        endTime = System.nanoTime()
        println(&quot;Time to generate iteration ${i + 1}${endTime-startTime}ns - With a size of ${expression.length}&quot;)
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generate</span><span style="color: #F6F6F4">(iterations: </span><span style="color: #97E1F1; font-style: italic">Int</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(ruleSet.axiom)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> startTime: </span><span style="color: #97E1F1; font-style: italic">Long</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> endTime: </span><span style="color: #97E1F1; font-style: italic">Long</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (i </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span><span style="color: #F6F6F4"> until iterations) {</span></span>
<span class="line"><span style="color: #F6F6F4">        startTime </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> System.</span><span style="color: #62E884">nanoTime</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">        expression </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generateExpression</span><span style="color: #F6F6F4">(expression)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        endTime </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> System.</span><span style="color: #62E884">nanoTime</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #E7EE98">&quot;Time to generate iteration </span><span style="color: #F286C4">${</span><span style="color: #E7EE98">i </span><span style="color: #F286C4">+</span><span style="color: #E7EE98"> </span><span style="color: #BF9EEE">1</span><span style="color: #F286C4">}${</span><span style="color: #E7EE98">endTime</span><span style="color: #F286C4">-</span><span style="color: #E7EE98">startTime</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">ns - With a size of </span><span style="color: #F286C4">${</span><span style="color: #E7EE98">expression.length</span><span style="color: #F286C4">}</span><span style="color: #E7EE98">&quot;</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><br>The <strong>generateExpression</strong> function is the heart of the L-System. It goes through the current expression character by character and tries to match up the rules with the upcoming characters using the <strong>matchesPattern</strong> helper function. When a match is found, the resulting string from the rule is appended to the new expression. If no match is found, the current character is appended to the new expression. This approach avoids the need for rules that don&#8217;t replace anything, such as <strong>&#8220;-&#8221; =&gt; &#8220;-&#8220;</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="private fun generateExpression(expression: StringBuilder) : StringBuilder {
    val newExpression = StringBuilder()
    
    var position = 0
    while (position &lt; expression.length) {
        var matched = false
    
        // Check each pattern in order
        for (pattern in ruleSet.rules) {
            if (position + pattern.key.length &lt;= expression.length &amp;&amp; // check we are not matching outside the expression
                matchesPattern(this.expression, position, pattern.key)
            ) {
                matched = true
                position += pattern.key.length // Move the position forward after matching
                newExpression.append(ruleSet.rules[pattern.key])
                break
            }
        }
    
        if (!matched) {
            newExpression.append(expression[position])
            position++ // Move to the next position if no pattern matched
        }
    }
    
    return newExpression
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">generateExpression</span><span style="color: #F6F6F4">(expression: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">) : </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> newExpression </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">StringBuilder</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> position </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">while</span><span style="color: #F6F6F4"> (position </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> expression.length) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> matched </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// Check each pattern in order</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (pattern </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> ruleSet.rules) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (position </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> pattern.key.length </span><span style="color: #F286C4">&lt;=</span><span style="color: #F6F6F4"> expression.length </span><span style="color: #F286C4">&amp;&amp;</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// check we are not matching outside the expression</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #62E884">matchesPattern</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.expression, position, pattern.key)</span></span>
<span class="line"><span style="color: #F6F6F4">            ) {</span></span>
<span class="line"><span style="color: #F6F6F4">                matched </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span></span>
<span class="line"><span style="color: #F6F6F4">                position </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> pattern.key.length </span><span style="color: #7B7F8B">// Move the position forward after matching</span></span>
<span class="line"><span style="color: #F6F6F4">                newExpression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(ruleSet.rules[pattern.key])</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">break</span></span>
<span class="line"><span style="color: #F6F6F4">            }</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">!</span><span style="color: #F6F6F4">matched) {</span></span>
<span class="line"><span style="color: #F6F6F4">            newExpression.</span><span style="color: #62E884">append</span><span style="color: #F6F6F4">(expression[position])</span></span>
<span class="line"><span style="color: #F6F6F4">            position</span><span style="color: #F286C4">++</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Move to the next position if no pattern matched</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> newExpression</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><br>The helper function <strong>matchesPattern</strong> goes through the characters in the pattern and tries to match them with the next characters in the input <strong>StringBuilder</strong>. This is a greedy approach, so the order of the rules matters. For instance, if we have the two rules <strong>&#8220;-&#8221; =&gt; &#8220;L&#8221;</strong> and <strong>&#8220;&#8211;&#8221; =&gt; &#8220;L&#8221;</strong> in that order, the second rule will never be applied because the first rule always matches first. Therefore, place the longer rules first.</p>



<p>We could pre-sort the rules, but for this introduction, we just have to keep the order in mind.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="  private fun matchesPattern(input: StringBuilder, position: Int, pattern: String): Boolean {
    for (index in pattern.indices) {
        if (input[position + index] != pattern[index]) {
            return false // Return false if any character doesn't match
        }
    }
    
    return true // Return true if all characters match
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">  </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">matchesPattern</span><span style="color: #F6F6F4">(input: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">, position: </span><span style="color: #97E1F1; font-style: italic">Int</span><span style="color: #F6F6F4">, pattern: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">): </span><span style="color: #97E1F1; font-style: italic">Boolean</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (index </span><span style="color: #F286C4">in</span><span style="color: #F6F6F4"> pattern.indices) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (input[position </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> index] </span><span style="color: #F286C4">!=</span><span style="color: #F6F6F4"> pattern[index]) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Return false if any character doesn&#39;t match</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4"> </span><span style="color: #7B7F8B">// Return true if all characters match</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<h2 class="wp-block-heading"><br>Implementing the Visualizer</h2>



<p>So now we have a long string of characters, but we need to interpret in some way. This is where the visualizer comes in. <br>We started by defining the variables and constants <strong>&#8211;</strong>, <strong>+</strong>, and <strong>L</strong>, so now we just have to draw from the expression.</p>



<p> The <strong>Visualizer</strong> constructor takes a few parameters:</p>



<ul class="wp-block-list">
<li><strong>expression</strong>, the expression to be interpreted</li>



<li><strong>imageSize</strong>, the size for the output image</li>



<li><strong>padding</strong>, the padding around the figure to the edge of the image, in pixels</li>



<li><strong>filename</strong>, the filename for the output file.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="class Visualizer(
    private val expression: StringBuilder,
    private val imageSize: Vector2,
    private var padding: Float,
    private var filename: String
) " style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Visualizer</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> expression: </span><span style="color: #97E1F1; font-style: italic">StringBuilder</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> imageSize: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> padding: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> filename: </span><span style="color: #97E1F1; font-style: italic">String</span></span>
<span class="line"><span style="color: #F6F6F4">) </span></span></code></pre></div>



<p>Let&#8217;s start with the rules and the drawing function <strong>doTurtleAction</strong>. But for that to make sense, we&#8217;ll also have to look at the <strong>SystemState</strong> data class.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="data class SystemState(
    var position: Vector2,
    var angle: Float,
    var length: Float,
)

fun doTurtleAction(c: Char, state: SystemState, canvas: Canvas? = null, draw : Boolean = true) {
    when (c) {
        'L' -&gt; drawLine(state, canvas, aPen, draw)
        '+' -&gt; state.angle += 45
        '-' -&gt; state.angle -= 45
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> position: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> angle: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">var</span><span style="color: #F6F6F4"> length: </span><span style="color: #97E1F1; font-style: italic">Float</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c: </span><span style="color: #97E1F1; font-style: italic">Char</span><span style="color: #F6F6F4">, state: </span><span style="color: #97E1F1; font-style: italic">SystemState</span><span style="color: #F6F6F4">, canvas: </span><span style="color: #97E1F1; font-style: italic">Canvas</span><span style="color: #F6F6F4">? </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">, draw : </span><span style="color: #97E1F1; font-style: italic">Boolean</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">when</span><span style="color: #F6F6F4"> (c) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;L&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">drawLine</span><span style="color: #F6F6F4">(state, canvas, aPen, draw)</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;+&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> state.angle </span><span style="color: #F286C4">+=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">45</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #E7EE98">&#39;-&#39;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> state.angle </span><span style="color: #F286C4">-=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">45</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>The <strong>SystemState</strong> class keeps track of the current position of the pen drawing the figure, the current angle in degrees, and the length. This can be extended to keep a stack of positions that can be pushed and popped so that when drawing, it can store a position, draw something, and return to that position. However, this isn&#8217;t implemented in this simple version.</p>



<p>In <strong>doTurtleAction</strong>, using Kotlin&#8217;s <em>when</em> function makes interpreting the character very straightforward. Here, we define what we want the different variables and constants to do. We use 45 degrees for <strong>+</strong> and <strong>&#8211;</strong> because this will create a nice Koch fractal, but you can set it to whatever you like. <strong>L</strong> draws a line based on the length and angle in <strong>state</strong>.</p>



<p>I added some extra steps in the <strong>Visualizer</strong> to help always output a nice image of the whole figure. That is, I go through the entire algorithm without drawing anything; I only log the minimum and maximum positions. This allows me to scale the lines to draw and set the starting position so the figure is centered and fills the given image size, excluding the padding.</p>



<p>Calculating the area of the figure with the line at size 1 is done using the <strong>calcArea</strong> function.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="private fun calcArea(): Rectangle {
    val state = SystemState(
        angle = 0f,
        length = 1f,
        position = Vector2(0f, 0f)
    ) hosted 
    
    expression.toString().forEach { c -&gt;
        doTurtleAction(c, state, null,false)
        updateAreaData(state)
    }
    
    val x = floor(minXPosition)
    val y = floor(minYPosition)
    val w = ceil(maxXPosition) - x
    val h = ceil(maxYPosition) - y
    return Rectangle(x.toInt(), y.toInt(), w.toInt(), h.toInt())
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">calcArea</span><span style="color: #F6F6F4">(): </span><span style="color: #97E1F1; font-style: italic">Rectangle</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> state </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">        angle </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        length </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        position </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Vector2</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    ) hosted </span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">toString</span><span style="color: #F6F6F4">().</span><span style="color: #62E884">forEach</span><span style="color: #F6F6F4"> { c </span><span style="color: #F286C4">-&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c, state, </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">,</span><span style="color: #BF9EEE">false</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">updateAreaData</span><span style="color: #F6F6F4">(state)</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> x </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">floor</span><span style="color: #F6F6F4">(minXPosition)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> y </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">floor</span><span style="color: #F6F6F4">(minYPosition)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> w </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ceil</span><span style="color: #F6F6F4">(maxXPosition) </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> x</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> h </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ceil</span><span style="color: #F6F6F4">(maxYPosition) </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> y</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Rectangle</span><span style="color: #F6F6F4">(x.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), y.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), w.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), h.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">())</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p>When outputting the image, we start by getting the area and performing some calculations to get the scale and the starting point to use.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="private fun outputAsImage(maxImageSize: Vector2, filename: String) {
    val area = calcArea()
     
    val xScale = (maxImageSize.x - padding) / area.width
    val yScale = (maxImageSize.y - padding) / area.height
    val scale = if (xScale &lt; yScale) xScale else yScale
    
    val state = SystemState(
        angle = 0f,
        length = scale,
        posi hosted tion = Vector2(minXPosition * (-scale) + (padding / 2), minYPosition * (-scale) + (padding / 2))
    )
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">fun</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">outputAsImage</span><span style="color: #F6F6F4">(maxImageSize: </span><span style="color: #97E1F1; font-style: italic">Vector2</span><span style="color: #F6F6F4">, filename: </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> area </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">calcArea</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">     </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> xScale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (maxImageSize.x </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> padding) </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> area.width</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> yScale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (maxImageSize.y </span><span style="color: #F286C4">-</span><span style="color: #F6F6F4"> padding) </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> area.height</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> scale </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (xScale </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4"> yScale) xScale </span><span style="color: #F286C4">else</span><span style="color: #F6F6F4"> yScale</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> state </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SystemState</span><span style="color: #F6F6F4">(</span></span>
<span class="line"><span style="color: #F6F6F4">        angle </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">0f</span><span style="color: #F6F6F4">,</span></span>
<span class="line"><span style="color: #F6F6F4">        length </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> scale,</span></span>
<span class="line"><span style="color: #F6F6F4">        posi hosted tion </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Vector2</span><span style="color: #F6F6F4">(minXPosition </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">scale) </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> (padding </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">), minYPosition </span><span style="color: #F286C4">*</span><span style="color: #F6F6F4"> (</span><span style="color: #F286C4">-</span><span style="color: #F6F6F4">scale) </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> (padding </span><span style="color: #F286C4">/</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">2</span><span style="color: #F6F6F4">))</span></span>
<span class="line"><span style="color: #F6F6F4">    )</span></span>
<span class="line"></span></code></pre></div>



<p>Now we setup the canvas to draw on. Here we use the Kotlin wrapper for the <a href="https://skia.org/">Skia</a> 2d graphics library called <a href="https://github.com/JetBrains/skiko">skiko</a>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="    val surface = Surface.makeRaster(ImageInfo.makeN32(maxImageSize.x.toInt(), maxImageSize.y.toInt(), ColorAlphaType.OPAQUE))
    
    // Get the canvas from the surface
    val canvas = surface.canvas
    // Clear the canvas with a white background
    canvas.clear(Color.TRANSPARENT)" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> surface </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> Surface.</span><span style="color: #62E884">makeRaster</span><span style="color: #F6F6F4">(ImageInfo.</span><span style="color: #62E884">makeN32</span><span style="color: #F6F6F4">(maxImageSize.x.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), maxImageSize.y.</span><span style="color: #62E884">toInt</span><span style="color: #F6F6F4">(), ColorAlphaType.OPAQUE))</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Get the canvas from the surface</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> canvas </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> surface.canvas</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Clear the canvas with a white background</span></span>
<span class="line"><span style="color: #F6F6F4">    canvas.</span><span style="color: #62E884">clear</span><span style="color: #F6F6F4">(Color.TRANSPARENT)</span></span></code></pre></div>



<p><em>Note</em>: The Kotlin wrapper for Skia doesn&#8217;t use the same naming for classes and functions, which makes it challenging to use the documentation for Skia. After a lot of searching, I got it working, but without a deeper understanding of why, so I&#8217;m not sure if it&#8217;s the right way of using it. But it works.</p>



<p>Now we draw the figure and output the image to a file.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Kotlin</span><span role="button" tabindex="0" data-code="    expression.toString().forEach { c -&gt; doTurtleAction(c, state, canvas) }
    
    // Get the snapshot of the surface
    val image = surface.makeImageSnapshot()
    
    // Encode the image as a PNG
    val data = image.encodeToData(EncodedImageFormat.PNG, 100)
    
    // Save the PNG to a file
    File(&quot;$filename.png&quot;).writeBytes(data!!.bytes)
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">    expression.</span><span style="color: #62E884">toString</span><span style="color: #F6F6F4">().</span><span style="color: #62E884">forEach</span><span style="color: #F6F6F4"> { c </span><span style="color: #F286C4">-&gt;</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">doTurtleAction</span><span style="color: #F6F6F4">(c, state, canvas) }</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Get the snapshot of the surface</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> image </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> surface.</span><span style="color: #62E884">makeImageSnapshot</span><span style="color: #F6F6F4">()</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Encode the image as a PNG</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">val</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">data</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> image.</span><span style="color: #62E884">encodeToData</span><span style="color: #F6F6F4">(EncodedImageFormat.PNG, </span><span style="color: #BF9EEE">100</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Save the PNG to a file</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #62E884">File</span><span style="color: #F6F6F4">(</span><span style="color: #E7EE98">&quot;</span><span style="color: #F6F6F4">$filename</span><span style="color: #E7EE98">.png&quot;</span><span style="color: #F6F6F4">).</span><span style="color: #62E884">writeBytes</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4">data!!</span><span style="color: #F6F6F4">.bytes)</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p><strong>That&#8217;s it!</strong><br>I&#8217;ve added the full project code here, for <a href="http://192.168.2.128/wp-content/uploads/2024/09/L-System-Kotlin.zip">free download</a>.</p>



<h3 class="wp-block-heading">Thoughts:</h3>



<p>However, nothing says we must use repetitive rules; we can do whatever we want. We could alternate between differenthosted rules, shift rules when a specific pattern is seen, reverse parts based on other triggers, or use any approach that could yield an interesting result. I like to add randomness to the constants, so instead of turning exactly 90 degrees, we turn 90 degrees plus or minus some small random value to introduce variation. Create different weighted rules, allowing multiple rules for the same pattern with different probabilities! &#8220;Barney Codes&#8221; has already implemented this, as seen in <a href="https://www.youtube.com/watch?v=TOPxa1xIG5Q">YouTube video</a>.</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-incd-021 wp-block-embed-incd-021"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="KUvuAtgB9J"><a href="https://incd021.com/disclaimer/">Disclaimer!</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Disclaimer!&#8221; &#8212; INCD021" src="https://incd021.com/disclaimer/embed/#?secret=PIIRGl3WlH#?secret=KUvuAtgB9J" data-secret="KUvuAtgB9J" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2024/10/27/implementing-simple-l-system-in-kotlin/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Late update, POC&#8217;s and current work</title>
		<link>https://incd021.com/2014/07/01/late-update-pocs-current-work/</link>
					<comments>https://incd021.com/2014/07/01/late-update-pocs-current-work/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Tue, 01 Jul 2014 19:13:37 +0000</pubDate>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=562</guid>

					<description><![CDATA[As every blog I have ever read, from time to time there happens a lot in the bloggers life, and updates test pushed into the back of the tasks list.....]]></description>
										<content:encoded><![CDATA[<p>As every blog I have ever read, from time to time there happens a lot in the bloggers life, and updates test pushed into the back of the tasks list. Life!</p>
<p>Since the last blog post, I have published my small racing game <a href="https://play.google.com/store/apps/details?id=com.incd021.strazer">Strazer </a>to Google Play store. <a href="https://incd021.com/wp-content/uploads/2014/07/Strazer.png"><img fetchpriority="high" decoding="async" class="aligncenter size-medium wp-image-566" src="https://incd021.com/wp-content/uploads/2014/07/Strazer-300x187.png" alt="Strazer" width="300" height="187" /></a></p>
<p>After updating the graphics, I&#8217;m pretty happy with it. It wasn&#8217;t meant to be a AAA game <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>After that I worked for a few weeks on a game about depression, but there was a bug in Unity (OnTriggerEnter2D) that kept giving me problems, so I put it on hold. The bug was fixed in the Unity 4.5 release, so maybe I&#8217;ll go back to that again&#8230; Later.</p>
<p><a href="https://incd021.com/wp-content/uploads/2014/07/D.png"><img decoding="async" class="aligncenter size-medium wp-image-571" src="https://incd021.com/wp-content/uploads/2014/07/D-300x168.png" alt="D" width="300" height="168" /></a></p>
<p>And the there are a lot of small POC as always <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>Save &#8217;em all:</strong></p>
<p><a href="https://incd021.com/wp-content/uploads/2014/07/SaveEmAll.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-567" src="https://incd021.com/wp-content/uploads/2014/07/SaveEmAll-300x168.png" alt="SaveEmAll" width="300" height="168" /></a></p>
<p><strong>GauntletX:</strong></p>
<p><a href="https://incd021.com/wp-content/uploads/2014/07/GauntletX.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-568" src="https://incd021.com/wp-content/uploads/2014/07/GauntletX-300x168.png" alt="GauntletX" width="300" height="168" /></a></p>
<p><strong>Forever: </strong><a href="https://incd021.com/wp-content/uploads/2014/07/Forever.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-569" src="https://incd021.com/wp-content/uploads/2014/07/Forever-300x168.png" alt="Forever" width="300" height="168" /></a></p>
<p><strong>DefendYourself:</strong><a href="https://incd021.com/wp-content/uploads/2014/07/DefendYourself.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-570" src="https://incd021.com/wp-content/uploads/2014/07/DefendYourself-300x168.png" alt="DefendYourself" width="300" height="168" /></a></p>
<p><strong>Defend4x8:<a href="https://incd021.com/wp-content/uploads/2014/07/Defend4x8.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-576" src="https://incd021.com/wp-content/uploads/2014/07/Defend4x8-300x175.png" alt="Defend4x8" width="300" height="175" /></a></strong></p>
<p>All small POC that I might go back and work on in the future.</p>
<p>At the moment I&#8217;m working on a game for two friends, one want me to make a zombie game, and the other a platformer, so it is going to be a zombie platformer game <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><a href="https://incd021.com/wp-content/uploads/2014/07/TheZombiePlatformer.png"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-572" src="https://incd021.com/wp-content/uploads/2014/07/TheZombiePlatformer-300x187.png" alt="TheZombiePlatformer" width="300" height="187" /></a></p>
<p>Right now I trying to get some graphics done for the game, it&#8217;s coming along but not as fast as I would like, and not as good either. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://incd021.com/wp-content/uploads/2014/07/ZombieMeele.gif"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-565" src="https://incd021.com/wp-content/uploads/2014/07/ZombieMeele.gif" alt="ZombieMeele" width="64" height="64" /></a></p>
<p>This is the melee attack of the zombie. It still is missing shadows and highlights.</p>
<p>So have done a lot, just haven&#8217;t blogged about it. I&#8217;ve started using twitter a lot more, I like the positive atmosphere and the nice people always there to help.</p>
<p>Have a great day, now go make games! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&#8211; Henning</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/07/01/late-update-pocs-current-work/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>First experience with Spriter</title>
		<link>https://incd021.com/2014/02/19/first-experience-spriter/</link>
					<comments>https://incd021.com/2014/02/19/first-experience-spriter/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Wed, 19 Feb 2014 16:29:12 +0000</pubDate>
				<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Spriter]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=507</guid>

					<description><![CDATA[So I want to try to make my crab animation using Spriter so, first I cut out all the different parts from my Inkscape image. I did leave out all....]]></description>
										<content:encoded><![CDATA[<p>So I want to try to make my crab animation using Spriter so, first I cut out all the different parts from my Inkscape image. I did leave out all but one leg, as I should be able to scale and rotate in Spriter to make all the legs, from one set of leg sprites <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> So here are the cutouts.</p>
<p><figure id="attachment_508" aria-describedby="caption-attachment-508" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2014/02/CrabCutouts.png"><img loading="lazy" decoding="async" class="size-medium wp-image-508" alt="Crab Cutouts" src="https://incd021.com/wp-content/uploads/2014/02/CrabCutouts-300x242.png" width="300" height="242" /></a><figcaption id="caption-attachment-508" class="wp-caption-text">Crab Cutouts</figcaption></figure></p>
<p>I saved them all in a sub-directory in the directory I&#8217;m going to use for the Spriter project. Spriter looks to be using the same project directory structure as Unity.</p>
<p>I have now assembled the crab within Spriter. I know Spriter is a work in progress, but some simple features I found missing was, copy of multiple objects within the scene. I have 3 left legs, that looks a lot like the 3 right legs. Would have loved to be able to just copy them all in one go, and mirror them. Probably just me not know how. And moving objects in the Z-order windows was a drag, no pun, intended, but it wasn&#8217;t possible to select all the leg parts and drag them all at once, and as I had to drag them all all the way to the bottom, it was not optimal. It should be possible to hold ctrl+up/down to move them up and down in the list, but it didn&#8217;t work (found out, it does work, the window just isn&#8217;t updating). Well it was still easy to set up my crab.</p>
<p><figure id="attachment_512" aria-describedby="caption-attachment-512" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2014/02/CrabInSpriter.png"><img loading="lazy" decoding="async" class="size-medium wp-image-512" alt="Crab in Spriter" src="https://incd021.com/wp-content/uploads/2014/02/CrabInSpriter-300x204.png" width="300" height="204" /></a><figcaption id="caption-attachment-512" class="wp-caption-text">Crab in Spriter</figcaption></figure></p>
<p>Looks almost like the original. Almost.. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But again, this is just a cold run, to show how easy Spriter is to learn and use.</p>
<p>To add the skeleton I did have to look at a tutorial, not that it&#8217;s hard to do, I just couldn&#8217;t find out how to add a single bone.. Found out, you have to hold down the Alt key, after watching the video.. How should I know <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>I followed this video:</p>
<p><iframe loading="lazy" title="Spriter features and workflow overview" width="768" height="576" src="https://www.youtube.com/embed/Y5PBw4aCVNQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<p>Once again they have made everything SO easy. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But did had a few problems. This time it was selecting the small legs when assigning the sprites to the bones, but I did find out that I could assign sprites to bones in the Hierarchy window. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Maybe I have used too small sprites or there are some setup somewhere I don&#8217;t know of, but it worked and now I can animate&#8230; Don&#8217;t expect to much <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><figure id="attachment_520" aria-describedby="caption-attachment-520" style="width: 284px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2014/02/crab.gif"><img loading="lazy" decoding="async" class="size-full wp-image-520" alt="Animated Crab" src="https://incd021.com/wp-content/uploads/2014/02/crab.gif" width="284" height="163" /></a><figcaption id="caption-attachment-520" class="wp-caption-text">Animated Crab</figcaption></figure></p>
<p><span style="line-height: 1.5;">And that&#8217;s it <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> An animated crab in a bit over an hour <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I already know where to use it.</span></p>
<p><strong>Conclusion:</strong></p>
<p>There where a few glitches throughout the Spriter experience, but nothing compared with the frustration of trying to work with Synfig. When exporting the animation to PNG&#8217;s some of the images had the previous frames in the background. Something that I&#8217;m sure will be fixed in future versions.</p>
<p>That was my first experience with Spriter, and I still like it a lot! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> It&#8217;s so easy to use. There are a lot of things that could be done better and small bugs, but $25 i cheap for a tool so powerful.</p>
<p>Features I would like to have include curves in the animation/key frame window, being able to drag multiple objects in the z-ordering windows, spritesheet output and that&#8217;s about it.</p>
<p><a href="https://brashmonkey.dpdcart.com/cart/add?product_id=59676&amp;method_id=60817">Go buy Spriter</a>, NOW! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> And then, go make games <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&#8211; Henning</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/02/19/first-experience-spriter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;Left&#8221;, a new mini game and what I learned</title>
		<link>https://incd021.com/2014/01/28/left-new-mini-game-learned/</link>
					<comments>https://incd021.com/2014/01/28/left-new-mini-game-learned/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Tue, 28 Jan 2014 11:06:10 +0000</pubDate>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[OUYA]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=486</guid>

					<description><![CDATA[So I&#8217;ve use a few weeks making this small puzzle idea into a working mini-game. It popped into my mind over the Christmas holiday. I thought that it would be....]]></description>
										<content:encoded><![CDATA[<p><figure id="attachment_495" aria-describedby="caption-attachment-495" style="width: 94px" class="wp-caption alignright"><a href="https://incd021.com/Games/Left/Left.html"><img loading="lazy" decoding="async" class="size-full wp-image-495 " title="Left Icon" alt="Play &quot;Left&quot;" src="https://incd021.com/wp-content/uploads/2014/01/Left-Icon.png" width="94" height="94" /></a><figcaption id="caption-attachment-495" class="wp-caption-text">Play &#8220;Left&#8221;</figcaption></figure></p>
<p>So I&#8217;ve use a few weeks making this small puzzle idea into a working mini-game. It popped into my mind over the Christmas holiday. I thought that it would be a fun little game, and I was sure that I would learn a thing or two. So here is what I did, and learned <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>The basic idea:</strong><br />
A top-down game where you have to build a bridge to save some small cute creatures. But as always the idea changed over time and turned into something else.</p>
<p>The different planks used to build the bridge would be rotating and changing length at different speeds and amount. I figured that 5 different planks would be a fine.</p>
<p><strong>Getting started:</strong><br />
So I started out by looking at the plank dynamics, I wanted to add planks at the end of the previous plank and in the same angle. But first, ONE, plank <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Keep it simple, right?</p>
<p style="text-align: center;"><a style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 11px;" href="https://incd021.com/wp-content/uploads/2014/01/FirstScene.jpg"><img loading="lazy" decoding="async" class="size-medium wp-image-488 aligncenter" alt="First run of Left" src="https://incd021.com/wp-content/uploads/2014/01/FirstScene-300x225.jpg" width="300" height="225" /></a><span style="font-size: 11px; line-height: 17px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">First run of Left</span></p>
<p>Ok, that worked <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> So now, adding more planks.</p>
<p><strong>Getting planks to align, and stay there:</strong></p>
<p>Getting the planks to appear at the end of the previous plank wasn&#8217;t  a problem, except for one out of about 10 planks, so it was very hard to debug. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><figure id="attachment_492" aria-describedby="caption-attachment-492" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2014/01/PlankMissplaced.png"><img loading="lazy" decoding="async" class="size-medium wp-image-492" alt="Misplaced Planks" src="https://incd021.com/wp-content/uploads/2014/01/PlankMissplaced-300x300.png" width="300" height="300" /></a><figcaption id="caption-attachment-492" class="wp-caption-text">Misplaced Planks</figcaption></figure></p>
<p>But after recording a video of the game, I could see the planks was placed at the correct position, but was then pushed in the first frame.. Ah, the physics engine! Problem identified <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />
All the planks have a collider and a rigid body to be able to collide with the walls, the goal and to be able to be use the it for the death sequence, where all the planks fall to the ground. So I couldn&#8217;t just remove the rigid body from the planks.</p>
<p><strong>The solution:</strong></p>
<p>I simply chose to lock the position and rotation every frame. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Well, simple but wasn&#8217;t easy to implement because of the way I had implemented the plank control, but it worked. And then every thing was locked into the right place <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>What did I learn:</strong></p>
<ul>
<li>2d and 3d physics engine doesn&#8217;t act the same. <a href="http://docs.unity3d.com/Documentation/Components/class-MeshCollider.html">Colliding rules are different</a>, follow link and see section &#8220;Collision action matrix&#8221; which works for 3d, but (and now I can&#8217;t remember the other link, sorry) this isn&#8217;t true for 2d.</li>
<li><span style="line-height: 1.5;">Dynamic <a href="https://incd021.com/pyxel-edit-first-impression-and-importer/">loading of levels</a></span></li>
<li>Got better at using animations instead of moving logos in code <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
<li>Deploy to OUYA and very basic OUYA input control (one button).</li>
</ul>
<p><strong>Things to do better:</strong></p>
<ul>
<li>If I want my POCs to be playable, make some simple object relation layout BEFORE coding a single line <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
<li>Use more object pools, instead of creating objects on the fly.</li>
<li>Find a better way to handle the growing switch/case section in the game manager.</li>
<li>Graphics.. I started looking at <a href="http://www.blender.org/">blender </a>again. Did the beautiful stars in it <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
<li>Write posts on the way instead of having to remember what I did after the fact.</li>
</ul>
<p>Hope you enjoy the 10 levels of this mini-game &#8220;<a href="https://incd021.com/Games/Left/Left.html">Left</a>&#8221; (named as such, as  you have a tendency to turn left).</p>
<p>Now, go make games! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&#8211; Henning</p>
<p>Screenshot of main screen, the 10 levels and the game completed screen.</p>
<p><figure id="attachment_487" aria-describedby="caption-attachment-487" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2014/01/AllLeftLevels.jpg"><img loading="lazy" decoding="async" class="size-medium wp-image-487" alt="All levels of Left" src="https://incd021.com/wp-content/uploads/2014/01/AllLeftLevels-300x300.jpg" width="300" height="300" /></a><figcaption id="caption-attachment-487" class="wp-caption-text">All levels of Left</figcaption></figure></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2014/01/28/left-new-mini-game-learned/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>3&#215;3 POC to production.</title>
		<link>https://incd021.com/2013/06/08/3x3-poc-to-production/</link>
					<comments>https://incd021.com/2013/06/08/3x3-poc-to-production/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sat, 08 Jun 2013 21:04:32 +0000</pubDate>
				<category><![CDATA[3x3]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Indie Game]]></category>
		<category><![CDATA[POC]]></category>
		<category><![CDATA[Polish]]></category>
		<category><![CDATA[production]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=284</guid>

					<description><![CDATA[I started the 3&#215;3 game as a POC of an old game idea, but I&#8217;m starting to like the game, so I have decided to spend some time adding to....]]></description>
										<content:encoded><![CDATA[<p>I started the 3&#215;3 game as a POC of an old game idea, but I&#8217;m starting to like the game, so I have decided to spend some time adding to it, polishing it, and see if I can make a decent game out of it. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><span style="line-height: 1.5;">This means that I have to find some music, sound effects, make some better looking graphics, and what I find hardest of all &#8211; make the menu system! I&#8217;ll keep it as simple as possible.</span></p>
<p><figure id="attachment_291" aria-describedby="caption-attachment-291" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2013/06/3x3v006.png"><img loading="lazy" decoding="async" class="size-medium wp-image-291" alt="3x3 POC version 6" src="https://incd021.com/wp-content/uploads/2013/06/3x3v006-300x187.png" width="300" height="187" /></a><figcaption id="caption-attachment-291" class="wp-caption-text">3&#215;3 POC version 6</figcaption></figure></p>
<p>After I did the <a href="https://incd021.com/full-progress-report-for-the-creation-of-the-game-do-no-harm/">DNH game for the GIG 2013</a>, I will not be making an online highscore list. I might do a cookie based one, so the players best score will remain between sessions, but that&#8217;s it.</p>
<p>One thing I would really like, is a better player controller. As mentioned in &#8220;<a href="https://incd021.com/player-movement-script-for-the-3x3-poc/">Player movement script for the 3&#215;3 POC</a>&#8221; the motion is done in steps and you can&#8217;t move diagonal or change direction while moving. This I need to do better. And I will <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Lets see where the game takes me.</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2013/06/08/3x3-poc-to-production/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>3×3 POC version 4</title>
		<link>https://incd021.com/2013/06/06/3x3-poc-version-4/</link>
					<comments>https://incd021.com/2013/06/06/3x3-poc-version-4/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Thu, 06 Jun 2013 06:01:25 +0000</pubDate>
				<category><![CDATA[3x3]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Indie Game]]></category>
		<category><![CDATA[POC]]></category>
		<category><![CDATA[Unity3D]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=265</guid>

					<description><![CDATA[The POC is really starting to look like a game. 🙂 New things added: New texture. I only use one for all surfaces. Rotation to selected box, to make it....]]></description>
										<content:encoded><![CDATA[<p>The POC is really starting to look like a game. <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>New things added:</p>
<ul>
<li><span style="line-height: 1.5;">New texture. I only use one for all surfaces.</span></li>
<li><span style="line-height: 1.5;">Rotation to selected box, to make it visible to the player what box is selected.</span></li>
<li><span style="line-height: 1.5;">More states to the box objects, to make possible removal animation aso.</span></li>
<li><span style="line-height: 1.5;">Color click logic, basic game mechanics .</span></li>
</ul>
<p><figure id="attachment_266" aria-describedby="caption-attachment-266" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2013/06/3x3v004.png"><img loading="lazy" decoding="async" class="size-medium wp-image-266" alt="3x3 POC version 4" src="https://incd021.com/wp-content/uploads/2013/06/3x3v004-300x187.png" width="300" height="187" /></a><figcaption id="caption-attachment-266" class="wp-caption-text">3&#215;3 POC version 4</figcaption></figure></p>
<p>The plan is to make the game run on my old HTC Desire, to learn the mobile part of unity. So for now I&#8217;m trying to keep everything to a minimum as not to drive the Desire to it&#8217;s knees.</p>
<p>Next things to add:</p>
<ul>
<li><span style="line-height: 1.5;">Mobile input part, to see if I can&#8217;t get the click and swipe part to work.</span></li>
<li><span style="line-height: 1.5;">Light bound to the box, to illuminate the boxes in the distance, and I might remove the current spotlight..</span></li>
</ul>
<p>&nbsp;</p>
<p><span style="line-height: 1.5;">Future things to add:</span></p>
<ul>
<li><span style="line-height: 1.5;">Sound effects.</span></li>
<li><span style="line-height: 1.5;">Music.</span></li>
<li>Score system. How fast you remove boxes, or something like that, have to think about a good way to differentiate different users abilities.</li>
</ul>
<p>&nbsp;</p>
<p>Here you can play <a href="https://incd021.com/Games_POC/3x3v004.html">version 4</a>, and as before, click to remove blocks and navigate using wasd.</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2013/06/06/3x3-poc-version-4/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>3&#215;3 POC version 3</title>
		<link>https://incd021.com/2013/06/04/3x3-poc-version-3/</link>
					<comments>https://incd021.com/2013/06/04/3x3-poc-version-3/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Tue, 04 Jun 2013 16:59:35 +0000</pubDate>
				<category><![CDATA[3x3]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Indie Game]]></category>
		<category><![CDATA[POC]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=254</guid>

					<description><![CDATA[OK, finally had some time to try some more things out with the 3&#215;3 idea. So now the colored boxes are boxes and not just generated quads, they are clickable....]]></description>
										<content:encoded><![CDATA[<p>OK, finally had some time to try some more things out with the 3&#215;3 idea. So now the colored boxes are boxes and not just generated quads, they are clickable and have box colliders and so does the camera/player, so if you hit a box, it&#8217;s game over, and for now you have to restart the game to play again. Also you are now able to hold down a key (wasd) to keep moving in that direction.</p>
<p>I added some game states but only use <em>playing</em> and <em>dead</em> for now.</p>
<p><figure id="attachment_255" aria-describedby="caption-attachment-255" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2013/06/3x3v003ScreenShot.png"><img loading="lazy" decoding="async" class="size-medium wp-image-255" alt="3x3 POC version 4" src="https://incd021.com/wp-content/uploads/2013/06/3x3v003ScreenShot-300x187.png" width="300" height="187" /></a><figcaption id="caption-attachment-255" class="wp-caption-text">3&#215;3 POC version 3</figcaption></figure></p>
<p><span style="line-height: 1.5;">Next I would like to make the color selection part to only allow you to remove boxes of same color, so if you click a blue box you can only remove another blue box. If you click another colored box the first selected color will change to this color.</span></p>
<p>Here you can play <a href="https://incd021.com/Games_POC/3x3v003.html">version 3</a>, click to remove blocks and navigate with wasd.</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2013/06/04/3x3-poc-version-3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>3&#215;3 square game.</title>
		<link>https://incd021.com/2013/05/29/3x3-square-game/</link>
					<comments>https://incd021.com/2013/05/29/3x3-square-game/#respond</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Wed, 29 May 2013 17:12:08 +0000</pubDate>
				<category><![CDATA[3x3]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=246</guid>

					<description><![CDATA[Yet another game idea. This time, a combined mouse and keyboard racer. The idea is to have a 3&#215;3 colored board coming towards you (the feel should of cause be....]]></description>
										<content:encoded><![CDATA[<p>Yet another game idea. This time, a combined mouse and keyboard racer. The idea is to have a 3&#215;3 colored board coming towards you (the feel should of cause be you race towards it), and you have to click two matching colored squares, and they will disappear, and you have to fly trough one of the hole left by the removed squares. The 9 square are to be colored using 1-8 colors, so there will always be at least 2 matching squares. the use of one color is level 1, and 8 colors level 8. The speed by which the squares are flying towards the player, will of cause increase over time.</p>
<p>Play the <a href="https://incd021.com/Games_POC/3x3.html">first proof of concept</a><span style="line-height: 1.5;">, it has only a simple wasd control and that&#8217;s about it.</span></p>
<p><figure id="attachment_249" aria-describedby="caption-attachment-249" style="width: 300px" class="wp-caption aligncenter"><a href="https://incd021.com/wp-content/uploads/2013/05/3x3POC001.png"><img loading="lazy" decoding="async" class="size-medium wp-image-249" alt="3x3 first proof of concept" src="https://incd021.com/wp-content/uploads/2013/05/3x3POC001-300x187.png" width="300" height="187" /></a><figcaption id="caption-attachment-249" class="wp-caption-text">Proof of concept, screenshot of the game 3&#215;3</figcaption></figure></p>
<p>I have to do more tests to see if this would be a fun.</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2013/05/29/3x3-square-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How simple a game can I make.</title>
		<link>https://incd021.com/2013/05/12/how-simple-a-game-can-i-make/</link>
					<comments>https://incd021.com/2013/05/12/how-simple-a-game-can-i-make/#comments</comments>
		
		<dc:creator><![CDATA[INC $D021]]></dc:creator>
		<pubDate>Sun, 12 May 2013 20:21:36 +0000</pubDate>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Proof of concept]]></category>
		<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">http://incd021.com/?p=229</guid>

					<description><![CDATA[Every new game developer, asking &#8220;What&#8217;s the best advice when starting game developing?&#8221; are often told &#8220;Make lots of games&#8221; and &#8220;Start simple&#8221;, so when I saw this small Ludum Dare....]]></description>
										<content:encoded><![CDATA[<p>Every new game developer, asking &#8220;What&#8217;s the best advice when starting game developing?&#8221; are often told &#8220;Make lots of games&#8221; and &#8220;Start simple&#8221;, so when I saw <span style="line-height: 1.5;">this small Ludum Dare 26 entry called </span><a style="line-height: 1.5;" href="http://www.jarcas.com/LD26/">Tiny Runner by Jarcas Studios</a><span style="line-height: 1.5;"> I was amazed of the </span>simplicity<span style="line-height: 1.5;"> of the game. </span><span style="line-height: 1.5;">So I had to try to make something even simpler, and at the same time I could test a simple character 2D controller <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> After a couple of hours I had this.</span></p>
<p><iframe loading="lazy" title="JumpNSlide" width="768" height="432" src="https://www.youtube.com/embed/famEBeYGguM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<p>And yes I did all the graphics myself <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>If you really want, you can <a href="https://incd021.com/Games_POC/JumpNSlide.html">play the game</a> here.</p>
<p>&#8211; Henning</p>
]]></content:encoded>
					
					<wfw:commentRss>https://incd021.com/2013/05/12/how-simple-a-game-can-i-make/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Page Caching using Disk: Enhanced 

Served from: incd021.com @ 2025-05-21 22:16:48 by W3 Total Cache
-->