Skip to content

Bassa de la Font Pudosa Traditional Cache

Hidden : 12/24/2012
Difficulty:
1.5 out of 5
Terrain:
2 out of 5

Size: Size:   small (small)

Join now to view geocache location details. It's free!

Watch

How Geocaching Works

Please note Use of geocaching.com services is subject to the terms and conditions in our disclaimer.

Geocache Description:


LA BASSA DE LA FONT PUDOSA A uns quilòmetres del nucli d'Amer i a poca distància a peu de l'embotelladora Fonter, en una zona boscosa, hi ha la Font Pudosa. Tothom, a Amer, en coneix l'existència, però la bassa no està indicada, ni sembla que tingui cap interès especial per als vilatans. Quan se'ls ho pregunta, tothom sap que és per aquella zona, però no en fan cas. La Font Pudosa no és més que una bassa però no deixa de tenir una certa fascinació. En el silenci del bosc, només se sent el mormoleig de les bombolles de diòxid de carboni (CO2) i radó en trencar-se a la superfície de l'aigua de la bassa. El CO2, sobretot, és un indicador que encara hi ha activitat sísmica a gran profunditat, i un testimoni que Amer qualsevol dia hi pot tornar a haver els terratrèmols i rèpliques que es van viure a la zona el 1427. M. Faura i Sans, a Sismologia catalana, va explicar així els moviments sísmics d'Amer: “Una repercussió del més extraordinari i impertinent terrabastall sísmic que afecta la regió volcànica olotina se sentí i ressonà a Barcelona, segons ho testifiquen les cròniques d'aquell any de desolació en què els volcans escumejaren flames i s'enderrocaren alguns pobles de la província de Girona. Aquells terratrèmols duraren prop de tres mesos, des del 23 de febrer fins al 15 de maig.” Un equip de geòlegs de la Universitat Autònoma de Barcelona (UAB) ha mesurat l'emanació de tres gasos (radó, toró i diòxid de carboni) de diversos punts d'Amer com a metodologia per poder determinar el grau d'activitat sísmica de la zona, ja que aquests gasos es poden haver generat a diversos quilòmetres de profunditat. Amer encara és una zona sísmica activa. Forma part de la falla de l'Empordà, de 30 quilòmetres, i Amer n'és al mig (arriba fins a Campdevànol). Pot haver-hi altres gasos a les zones estudiades, però els geòlegs de la UAB s'han centrat en el radó, el toró i el CO2. “Si rebem aquests gasos en superfície és un indicador que la fractura està oberta i té potencial de continuar-se movent". El CO2, concretament, és un gas que denota que hi ha activitat a molta fondària, després vindria el radó i en un tercer lloc, el toró. La concentració de gasos a la Font Pudosa es percep fàcilment, no només visualment, i pot arribar a marejar si s'hi està una estona a prop, però no és perillosa ja que és en un espai obert i ventilat. Una altra zona on abans també es concentraven gasos era a la Font Picant, que es troba a uns 2 km al nord del poble, al veïnat del Colomer. L'exalcalde d'Amer i estudiós del tema, Josep Puigdemont, explica com a anècdota que fa anys cada dia es trobava algun ocell mort a la zona enclotada de la Font Picant, a causa del CO2, que els estabornia i no tenien forces per tornar a emprendre el vol. “Cada matí, la dona que s'encarregava de la font treia els ocells morts”, explica. També recorda que quan era jove, era costum que els excursionistes que s'acostaven a la Font Pudosa en beguessin un got d'aigua. “Deien que netejava la sang”, recorda. Ara aquest costum s'ha abandonat del tot. Malgrat els estudis, és molt difícil saber quan es pot tornar a produir un terratrèmol d'una magnitud semblant al del 1427. “No és com a la zona de Califòrnia, a Catalunya els terratrèmols vénen molt espaiats, no és una zona sísmicament tan activa, i si els terratrèmols grans vénen cada mil anys, no en tenim cap registre”. Tot i que pot semblar que el segle XV queda molt lluny, en termes geològics, és molt poc temps.

 

<!doctype html>
<html lang="ca">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>Tetris</title>
<style>
  :root{
    --bg:#0f0f12; --panel:#17181d; --ink:#e8e8ef; --muted:#9196a6; --accent:#7bd88f; --warn:#ffbe55;
  }
  *{box-sizing:border-box; font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif}
  body{margin:0; background:linear-gradient(180deg,#0b0c10,#101217 40%,#0f0f12)}
  .wrap{display:flex; gap:16px; padding:16px; max-width:980px; margin:0 auto; align-items:flex-start}
  .board{background:#0b0c10; border-radius:12px; padding:12px; box-shadow:0 10px 30px rgba(0,0,0,.35), inset 0 0 0 1px rgba(255,255,255,.06)}
  canvas{display:block; width:100%; height:auto; image-rendering:pixelated}
  .side{flex:1; display:grid; gap:12px}
  .card{background:var(--panel); color:var(--ink); border-radius:12px; padding:12px; box-shadow:inset 0 0 0 1px rgba(255,255,255,.06)}
  h1{color:var(--ink); font-size:20px; margin:0 0 4px}
  .meta{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:6px}
  .meta div{background:#1d1f27; padding:10px; border-radius:10px; text-align:center}
  .label{font-size:11px; color:var(--muted)}
  .value{font-size:18px; font-weight:700}
  .nextHold{display:flex; gap:12px}
  .mini{flex:1}
  .miniCanvas{width:100%; background:#0b0c10; border-radius:8px; aspect-ratio:1/1; display:block}
  .keys{font-size:12px; color:var(--muted); line-height:1.5}
  kbd{background:#1e2230; border:1px solid rgba(255,255,255,.08); border-bottom-width:2px; padding:2px 6px; border-radius:6px; color:#e9ecff}
  .row{display:flex; gap:6px; flex-wrap:wrap}
  .btns{display:none}
  .btn{flex:1; background:#1e2230; color:#e9ecff; border:none; border-radius:10px; padding:12px; font-weight:700}
  .btn:active{transform:translateY(1px)}
  .footer{color:var(--muted); font-size:11px; text-align:center; margin-top:4px}
  @media (max-width:900px){
    .wrap{flex-direction:column; padding:12px}
    .btns{display:grid; gap:8px; grid-template-columns:1fr 1fr 1fr}
    .board{order:1}
    .side{order:2}
  }
</style>
</head>
<body>
  <div class="wrap">
    <div class="board">
      <canvas id="game" width="300" height="600" aria-label="Tetris"></canvas>
      <div class="btns" aria-hidden="false" role="group" aria-label="Controls tàctils">
        <button class="btn" id="left">◀︎</button>
        <button class="btn" id="down">▼</button>
        <button class="btn" id="right">▶︎</button>
        <button class="btn" id="rotL">Gira ⤺</button>
        <button class="btn" id="hard">Hard ⤓</button>
        <button class="btn" id="rotR">Gira ⤼</button>
      </div>
      <div class="footer">P: pausa · R: reinicia</div>
    </div>

    <div class="side">
      <div class="card">
        <h1>Tetris</h1>
        <div class="meta">
          <div><div class="label">Puntuació</div><div id="score" class="value">0</div></div>
          <div><div class="label">Nivell</div><div id="level" class="value">1</div></div>
          <div><div class="label">Línies</div><div id="lines" class="value">0</div></div>
          <div><div class="label">Estat</div><div id="state" class="value">Jugant</div></div>
        </div>
      </div>

      <div class="card nextHold">
        <div class="mini">
          <div class="label">Següent</div>
          <canvas id="next" class="miniCanvas" width="120" height="120"></canvas>
        </div>
        <div class="mini">
          <div class="label">Hold (C)</div>
          <canvas id="hold" class="miniCanvas" width="120" height="120"></canvas>
        </div>
      </div>

      <div class="card">
        <div class="keys">
          <div class="row"><kbd>◀︎/▶︎</kbd> moure · <kbd>▼</kbd> baixar</div>
          <div class="row"><kbd>Z</kbd>/<kbd>X</kbd> girar · <kbd>Espai</kbd> hard drop</div>
          <div class="row"><kbd>C</kbd> hold · <kbd>P</kbd> pausa · <kbd>R</kbd> reinicia</div>
        </div>
      </div>
    </div>
  </div>

<script>
(() => {
  // --- Paràmetres bàsics ---
  const COLS = 10, ROWS = 20, CELL = 30;
  const CANVAS = document.getElementById('game');
  const CTX = CANVAS.getContext('2d');
  const NEXT = document.getElementById('next').getContext('2d');
  const HOLD = document.getElementById('hold').getContext('2d');

  CANVAS.width = COLS * CELL;
  CANVAS.height = ROWS * CELL;

  const UI = {
    score: document.getElementById('score'),
    level: document.getElementById('level'),
    lines: document.getElementById('lines'),
    state: document.getElementById('state'),
  };

  // Colors per peça (I,J,L,O,S,T,Z)
  const COLORS = {
    I:'#63e6ff', J:'#74c0fc', L:'#ffd43b', O:'#ffe066', S:'#8ce99a', T:'#b197fc', Z:'#ff8787', G:'#2b2f3a'
  };

  // Definició SRS (rotacions) amb matrius 4x4
  const SHAPES = {
    I: [
      [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],
      [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]],
      [[0,0,0,0],[0,0,0,0],[1,1,1,1],[0,0,0,0]],
      [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],
    ],
    O: [
      [[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],
      [[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],
      [[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],
      [[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],
    ],
    T: rotBase([[0,1,0],[1,1,1],[0,0,0]]),
    S: rotBase([[0,1,1],[1,1,0],[0,0,0]]),
    Z: rotBase([[1,1,0],[0,1,1],[0,0,0]]),
    J: rotBase([[1,0,0],[1,1,1],[0,0,0]]),
    L: rotBase([[0,0,1],[1,1,1],[0,0,0]]),
  };

  function rotBase(base3) {
    // Expandeix a 4x4 i genera 4 rotacions
    const pad4 = m => {
      const r = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
      for (let y=0;y<3;y++) for (let x=0;x<3;x++) r[y][x]=base3[y][x];
      return r;
    };
    const r0 = pad4(base3);
    const r1 = rotate(r0);
    const r2 = rotate(r1);
    const r3 = rotate(r2);
    return [r0,r1,r2,r3];
  }
  function rotate(m){
    const n = m.length, r = Array.from({length:n},()=>Array(n).fill(0));
    for(let y=0;y<n;y++) for(let x=0;x<n;x++) r[x][n-1-y]=m[y][x];
    return r;
  }

  // SRS kicks (simplificats). Font: orientació estàndard
  // Clau `${piece}${from}${to}`
  const KICKS = {
    // Peça I
    'I01':[[0,0],[-2,0],[1,0],[-2,-1],[1,2]],
    'I10':[[0,0],[2,0],[-1,0],[2,1],[-1,-2]],
    'I12':[[0,0],[-1,0],[2,0],[-1,2],[2,-1]],
    'I21':[[0,0],[1,0],[-2,0],[1,-2],[-2,1]],
    'I23':[[0,0],[2,0],[-1,0],[2,1],[-1,-2]],
    'I32':[[0,0],[-2,0],[1,0],[-2,-1],[1,2]],
    'I30':[[0,0],[1,0],[-2,0],[1,-2],[-2,1]],
    'I03':[[0,0],[-1,0],[2,0],[-1,2],[2,-1]],
    // Altres
    'X01':[[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],
    'X10':[[0,0],[1,0],[1,-1],[0,2],[1,2]],
    'X12':[[0,0],[1,0],[1,-1],[0,2],[1,2]],
    'X21':[[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],
    'X23':[[0,0],[1,0],[1,1],[0,-2],[1,-2]],
    'X32':[[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],
    'X30':[[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],
    'X03':[[0,0],[1,0],[1,1],[0,-2],[1,-2]],
  };

  // Estat del joc
  const state = {
    grid: Array.from({length:ROWS},()=>Array(COLS).fill(0)),
    cur: null,
    hold: null,
    canHold: true,
    bag: [],
    score: 0,
    lines: 0,
    level: 1,
    over:false,
    paused:false,
    dropMs: 1000, // base 1s
    last: 0,
    acc: 0
  };

  // Generador bossa 7
  function nextFromBag(){
    if(state.bag.length===0){
      state.bag = shuffle(['I','J','L','O','S','T','Z']);
    }
    return state.bag.pop();
  }
  function shuffle(a){
    for(let i=a.length-1;i>0;i--){
      const j=Math.floor(Math.random()*(i+1));
      [a,a[j]]=[a[j],a];
    }
    return a;
  }

  // Crear peça
  function spawn(type){
    const rot=0, shape=SHAPES[type][rot];
    // Posició inicial: x centrat, y - (filera visible)
    const x = Math.floor((COLS-4)/2);
    const y = -1; // permet sortir per sobre
    return {type, rot, x, y};
  }

  // Col·lisió
  function collides(p, gx=0, gy=0, rotDelta=0){
    const rot = (p.rot + rotDelta + 4) % 4;
    const m = SHAPES[p.type][rot];
    for(let y=0;y<4;y++){
      for(let x=0;x<4;x++){
        if(!m[y][x]) continue;
        const nx = p.x + x + gx;
        const ny = p.y + y + gy;
        if(nx<0 || nx>=COLS || ny>=ROWS) return true;
        if(ny>=0 && state.grid[ny][nx]) return true;
      }
    }
    return false;
  }

  // Fixar peça al tauler
  function merge(p){
    const m = SHAPES[p.type][p.rot];
    for(let y=0;y<4;y++){
      for(let x=0;x<4;x++){
        if(!m[y][x]) continue;
        const nx = p.x + x, ny = p.y + y;
        if(ny<0){ // toca sostre: game over
          state.over = true;
          UI.state.textContent = 'Game Over';
          return;
        }
        state.grid[ny][nx] = p.type;
      }
    }
  }

  // Neteja línies
  function clearLines(){
    let cleared = 0;
    for(let y=ROWS-1;y>=0;y--){
      if(state.grid[y].every(v=>v)){
        state.grid.splice(y,1);
        state.grid.unshift(Array(COLS).fill(0));
        cleared++;
        y++;
      }
    }
    if(cleared){
      state.lines += cleared;
      const pts = [0,100,300,500,800][cleared] * state.level;
      state.score += pts;
      // puja nivell cada 10 línies
      const newLevel = Math.floor(state.lines/10)+1;
      if(newLevel !== state.level){
        state.level = newLevel;
        state.dropMs = Math.max(60, 1000 - (state.level-1)*80); // més ràpid
      }
      updateUI();
    }
  }

  // Dibuix
  function drawCell(ctx,x,y,type){
    const color = COLORS[type] || COLORS.G;
    ctx.fillStyle = color;
    ctx.fillRect(x*CELL, y*CELL, CELL, CELL);
    // contorn suau
    ctx.fillStyle = 'rgba(255,255,255,0.06)';
    ctx.fillRect(x*CELL, y*CELL, CELL, 4);
    ctx.fillStyle = 'rgba(0,0,0,0.15)';
    ctx.fillRect(x*CELL, y*CELL+CELL-4, CELL, 4);
  }
  function draw(){
    // fons
    CTX.fillStyle = '#0b0c10';
    CTX.fillRect(0,0,CANVAS.width,CANVAS.height);

    // quadricula
    CTX.strokeStyle = 'rgba(255,255,255,0.06)';
    CTX.lineWidth = 1;
    for(let x=0;x<=COLS;x++){
      CTX.beginPath();
      CTX.moveTo(x*CELL,0); CTX.lineTo(x*CELL,ROWS*CELL); CTX.stroke();
    }
    for(let y=0;y<=ROWS;y++){
      CTX.beginPath();
      CTX.moveTo(0,y*CELL); CTX.lineTo(COLS*CELL,y*CELL); CTX.stroke();
    }

    // fantasme (ghost)
    if(state.cur){
      let gY = state.cur.y;
      while(!collides(state.cur,0,gY - state.cur.y + 1,0)) gY++;
      const m = SHAPES[state.cur.type][state.cur.rot];
      CTX.globalAlpha = 0.20;
      for(let y=0;y<4;y++) for(let x=0;x<4;x++){
        if(m[y][x]){
          const nx = state.cur.x + x, ny = gY + y;
          if(ny>=0) drawCell(CTX,nx,ny,'G');
        }
      }
      CTX.globalAlpha = 1;
    }

    // tauler
    for(let y=0;y<ROWS;y++){
      for(let x=0;x<COLS;x++){
        if(state.grid[y][x]) drawCell(CTX,x,y,state.grid[y][x]);
      }
    }

    // peça actual
    if(state.cur){
      const m = SHAPES[state.cur.type][state.cur.rot];
      for(let y=0;y<4;y++) for(let x=0;x<4;x++){
        if(m[y][x]){
          const nx = state.cur.x + x, ny = state.cur.y + y;
          if(ny>=0) drawCell(CTX,nx,ny,state.cur.type);
        }
      }
    }

    // overlays
    if(state.paused){
      overlay('Pausa');
    } else if(state.over){
      overlay('Game Over\nR per reiniciar');
    }
  }
  function overlay(text){
    CTX.fillStyle = 'rgba(0,0,0,0.5)';
    CTX.fillRect(0,0,CANVAS.width,CANVAS.height);
    CTX.fillStyle = '#e8e8ef';
    CTX.textAlign='center';
    CTX.textBaseline='middle';
    CTX.font = 'bold 28px system-ui, sans-serif';
    const lines = text.split('\n');
    lines.forEach((l,i)=>CTX.fillText(l, CANVAS.width/2, CANVAS.height/2 + i*34));
  }

  // Mini canvases (next/hold)
  function drawMini(ctx, pieceType){
    ctx.clearRect(0,0,120,120);
    if(!pieceType) return;
    const m = SHAPES[pieceType][0];
    // centrar
    const cells = [];
    for(let y=0;y<4;y++) for(let x=0;x<4;x++) if(m[y][x]) cells.push({x,y});
    const xs = cells.map(c=>c.x), ys=cells.map(c=>c.y);
    const minX=Math.min(...xs), maxX=Math.max(...xs), minY=Math.min(...ys), maxY=Math.max(...ys);
    const w = (maxX-minX+1), h = (maxY-minY+1);
    const size = 22;
    const offX = Math.floor((120 - w*size)/2);
    const offY = Math.floor((120 - h*size)/2);
    ctx.fillStyle = COLORS[pieceType];
    cells.forEach(c=>{
      const x = offX + (c.x-minX)*size;
      const y = offY + (c.y-minY)*size;
      ctx.fillRect(x,y,size,size);
      ctx.fillStyle = 'rgba(255,255,255,0.06)'; ctx.fillRect(x,y,size,3);
      ctx.fillStyle = 'rgba(0,0,0,0.15)'; ctx.fillRect(x,y+size-3,size,3);
      ctx.fillStyle = COLORS[pieceType];
    });
  }

  // UI
  function updateUI(){
    UI.score.textContent = state.score.toString();
    UI.level.textContent = state.level.toString();
    UI.lines.textContent = state.lines.toString();
    UI.state.textContent = state.over ? 'Game Over' : (state.paused ? 'Pausa' : 'Jugant');
    drawMini(NEXT, peekNext());
    drawMini(HOLD, state.hold?.type);
  }

  // Lògica moviment
  function hardDrop(){
    if(!state.cur) return;
    let dist = 0;
    while(!collides(state.cur,0,1,0)){ state.cur.y++; dist++; }
    state.score += dist*2; // punts per hard drop
    lockPiece();
  }
  function softDrop(){
    if(!state.cur) return;
    if(!collides(state.cur,0,1,0)){ state.cur.y++; state.score += 1; }
    else lockPiece();
    updateUI();
  }
  function move(dx){
    if(!state.cur) return;
    if(!collides(state.cur,dx,0,0)) state.cur.x += dx;
  }
  function rotateCW(){
    rotateGeneric(1);
  }
  function rotateCCW(){
    rotateGeneric(-1);
  }
  function rotateGeneric(dir){
    if(!state.cur) return;
    const from = state.cur.rot;
    const to = (from + (dir>0?1:3))%4;
    const key = (state.cur.type==='I'?'I':'X')+from+to;
    const kicks = KICKS[key] || [[0,0]];
    for(const [kx,ky] of kicks){
      if(!collides(state.cur, kx, ky, dir>0?1:-1)){
        state.cur.x += kx; state.cur.y += ky; state.cur.rot = to; return;
      }
    }
  }

  function lockPiece(){
    merge(state.cur);
    clearLines();
    state.cur = spawn(nextFromBag());
    state.canHold = true;
    if(collides(state.cur,0,0,0)){ // apareix i col·lisiona
      state.over = true;
    }
    updateUI();
  }

  function peekNext(){
    if(state.bag.length===0) return null;
    return state.bag[state.bag.length-1];
  }

  function hold(){
    if(!state.canHold || !state.cur) return;
    const temp = state.hold;
    state.hold = {type: state.cur.type};
    if(temp){
      state.cur = spawn(temp.type);
    }else{
      state.cur = spawn(nextFromBag());
    }
    state.cur.x = Math.floor((COLS-4)/2);
    state.cur.y = -1;
    state.cur.rot = 0;
    state.canHold = false;
    updateUI();
  }

  // Bucle principal
  function loop(ts){
    if(!state.last) state.last = ts;
    const dt = ts - state.last; state.last = ts;
    if(!state.paused && !state.over){
      state.acc += dt;
      if(state.acc >= state.dropMs){
        softDrop();
        state.acc = 0;
      }
    }
    draw();
    requestAnimationFrame(loop);
  }

  // Reinicia joc
  function reset(){
    state.grid = Array.from({length:ROWS},()=>Array(COLS).fill(0));
    state.cur = spawn(nextFromBag());
    state.hold = null;
    state.canHold = true;
    state.score = 0; state.lines = 0; state.level = 1;
    state.dropMs = 1000; state.over = false; state.paused=false;
    state.last = 0; state.acc = 0;
    updateUI();
  }

  // Controls teclat
  window.addEventListener('keydown', (e)=>{
    if(state.over && e.key.toLowerCase()!=='r') return;
    switch(e.key){
      case 'ArrowLeft': move(-1); break;
      case 'ArrowRight': move(1); break;
      case 'ArrowDown': softDrop(); break;
      case ' ': e.preventDefault(); hardDrop(); break;
      case 'z': case 'Z': rotateCCW(); break;
      case 'x': case 'X': rotateCW(); break;
      case 'c': case 'C': hold(); break;
      case 'p': case 'P': state.paused = !state.paused; updateUI(); break;
      case 'r': case 'R': reset(); break;
    }
  });

  // Controls tàctils
  const btn = id => document.getElementById(id);
  const tap = (el, fn) => { el.addEventListener('click', fn); el.addEventListener('touchstart', (e)=>{e.preventDefault(); fn();},{passive:false}); };
  tap(btn('left'), ()=>move(-1));
  tap(btn('right'), ()=>move(1));
  tap(btn('down'), ()=>softDrop());
  tap(btn('rotL'), ()=>rotateCCW());
  tap(btn('rotR'), ()=>rotateCW());
  tap(btn('hard'), ()=>hardDrop());

  // “Swipe” simple al canvas (moure/girar)
  let touchStart=null;
  CANVAS.addEventListener('touchstart', (e)=>{ if(e.touches.length===1){ touchStart = {x:e.touches[0].clientX, y:e.touches[0].clientY, t:performance.now()}; }});
  CANVAS.addEventListener('touchmove', (e)=>{
    if(!touchStart || e.touches.length!==1) return;
    const dx = e.touches[0].clientX - touchStart.x;
    const dy = e.touches[0].clientY - touchStart.y;
    if(Math.abs(dx) > 24 && Math.abs(dx) > Math.abs(dy)){
      move(dx>0?1:-1);
      touchStart.x = e.touches[0].clientX;
    } else if(dy > 24){
      softDrop();
      touchStart.y = e.touches[0].clientY;
    }
  }, {passive:true});
  CANVAS.addEventListener('touchend', (e)=>{
    if(!touchStart) return;
    const dt = performance.now() - touchStart.t;
    if(dt<180) rotateCW(); // tap curt = gir
    touchStart=null;
  });

  // Inicialització
  // Prepara bossa inicial amb almenys una peça per "Següent"
  state.bag = shuffle(['I','J','L','O','S','T','Z']);
  state.cur = spawn(nextFromBag());
  updateUI();
  requestAnimationFrame(loop);
})();
</script>
</body>
</html>





 






UN CATXÉ DE 100-TEAM
 

Additional Hints ()

sbeng n yn cnerg

Decryption Key

A|B|C|D|E|F|G|H|I|J|K|L|M
-------------------------
N|O|P|Q|R|S|T|U|V|W|X|Y|Z

(letter above equals below, and vice versa)

Advertising with Us