Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Beispiel:Fliegen fangen.html
<!DOCTYPE html> <html lang="de"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fliegen fangen</title> <style> body { margin: 0; padding: 0; box-sizing: border-box; } h1 { margin: 0.5rem 2rem 2.5rem 2rem; font-size: 2rem; line-height: 1; } :root{ --breite: min(99vw, calc(99vh - 5rem)); --fliege: calc(var(--breite)/10); } #spielfeld { aspect-ratio: 1 / 1; width: var(--breite); margin: auto; position: relative; cursor: crosshair; border: thin solid black; user-select: none; img { position: absolute; transition: top 0.1s linear, left 0.1s linear, transform 0.1s linear; max-width: var(--fliege); } dialog { margin: 30vh auto; } progress { margin-left: 10%; width: 80%; } } </style> <script type="module"> document.addEventListener('DOMContentLoaded', function () {
let anzahlFliegen, maxAnzahlFliegen = 10, alleFliegen = []; let fliege_passiv = "https://wiki.selfhtml.org/images/1/17/Fliege_zuckt.svg"; let fliege_active = "https://wiki.selfhtml.org/images/b/b2/Fliege_krabbelt.svg"; let maxZeit = 15000, startZeit; let parky = -5; let playInterval; let daneben;
const spielFeld = document.querySelector("#spielfeld"); spielFeld.scrollIntoView(); spielFeld.addEventListener("pointerdown", pointerdownevent => { if(pointerdownevent.target.active) { anzahlFliegen--; pointerdownevent.target.active = false; pointerdownevent.target.src = fliege_passiv; moveFly(pointerdownevent.target, (anzahlFliegen+.5)*100/maxAnzahlFliegen, parky, 1+Math.random()); if(anzahlFliegen == 0) { showInfo(`
Geschafft
${maxAnzahlFliegen} Fliegen in ${Math.round((Date.now()-startZeit)/100)/10}s gefangen
und ${daneben} mal nicht getroffen.
`); clearInterval(playInterval); } } else { daneben++; } }); // pointerdownevent
const info = spielFeld.querySelector("dialog"); const infoOut = info.querySelector("div"); info.querySelector("button").addEventListener("click", play);
const progress = spielFeld.querySelector("progress");
function showInfo(infoHTML) { infoOut.innerHTML = infoHTML; info.showModal(); //info.show(); }
function hideInfo() { info.close(); }
function makeFlys() { for(let i=0; i<maxAnzahlFliegen; i++) alleFliegen.push(makeFly((i+.5)*100/maxAnzahlFliegen, parky, 1+Math.random())); } // makeFlys
function makeFly(x, y, phi) { let fliege = document.createElement("img"); fliege.src = fliege_passiv; fliege.active = false; spielFeld.appendChild(fliege); moveFly(fliege, x, y, phi); return fliege; } // makeFly
function moveFly(fliege, x, y, phi) { fliege.style.left = `${x}%`; fliege.style.top = `${y}%`; fliege.style.transform = `translate(-50%,-50%) rotate(${phi}rad)`; fliege.posx = x; fliege.posy = y; fliege.phi = phi; } // moveFly
function randomMoveFly(fliege) { let x = fliege.posx, y = fliege.posy, phi = fliege.phi; if(x<5 | x>95 | y<5 | y>95) { phi = Math.atan2(50-y,50-x) + .2*(Math.random()-0.5); } else { phi += Math.random()-0.5; } let dx = Math.cos(phi); let dy = Math.sin(phi); x += dx; y += dy; moveFly(fliege, x, y, phi); } // randomMoveFly
function move() { progress.value = 1 - (Date.now()-startZeit)/maxZeit; if((Date.now()-startZeit) < maxZeit) { alleFliegen.filter(fliege=>fliege.active).forEach(randomMoveFly); } else { clearInterval(playInterval); showInfo(`
Nicht geschafft
Nur ${maxAnzahlFliegen-anzahlFliegen} von ${maxAnzahlFliegen} Fliegen in ${maxZeit/1000}s gefangen.
`); alleFliegen.filter(fliege=>fliege.active).forEach((fliege) => { fliege.src = fliege_passiv; fliege.active = false; }); } } // move
function play() { hideInfo(); progress.value = 1; daneben = 0; anzahlFliegen = maxAnzahlFliegen; alleFliegen.forEach((fliege) => { let x = 50 + 90*(Math.random()-0.5); let y = 50 + 90*(Math.random()-0.5); let phi = 2*Math.PI*Math.random(); fliege.src = fliege_active; fliege.active = true; moveFly(fliege, x, y, phi); }); startZeit = Date.now(); playInterval = setInterval(move, 100); } // play
makeFlys();
showInfo(`Los gehts
`);}); </script>
</head> <body>
Fliegen fangen
<progress value="1" min="0" max="1"></progress> <dialog id="info">
<button>Nächstes Spiel</button>
</dialog>
</body> </html>