<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://cataluna.cat/feed.xml" rel="self" type="application/atom+xml" /><link href="https://cataluna.cat/" rel="alternate" type="text/html" /><updated>2026-02-20T15:11:04+00:00</updated><id>https://cataluna.cat/feed.xml</id><title type="html">Luna a l’interxarxa</title><subtitle>Web de luna. Aqui trobaras totes les coses que faig he fet i tal. Noseee</subtitle><entry><title type="html">Descarregar de Texture Haven en baixa qualitat (a propòsit)</title><link href="https://cataluna.cat/paraules/2025/03/13/Tinc-una-eina.html" rel="alternate" type="text/html" title="Descarregar de Texture Haven en baixa qualitat (a propòsit)" /><published>2025-03-13T00:00:00+00:00</published><updated>2025-03-13T00:00:00+00:00</updated><id>https://cataluna.cat/paraules/2025/03/13/Tinc-una-eina</id><content type="html" xml:base="https://cataluna.cat/paraules/2025/03/13/Tinc-una-eina.html"><![CDATA[<p>M’encanta utilitzar <a href="https://polyhaven.com/textures">Texture Haven</a> per als meus projectes.</p>

<p>És una eina que he fet servir molts cops i em meravella la qualitat de les textures i que siguin tan accessibles.</p>

<p>Però molts cops les textures tenen massa qualitat per als meus jocs low poly. Al descarregar, la qualitat mínima és de 1k (1024x1024).</p>

<p><img src="/imgs/posts/texturehaven-download.jpg" alt="Al descarregar, la qualitat mínima és 1k" /></p>

<p>Que pot semblar poc (ho és) però per als meus jocs web això pot arribar a repercutir gairebé 1mb d’espai per textura! I si és un material PBR ja multiplica això per 5.</p>

<h2 id="rescalat">Rescalat</h2>
<p>Molts cops havia de, abans d’usar la textura, descarregar-la, descomprimir-la i anar una per una reescalant la imatge. Avorrit si em pregunten.</p>

<p>Això fins que vaig adonar-me que a la previsualització, apareixen els materials PBR.</p>

<p><img src="/imgs/posts/texturehaven-thumbnail.jpg" alt="Al descarregar, la qualitat mínima és 1k" /></p>

<p>Obrint aquests thumbnails en una nova finestra ens desvela el següent format de URL:</p>

<p>`
nomMaterial/nomMaterial_tipusTextura_1k.jpg?height=midaPixels&amp;width=midaPixels
`</p>

<p>Bingo. Amb aquesta adreça podíem trobar un .webp de la textura 1k escalada a la mida que volgués (sempre que no excedís 1024). Perfecte, perquè a sobre Godot em deixa ficar .webp com textures.</p>

<h2 id="la-màgia-dels-bookmarks-de-chrome">La màgia dels bookmarks de Chrome</h2>
<p>Amb aquesta URL podia anar per cada tipus de textura i descarregar en una mida tipus 512x512. Però igualment continuava sent més lent.</p>

<p>Buscaba una manera de fer aquest process més rapid, en concret perque estava fent el meu ultim joc <a href="https://lunamoreno.itch.io/corridors-of-power">Corridors of Power</a></p>

<p>Així que vaig fer un programet en JS que ho fes per mi. Detectés la textura on fos, em fes un prompt de la mida a la que volia les imatges i m’obrís en finestres noves cada tipus de textura. Voilà!</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">javascript</span><span class="p">:(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
    <span class="kd">function</span> <span class="nx">openNewTab</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span>
        <span class="nb">window</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="dl">"</span><span class="s2">_blank</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="kd">let</span> <span class="nx">currentUrl</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">currentUrl</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="dl">"</span><span class="s2">https://polyhaven.com/a</span><span class="dl">"</span><span class="p">))</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nx">pixel_size</span> <span class="o">=</span> <span class="nx">prompt</span><span class="p">(</span><span class="dl">"</span><span class="s2">Mida en px: (1,1080)</span><span class="dl">"</span><span class="p">);</span>
        <span class="kd">let</span> <span class="nx">varMaterial</span> <span class="o">=</span> <span class="nx">currentUrl</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">"</span><span class="s2">/</span><span class="dl">"</span><span class="p">)[</span><span class="mi">4</span><span class="p">];</span>
        <span class="kd">let</span> <span class="nx">textureTypes</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">ao</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">diff</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">nor_gl</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">rough</span><span class="dl">"</span><span class="p">];</span>
        <span class="nx">textureTypes</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">textureType</span><span class="p">)</span> <span class="p">{</span>
            <span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`https://cdn.polyhaven.com/asset_img/map_previews/</span><span class="p">${</span><span class="nx">varMaterial</span><span class="p">}</span><span class="s2">/</span><span class="p">${</span><span class="nx">varMaterial</span><span class="p">}</span><span class="s2">_</span><span class="p">${</span><span class="nx">textureType</span><span class="p">}</span><span class="s2">_1k.jpg?height=</span><span class="p">${</span><span class="nx">pixel_size</span><span class="p">}</span><span class="s2">&amp;width=</span><span class="p">${</span><span class="nx">pixel_size</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
            <span class="nx">openNewTab</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
        <span class="p">});</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="nx">openNewTab</span><span class="p">(</span><span class="dl">"</span><span class="s2">https://polyhaven.com/textures</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">})();</span>
</code></pre></div></div>

<p>Per poder-ho executar, ho vaig posar com una de les meves funcions preferides dels bookmarks de Chrome: un enllaç que executi JS.</p>

<p>Per afegir-ho al Chrome simplement selecciona el codi de dalt i arrossega-ho a la barra d’adreces.</p>

<p><img src="/imgs/posts/texturehaven-bookmark.gif" alt="Exemple assignació bookmark" /></p>

<h2 id="funcionament">Funcionament</h2>
<p>El funcionament és molt senzill. Si s’executa en una pàgina que no és la d’una textura de Polyhaven, redireccionarà a la pàgina principal de textures.</p>

<p>Un cop la pestanya actual sigui d’una textura, al prémer el botó demanarà la mida de textura desitjada (més de 1080 no tindrà efecte).</p>

<p>Al prémer acceptar, obrirà en una nova finestra les textures PBR corresponents. L’única feina manual que s’ha de fer és 1 per 1 descarregar les textures de les pestanyes.</p>

<p><img src="/imgs/posts/texturehaven-tutorial.gif" alt="Exemple us extensió" /></p>]]></content><author><name>Luna</name></author><category term="paraules" /><category term="tools," /><category term="codi," /><category term="javascript" /><summary type="html"><![CDATA[M’encanta utilitzar Texture Haven per als meus projectes.]]></summary></entry><entry><title type="html">Creant un bot de Twitter (X) amb GitHub Actions</title><link href="https://cataluna.cat/paraules/2024/09/25/Tinc-un-bot-de-tuiter.html" rel="alternate" type="text/html" title="Creant un bot de Twitter (X) amb GitHub Actions" /><published>2024-09-25T00:00:00+00:00</published><updated>2024-09-25T00:00:00+00:00</updated><id>https://cataluna.cat/paraules/2024/09/25/Tinc-un-bot-de-tuiter</id><content type="html" xml:base="https://cataluna.cat/paraules/2024/09/25/Tinc-un-bot-de-tuiter.html"><![CDATA[<p>Un dels meus projectes actius es el compte <a href="https://twitter.com/girocletaBOT">girocletaBOT</a> a la xarxa social Twitter (X).</p>

<p>Aquest compte es dedica a tuitar en intervals de 30 minuts l’estat de la xarxa de bicicletes compartides de la ciutat de Girona, a.k.a <a href="https://www.girocleta.cat/">Girocleta</a>.</p>

<p>Les publicacions es composen d’un text indicant la hora de publicació i un llistat on es detallen les bicicletes disponibles i els espais lliures per cada parada que, o bé tingui 5 o menys bicicletes o 5 o menys espais lliures. Al final del post s’incorpora un mapa de Girona amb la informació del tuit superposada a la ubicació de les estacions.</p>

<p><img src="/imgs/posts/girocleta-tweet.jpg" alt="Imatge del tuit de girocleta bot" /></p>

<h2 id="part-1-necesitat-i-recerca-de-alternatives">Part 1: Necesitat i recerca de alternatives</h2>
<p>Desde fa ben bé 2 anys soc usuaria de forma casi diaria del servei de Girocletes. Tinc la sort de tenir una parada prop d’on visc i un altre a prop d’on treballo, així que l’elecció d’aquest transport es casi obvia. L’estació al costat del meu pis es tracta d’una estació on hi ha molt moviment, cosa que provoca que a les 8:00 quan solc agafarles sigui una loteria el fet de trobar o no bicicletes, sobretot els dilluns.</p>

<p>Per tal de no trobar l’estacio buida pel mati i haver de fer mitja volta per anar a la seguent, em vaig acostumbrar a revisar el <a href="https://www.girocleta.cat/mapaestacions.aspx">mapa d’estacions oficial</a> i qualsevol que hagi usar el mapa oficial podra estar d’acord que, sobretot al movil, es molt poc <code class="language-plaintext highlighter-rouge">user friendly</code>. Els icones es moven de manera horrible, no estan ben centrats, la informació massa.</p>

<p><img src="/imgs/posts/girocleta-mapa.jpg" alt="Imatge del mapa de estacions oficial" /></p>

<p>D’aqui va neixer la voluntat de trobar una alternativa, i quan l’unica que vaig trobar va ser un <a href="https://github.com/Lloople/bot-girocleta">bot de telegram</a> que feia 4 anys que no s’actualitzava vaig pensar que hauria de practicar les meves habilitats trobant una sol·lució.</p>

<h2 id="part-2-origen-de-les-dades">Part 2: Origen de les dades</h2>
<p>Desde el prinicipi tenia clar que la clau del projecte era la obtencio de dades. Vaig pensar que el mapa d’estacions tindria una cosa semblant a una API… Si voleu mireu amb el codi de la pagina d’estacions per veure com esta fet… yikes. Es més, vaig pensar en buscar l’empresa responsable de l’instalació de les Girocletes, Emovity, filla de Icnita. Us animo a buscar en Google la situacio d’aquestes dues empreses.</p>

<p>Veient que no hi havia cap solució vaig pensar en fer un scraping del web, pero llavors vaig topar-me amb la api de <a href="https://api.citybik.es/v2/">CityBikes</a>. La felicitat que vaig sentir al trobar aquesta api va ser com descobrir el Sant Grial. Amb només un endpoint ja tenia sol·lucionat aquet problema, asobre en un molt assolible format <a href="https://api.citybik.es/v2/networks/girocleta">JSON</a>.</p>

<p>Com a curiositat, CityBikes funciona mitjançant scraping, i a la part del <a href="https://github.com/eskerda/pybikes/blob/master/pybikes/emovity.py">codi</a> que fa scrpaping del mapa de girocletes hi ha aquest comentari:
<img src="/imgs/posts/girocleta-comment.jpg" alt="Comentari al codi scraping" /></p>

<p>En construcció</p>]]></content><author><name>Luna</name></author><category term="paraules" /><summary type="html"><![CDATA[Un dels meus projectes actius es el compte girocletaBOT a la xarxa social Twitter (X).]]></summary></entry><entry><title type="html">Tinc un blog</title><link href="https://cataluna.cat/paraules/2024/09/23/Tinc-un-blog.html" rel="alternate" type="text/html" title="Tinc un blog" /><published>2024-09-23T00:00:00+00:00</published><updated>2024-09-23T00:00:00+00:00</updated><id>https://cataluna.cat/paraules/2024/09/23/Tinc-un-blog</id><content type="html" xml:base="https://cataluna.cat/paraules/2024/09/23/Tinc-un-blog.html"><![CDATA[<p>Finalment, m’he decidit en tenir un blog en condicions.</p>

<h3 id="per-què">Per què?</h3>
<p>El principal motiu per voler un blog, i en definitiva una pàgina web, és tenir un lloc descentralitzat on posar les meves idees. Xarxes de bloging com Twitter o tal estan bé, però sempre està la por que arribi un Elon Musk i la tiri a terra.</p>

<p>Aquestes xarxes no deixen de ser negocis, i tot el que hi escrius com si fos el teu bloc de notes acaba sent <code class="language-plaintext highlighter-rouge">contingut</code>, un <em>asset</em> més d’una empresa que poc a veure’t amb tu. Poder tenir les meves idees i els meus projectes en un <em>host</em> propi m’aporta tranquil·litat.</p>
<h3 id="internet-antic">Internet antic</h3>
<p>Un altre motiu és la <em>nostalgia</em> per un internet més lliure, una extensió de l’expressió humana per sobre de tot. L’internet actual es troba en un estat de submissió on les pàgines grans s’han imposat i han fet de l’internet un lloc homogeni i avorrit, amb poques opcions de personalització i expressió dels usuaris.</p>

<p>L’internet hauria de ser una altra cosa. M’imagino l’internet com un camp infinit, on cada individu pot tenir la seva pròpia parcel·la de terreny, sense haver de dependre d’un tercer gegant, que no es preocupa pels seus usuaris.</p>

<hr />
<p>Al final, per mi aquesta pàgina web i tot el que amaga per mi acaba sent com un diari personal més que com un cartell publicitari. És a dir, l’objectiu de visitats ideals sempre serà 0, i qualsevol persona que es trobi amb això ho senti com entrar en un espai personal, no en una plana publicitaria.</p>]]></content><author><name>Luna</name></author><category term="paraules" /><summary type="html"><![CDATA[Finalment, m’he decidit en tenir un blog en condicions.]]></summary></entry></feed>