Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Beispiel:Fliegen fangen.html
Aus SELFHTML-Wiki
<!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;
}
#spielfeld {
aspect-ratio: 1 / 1;
width: min(99vw, calc(99vh - 5rem));
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;
}
dialog {
margin: 30vh auto;
}
progress {
margin-left: 10%;
width: 80%;
}
}
</style>
<script type="module">
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(`
<h2>Geschafft</h2>
<p>${maxAnzahlFliegen} Fliegen in ${Math.round((Date.now()-startZeit)/100)/10}s gefangen<br>und ${daneben} mal nicht getroffen.</p>
`);
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(`
<h2>Nicht geschafft</h2>
<p>Nur ${maxAnzahlFliegen-anzahlFliegen} von ${maxAnzahlFliegen} Fliegen in ${maxZeit/1000}s gefangen.</p>
`);
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(`<p>Los gehts</p>`);
</script>
</head>
<body>
<h1>Fliegen fangen</h1>
<div id="spielfeld">
<progress value="1" min="0" max="1"></progress>
<dialog id="info">
<div></div>
<p><button>Nächstes Spiel</button></p>
</dialog>
</div>
</body>
</html>