<?xml version='1.0' encoding='utf-8'?>
<MNPreset formatVersion="1"><metadata name="Pong" description="A game in one node: its state in Buffer A, played with the mouse or the keys. Edit the Shader Code node to change the drawing, or set its File to follow your own GLSL file." author="MNodes" category="Scene Studio" pluginVersion="1.1.5" createdAt="1790467200000" modifiedAt="1790467200000" type="Utility" preferredOpenMode="perform" tags="scene, visual, interface" /><state><marionietoworld.MNodes_State gridActive="0" gridSize="20" viewOffsetX="0" viewOffsetY="48" zoom="0.80" didInitView="1" toolbarExpanded="0" pv="1.1.5"><nodes nextId="6"><node id="1" type="visual.shadercode" title="Code - Pong" expanded="1" x="32" y="200" w="310" h="240"><state file="" textsize="13.0" out="0.0" code="// Pong&#10;//&#10;// A game in one node. Its state (the ball, the paddles, the score) lives in&#10;// Buffer A: a few pixels that pass writes each frame from what it read the&#10;// frame before. Image draws it. Your paddle is on the left: drag it (the&#10;// Paddle zone), or turn Keyboard on in the Inspector and use W and S or the&#10;// arrows, and Space to serve. A click serves too. First to nine wins.&#10;&#10;#pass A&#10;void mainImage(out vec4 o, in vec2 fragCoord)&#10;{&#10;    ivec2 t = texelAt(fragCoord);&#10;    o = vec4(0.0);&#10;    if (t.y != 0 || t.x &gt; 2) return;&#10;&#10;    vec2 R = iResolution.xy;&#10;    float dt = clamp(iTimeDelta, 0.0, 1.0 / 30.0);&#10;    vec4 ball = readA(ivec2(0, 0));   // where it is, where it goes&#10;    vec4 pads = readA(ivec2(1, 0));   // your paddle, the other, your score, its score&#10;    vec4 game = readA(ivec2(2, 0));   // waiting to serve, serves so far, who won, set up&#10;&#10;    float padH = R.y * 0.2, padW = R.x * 0.015, radius = R.y * 0.022;&#10;    float leftX = R.x * 0.06, rightX = R.x * 0.94;&#10;&#10;    if (game.w &lt; 0.5)&#10;    {&#10;        ball = vec4(R * 0.5, 0.0, 0.0);&#10;        pads = vec4(R.y * 0.5, R.y * 0.5, 0.0, 0.0);&#10;        game = vec4(1.0, 0.0, 0.0, 1.0);&#10;    }&#10;&#10;    // Your paddle: the keys move it, dragging puts it where you drag.&#10;    float move = max(keyDown(KEY_W), keyDown(KEY_UP)) - max(keyDown(KEY_S), keyDown(KEY_DOWN));&#10;    pads.x += move * R.y * 1.3 * dt;&#10;    if (zonePressed(Paddle) &gt; 0.5)&#10;        pads.x = mix(padH * 0.5, R.y - padH * 0.5, zoneValue(Paddle));&#10;    pads.x = clamp(pads.x, padH * 0.5, R.y - padH * 0.5);&#10;&#10;    // The other paddle follows the ball, a little slower than it can go.&#10;    float target = ball.z &gt; 0.0 ? ball.y : R.y * 0.5;&#10;    pads.y += clamp(target - pads.y, -R.y * 0.75 * dt, R.y * 0.75 * dt);&#10;    pads.y = clamp(pads.y, padH * 0.5, R.y - padH * 0.5);&#10;&#10;    bool serve = keyPressed(KEY_SPACE) &gt; 0.5 || MouseClick &gt; 0.5;&#10;    if (game.x &gt; 0.5)&#10;    {&#10;        ball = vec4(R * 0.5, 0.0, 0.0);&#10;        if (serve)&#10;        {&#10;            if (game.z &gt; 0.5) { pads.zw = vec2(0.0); game.z = 0.0; }   // a new game&#10;            game.x = 0.0;&#10;            game.y += 1.0;&#10;            float side = mod(game.y, 2.0) &lt; 1.0 ? 1.0 : -1.0;&#10;            float angle = (fract(sin(game.y * 12.9898 + iTime) * 43758.5453) - 0.5) * 1.1;&#10;            ball.zw = vec2(side * cos(angle), sin(angle)) * R.x * 0.5;&#10;        }&#10;    }&#10;    else&#10;    {&#10;        ball.xy += ball.zw * dt;&#10;        if (ball.y &lt; radius)       { ball.y = radius;       ball.w = abs(ball.w); }&#10;        if (ball.y &gt; R.y - radius) { ball.y = R.y - radius; ball.w = -abs(ball.w); }&#10;&#10;        // The paddles send it back, faster, and at an angle from where it hit.&#10;        if (ball.z &lt; 0.0 &amp;&amp; ball.x - radius &lt; leftX + padW &amp;&amp; ball.x &gt; leftX - padW&#10;            &amp;&amp; abs(ball.y - pads.x) &lt; padH * 0.5 + radius)&#10;        {&#10;            ball.z = abs(ball.z) * 1.06;&#10;            ball.w += (ball.y - pads.x) / padH * R.y * 1.2;&#10;            ball.x = leftX + padW + radius;&#10;        }&#10;        if (ball.z &gt; 0.0 &amp;&amp; ball.x + radius &gt; rightX - padW &amp;&amp; ball.x &lt; rightX + padW&#10;            &amp;&amp; abs(ball.y - pads.y) &lt; padH * 0.5 + radius)&#10;        {&#10;            ball.z = -abs(ball.z) * 1.06;&#10;            ball.w += (ball.y - pads.y) / padH * R.y * 1.2;&#10;            ball.x = rightX - padW - radius;&#10;        }&#10;        ball.zw = clamp(ball.zw, -R.xx * 2.5, R.xx * 2.5);&#10;&#10;        // A point, and a winner at nine.&#10;        if (ball.x &lt; -radius * 2.0)      { pads.w += 1.0; game.x = 1.0; }&#10;        if (ball.x &gt; R.x + radius * 2.0) { pads.z += 1.0; game.x = 1.0; }&#10;        if (pads.z &gt;= 9.0) game.z = 1.0;&#10;        if (pads.w &gt;= 9.0) game.z = 2.0;&#10;    }&#10;&#10;    o = t.x == 0 ? ball : t.x == 1 ? pads : game;&#10;}&#10;&#10;#pass Image&#10;float px;&#10;float fillOf(float d) { return clamp(0.5 - d / px, 0.0, 1.0); }&#10;&#10;float sdSegment(vec2 p, vec2 a, vec2 b)&#10;{&#10;    vec2 pa = p - a, ba = b - a;&#10;    return length(pa - ba * clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0));&#10;}&#10;&#10;float sdBox(vec2 p, vec2 b) { vec2 q = abs(p) - b; return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0); }&#10;&#10;// A digit from 0 to 9 in seven segments, in a box one wide and two tall.&#10;float digit(vec2 p, int n)&#10;{&#10;    int m = n == 0 ? 0x3F : n == 1 ? 0x06 : n == 2 ? 0x5B : n == 3 ? 0x4F : n == 4 ? 0x66&#10;          : n == 5 ? 0x6D : n == 6 ? 0x7D : n == 7 ? 0x07 : n == 8 ? 0x7F : 0x6F;&#10;    float d = 1.0e5;&#10;    if ((m &amp; 1)  != 0) d = min(d, sdSegment(p, vec2(0.0, 2.0), vec2(1.0, 2.0)));&#10;    if ((m &amp; 2)  != 0) d = min(d, sdSegment(p, vec2(1.0, 2.0), vec2(1.0, 1.0)));&#10;    if ((m &amp; 4)  != 0) d = min(d, sdSegment(p, vec2(1.0, 1.0), vec2(1.0, 0.0)));&#10;    if ((m &amp; 8)  != 0) d = min(d, sdSegment(p, vec2(0.0, 0.0), vec2(1.0, 0.0)));&#10;    if ((m &amp; 16) != 0) d = min(d, sdSegment(p, vec2(0.0, 1.0), vec2(0.0, 0.0)));&#10;    if ((m &amp; 32) != 0) d = min(d, sdSegment(p, vec2(0.0, 2.0), vec2(0.0, 1.0)));&#10;    if ((m &amp; 64) != 0) d = min(d, sdSegment(p, vec2(0.0, 1.0), vec2(1.0, 1.0)));&#10;    return d;&#10;}&#10;&#10;void mainImage(out vec4 fragColor, in vec2 fragCoord)&#10;{&#10;    px = 1.0 / max(mnPixelScale, 0.001);&#10;    vec2 R = iResolution.xy, p = fragCoord;&#10;    vec4 ball = readA(ivec2(0, 0)), pads = readA(ivec2(1, 0)), game = readA(ivec2(2, 0));&#10;    float padH = R.y * 0.2, padW = R.x * 0.015, radius = R.y * 0.022;&#10;    vec3 light = vec3(0.3, 1.0, 0.75);&#10;&#10;    // the court&#10;    vec3 col = mix(vec3(0.01, 0.03, 0.03), vec3(0.02, 0.06, 0.06), p.y / R.y);&#10;    col += light * 0.12 * fillOf(abs(p.x - R.x * 0.5) - 1.0) * step(0.5, fract(p.y / (R.y * 0.05)));&#10;    col += light * 0.25 * fillOf(min(p.y, R.y - p.y) - 1.5);&#10;&#10;    // the score&#10;    float size = R.y * 0.07;&#10;    float score = min(digit((p - vec2(R.x * 0.5 - size * 2.2, R.y - size * 2.8)) / size, int(pads.z)),&#10;                      digit((p - vec2(R.x * 0.5 + size * 1.2, R.y - size * 2.8)) / size, int(pads.w))) * size - size * 0.09;&#10;    col = mix(col, light * 0.8, fillOf(score));&#10;    col += light * 0.25 * exp(-max(score, 0.0) / (size * 0.3));&#10;&#10;    // the paddles and the ball, with their light&#10;    float paddles = min(sdBox(p - vec2(R.x * 0.06, pads.x), vec2(padW, padH * 0.5)),&#10;                        sdBox(p - vec2(R.x * 0.94, pads.y), vec2(padW, padH * 0.5))) - 2.0;&#10;    col = mix(col, vec3(0.85, 1.0, 0.95), fillOf(paddles));&#10;    col += light * 0.5 * exp(-max(paddles, 0.0) / (R.y * 0.03));&#10;    float b = length(p - ball.xy) - radius;&#10;    col = mix(col, vec3(1.0), fillOf(b));&#10;    col += vec3(1.0, 0.8, 0.4) * 0.6 * exp(-max(b, 0.0) / (radius * 1.5));&#10;&#10;    // waiting to serve: a soft pulse in the middle&#10;    if (game.x &gt; 0.5)&#10;        col += light * 0.15 * (0.5 + 0.5 * sin(iTime * 4.0)) * exp(-length(p - R * 0.5) / (R.y * 0.15));&#10;&#10;    // where you drag your paddle, lit while the pointer is over it&#10;    col += light * 0.04 * zoneHover(Paddle) * step(p.x, R.x * 0.33);&#10;    fragColor = vec4(col, 1.0);&#10;}&#10;" live="1" ui_only="1" hide_unconnected="1" /></node><node id="2" type="visual.gpucanvas" title="Scene" expanded="1" x="754" y="200" w="600" h="420"><state in="0.0" inb="0.0" codein="0.0" zonesin="0.0" setrow="0.0" scriptin="0.0" editObjects="0" appearanceRow="0.0" pcount="8" speed="1.0" p1="0.0" p2="0.0" p3="0.0" p4="0.0" p5="0.0" p6="0.0" p7="0.0" p8="0.0" mousex="0.5" mousey="0.5" wheel="0.0" dragx="0.0" dragy="0.0" imouse="0 0 0 0" code="" zones="[&#10;  { &quot;id&quot;: 1, &quot;name&quot;: &quot;Paddle&quot;, &quot;type&quot;: &quot;slider&quot;, &quot;shape&quot;: &quot;rect&quot;, &quot;x&quot;: 0, &quot;y&quot;: 0, &quot;w&quot;: 0.33, &quot;h&quot;: 1, &quot;default&quot;: 0.5, &quot;vertical&quot;: true }&#10;]" zonevalues="" labels="" image1="" image2="" fontFile="" preserveBuffers="0" resolution="0" framerate="1" transparent="0" background="FF0F131A" keyboard="1" zoneinputs="1" showOrientation="0" showObjectAxes="0" visible="1" ignoreClicks="0" panelX="0.0" panelY="0.0" panelW="0.0" panelH="0.0" tooltipStyle="" exposeToDAW="0" ui_only="1" hide_unconnected="1" /></node><node id="3" type="comment" title="Comment" expanded="0" x="24" y="18" w="1320" h="48"><state text="Pong" fontSize="32" fontWeight="3" align="0" textColour="ffe5ecee" bgColour="00000000" borderColour="80ffffff" borderOn="0" borderStroke="1.0" fontFamily="Inter" /></node><node id="4" type="comment" title="Comment" expanded="0" x="24" y="78" w="1320" h="94"><state text="A game in one node: its state in Buffer A, played with the mouse or the keys. Edit the Shader Code node to change the drawing, or set its File to follow your own GLSL file." fontSize="20" fontWeight="1" align="0" textColour="ffcad5d9" bgColour="00000000" borderColour="80ffffff" borderOn="0" borderStroke="1.0" fontFamily="Inter" /></node><node id="5" type="comment" title="Comment" expanded="0" x="754" y="654" w="580" h="116"><state text="Select a node for its settings. Open the separate Code or Script to change the drawing. Show Zones reveals interaction areas." fontSize="20" fontWeight="1" align="0" textColour="ff80d9de" bgColour="00000000" borderColour="80ffffff" borderOn="0" borderStroke="1.0" fontFamily="Inter" /></node></nodes><edges><e fn="1" fp="0" tn="2" tp="2" /></edges><panel width="720" height="440" locked="1" zoom="1" performScale="1" gridEnabled="0" toolbarExpanded="0" panelBgColour="ff101820"><entry nodeId="2" x="0" y="0" w="720" h="440" z="0" auto="0" /></panel></marionietoworld.MNodes_State></state></MNPreset>