Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Friday, January 21, 2022

A simple 3d world in ~200 lines

Controls: click and drag to look around, and click on a location to move to it!

The main technique here is ray-marching signed distance fields, as pioneered / popularized by the incredible Inigo Quilez.

Monday, November 6, 2017

Metaballs in ~100 lines!


ThreeJS is pretty neat!

Saturday, June 24, 2017

3D Breakout in ~120 lines

Controls are WASD; game appears after the jump!

Thursday, June 15, 2017

Sunday, June 11, 2017

Tetris in <100 lines of code

Controls: W, A, S, D

0
<script>
var piece, rows = [], delay = 500, key = 0; 
onkeydown = e => key = e.key;
document.body.onload = () => (
 cvs.style.width = "100px", cvs.style.height = "300px",
 piece = makep(), frame(), setTimeout(step, delay));

// respond to player input, draw the board and piece
function frame() {
 move(({w: p => p.r = (p.r+1)%4, s: p => p.y--,
  a: p => p.x--, d: p => p.x++})[key] || (p => p));
 key = 0;
 cvs.getContext("2d").clearRect(0, 0, cvs.width, cvs.height);
 var px = (x, y) => cvs.getContext("2d").fillRect(x, cvs.height-y-1, 1, 1);
 rows.map((r, y) => Object.keys(r).map(x => px(+x, y)));
 eachblock(piece, px);
 if (delay > 0) delay -= .01;
 requestAnimationFrame(frame);
}

// try to move the piece down, clear rows and/or end the game if can't
function step() {
 setTimeout(step, delay);
 if (move(p => p.y--)) return; 
 eachblock(piece, (x, y) => (rows[y] = rows[y] || {}, rows[y][x] = 1));
 score.innerHTML = parseInt(score.innerHTML) + rows.length - 
  (rows = rows.filter(r => Object.keys(r).length < cvs.width)).length;
 if (rows.length >= cvs.height) score.innerHTML += " -- GAME OVER";
 piece = makep();
}

function move(f) {
 var newp = Object.assign({}, piece);
 f(newp);
 if (legal(newp)) {Object.assign(piece, newp); return true}
 return false;
}

var makep = () => ({y: cvs.height-1, x: cvs.width/2 -1|0, r: 0,
 blocks: ["1111", "11\n 11", " 11\n11", "11\n11",
  "111\n1", "111\n 1", "111\n  1"][Math.random()*7|0]});

function eachblock(p, f) {
 var results = [], [x, y] = [p.x, p.y];
 var r = p.blocks == "11\n11"? 0 : p.r;
 var [nextblock, nextline] = [
  [() => x++, () => {y--; x = p.x}], [() => y--, () => {x--; y = p.y}],
  [() => x--, () => {y++; x = p.x}], [() => y++, () => {x++; y = p.y}]][r];
 p.blocks.split("").map(c => {
  if (c == "\n") {nextline(); return}
  if (c == "1") results.push(f(+x + [0,1,2,0][r], +y + [0,0,-1,-1][r]));
  nextblock()});
 return results;
}

var legal = p => eachblock(p, (x, y) => x >= 0 && x < cvs.width && y >= 0
 && !(rows[y] || {})[x]).filter(x=>x).length == 4;
</script>
<canvas id="cvs" width="10" height = "30"
style = "image-rendering:pixelated; border: 1px solid black;">
</canvas> <div id="score">0</div>