JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<canvas id=main width="300" height="300"></canvas>
CSS
canvas{
background: #38c;
}
JavaScript
function vec4(w, x, y, z) {
return {w, x, y, z};
}
const blocks = [
vec4(0, 0, 0, 0),
vec4(0, 1, 0, 1),
vec4(1, 0, 0, 0),
vec4(2, 0, 0, 0),
];
const playerPos = vec4(0, 0, 0, 1);
function render() {
const canvas = document.getElementById('main');
const ctx = canvas.getContext('2d');
// 6 faces
const project = ({w, x, y, z}) => {
return [
125 + 50 * (-0.1 * w + x + 0.1 * y),
125 + 50 * (z),
];
};
const projZ = ({w, x, y, z}) => w + y;
const sum = (a, ...rest) => {
const c = {...a};
for(const b of rest) {
c.w += b.w;
c.x += b.x;
c.y += b.y;
c.z += b.z;
}
return c;
}
const square = (start, delta) => {
// delta doesn't include z, assume it's 1
return [
start,
sum(start, delta),
sum(start, delta, vec4(0, 0, 0, 1)),
sum(start, vec4(0, 0, 0, 1)),
];
};
const makeTess = ({w, x, y, z}) => {
// returns a series of faces, where each face is a list
// of 4 verts the define the loop
return [
[0, 0],
[0, 1],
[1, 0],
[1, 1],
].flatMap(([a, b]) => [
square( // w: 0 -> 1
vec4(w, x + a, y + b, z),
vec4(1, 0, 0, 0),
),
square( // x: 0 -> 1
vec4(w + a, x, y + b, z),
vec4(0, 1, 0, 0),
),
square( // y: 0 -> 1
vec4(w + a, x + b, y, z),
vec4(0, 0, 1, 0),
),
]);
}
const scale = (v, s) => vec4(v.w * s, v.x * s, v.y * s, v.z * s);
const faceCenter = face => scale(sum(...face), 0.25);
function drawTess(t) {
const faces = [...t];
faces.sort((a, b) => projZ(faceCenter(a)) - projZ(faceCenter(b)));
for(const face of faces) {
ctx.beginPath();
for(const point of [...face, face[0]]) {
const screenLocation = project(point);
ctx.lineTo(...screenLocation);
//...