<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Mê Cung Kĩ Thuật Số</title><style>body{background-color:#050505;color:#0ff;font-family:'Segoe UI',sans-serif;margin:0;overflow:hidden;position:relative;height:100vh;}#TextMode{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;}</style></head><body><canvas id="TextMode" width="1920" height="276"></canvas><script>
const canvas = document.getElementById('TextMode'),
ctx = canvas.getContext('2d');
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
let frameCount = 0;
let speedDivider = 2;
let Size = 5;
var NAMES = {
black: '#000000',
red: '#cd0000',
green: '#00cd00',
yellow: '#cdcd00',
blue: '#268bd2',
magenta: '#cd00cd',
cyan: '#00cdcd',
white: '#e5e5e5',
gray: '#808080',
grey: '#808080',
brightred: '#ff0000',
brightgreen: '#00ff00',
brightyellow: '#ffff00',
brightblue: '#5c5cff',
brightmagenta: '#ff00ff',
brightcyan: '#00ffff',
brightwhite: '#ffffff'
};
var NAME_ORDER = [
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
'gray', 'brightred', 'brightgreen', 'brightyellow', 'brightblue',
'brightmagenta', 'brightcyan', 'brightwhite'
];
var CUBE_LEVELS = [0, 95, 135, 175, 215, 255];
function toHex(n) {
var h = Math.max(0, Math.min(255, Math.round(n))).toString(16);
return h.length === 1 ? '0' + h : h;
}
function indexToHex(index) {
var i, r, g, b, level;
if (index < 16) {
return NAMES[NAME_ORDER[index]];
}
if (index < 232) {
i = index - 16;
r = CUBE_LEVELS[Math.floor(i / 36) % 6];
g = CUBE_LEVELS[Math.floor(i / 6) % 6];
b = CUBE_LEVELS[i % 6];
return '#' + toHex(r) + toHex(g) + toHex(b);
}
level = 8 + (index - 232) * 10;
return '#' + toHex(level) + toHex(level) + toHex(level);
}
function isIndex(value) {
return typeof value === 'number' && isFinite(value) && value >= 0 && value <= 255;
}
function resolveColor(value) {
if (value === undefined || value === null || value === '' || value === 'default') {
return null;
}
if (isIndex(value)) {
return indexToHex(Math.floor(value));
}
if (Object.prototype.hasOwnProperty.call(NAMES, value)) {
return NAMES[value];
}
return null;
}
let Z=1;
const R=()=>(Z=Z*75%65537)/65537,
W=80,
H=50,
TH=25,
P=new Uint8Array(768),
S=[0,95,135,175,215,255],
C16=[
[0,0,0],
[128,0,0],
[0,128,0],
[128,128,0],
[0,0,128],
[128,0,128],
[0,128,128],
[192,192,192],
[128,128,128],
[255,0,0],
[0,255,0],
[255,255,0],
[0,0,255],
[255,0,255],
[0,255,255],
[255,255,255]
];
for(let i=0;i<16;i++){
P[i*3]=C16[i][0];
P[i*3+1]=C16[i][1];
P[i*3+2]=C16[i][2];
}
let pi=16;
for(let r=0;r<6;r++)
for(let g=0;g<6;g++)
for(let b=0;b<6;b++){
P[pi*3]=S[r];
P[pi*3+1]=S[g];
P[pi*3+2]=S[b];
pi++;
}
for(let i=0;i<24;i++){
const v=8+i*10;
P[pi*3]=v;
P[pi*3+1]=v;
P[pi*3+2]=v;
pi++;
}
const L=new Uint8Array(32768);
for(let r5=0;r5<32;r5++){
const r=r5*255/31;
for(let g5=0;g5<32;g5++){
const g=g5*255/31;
for(let b5=0;b5<32;b5++){
const b=b5*255/31;
let bd=1e9,
bc=0;
for(let i=0;i<256;i++){
const dr=r-P[i*3],
dg=g-P[i*3+1],
db=b-P[i*3+2],
d=dr*dr*.3+dg*dg*.59+db*db*.11;
if(d<bd){
bd=d;
bc=i;
}
}
L[(r5<<10)|(g5<<5)|b5]=bc;
}
}
}
const WT=new Uint8Array(6*256*3),
FT=new Uint8Array(768),
CT=new Uint8Array(768);
for(let y=0;y<16;y++)
for(let x=0;x<16;x++){
const i=(y*16+x)*3;
WT[i]=(x===0||y===0||((x^y)&4)===0)?0:10;
WT[i+1]=(x===0||y===0||((x^y)&4)===0)?210:25;
WT[i+2]=(x===0||y===0||((x^y)&4)===0)?255:60;
const m1=(y%8===0)||(y<8?x%8===0:(x+4)%8===0),
g1=((x*37+y*17)&15);
WT[768+i]=m1?40:170+g1*4;
WT[768+i+1]=m1?20:45+g1;
WT[768+i+2]=m1?15:25;
const ms=Math.sin(x*.5)*Math.cos(y*.5)>0.1;
WT[1536+i]=ms?30:10;WT[1536+i+1]=ms?230:70;
WT[1536+i+2]=ms?70:30;
const st=(y%4===0)||(x===7);
WT[2304+i]=st?255:35;
WT[2304+i+1]=st?10:10;
WT[2304+i+2]=st?170:65;
const dm=Math.abs(x-7.5)+Math.abs(y-7.5)<5;
WT[3072+i]=dm?250:20;
WT[3072+i+1]=dm?190:20;
WT[3072+i+2]=dm?40:25;
const dg=((x+y)&7)<4;
WT[3840+i]=dg?240:35;
WT[3840+i+1]=dg?200:35;
WT[3840+i+2]=dg?10:35;
const tb=(x===0||y===0||x===15||y===15),
chk=((x^y)&4)===0;
FT[i]=tb?180:chk?120:70;
FT[i+1]=tb?210:chk?140:90;
FT[i+2]=tb?255:chk?180:120;
const sr=((x*13+y*71)%29===0),
cgrid=(x===7||y===7);
CT[i]=sr?255:cgrid?190:40;
CT[i+1]=sr?230:cgrid?60:15;
CT[i+2]=sr?255:cgrid?240:70
}
const MW=31,
CW=15,
MAP = [new Uint8Array(MW).fill(1)];
let eSets=new Int32Array(CW),
nextSet=1;
const genRow=()=>{
const cr=new Uint8Array(MW),
wr=new Uint8Array(MW);
cr[0]=cr[MW-1]=wr[0]=wr[MW-1]=1;
for(let c=0;c<CW;c++)
if(!eSets[c])
eSets[c]=nextSet++;
for(let c=0;c<CW;c++)
cr[c*2+1]=0;
for(let c=0;c<CW-1;c++){
if(eSets[c]===eSets[c+1]||R()>.5){
cr[c*2+2]=(R()*6|0)+1;
}else{
const oldS=eSets[c+1],
newS=eSets[c];
for(let k=0;k<CW;k++)
if(eSets[k]===oldS)eSets[k]=newS;
cr[c*2+2]=0;
}
}
const nextESets=new Int32Array(CW);
for(let c=0;c<CW;c++){
wr[c*2]=(R()*6|0)+1;
const s=eSets[c];
let hasDown=0;
for(let k=0;k<CW;k++)
if(eSets[k]===s&&nextESets[k])
hasDown=1;
if(!hasDown||R()>.4){
wr[c*2+1]=0;nextESets[c]=s;
}else{
wr[c*2+1]=(R()*6|0)+1;
}
}
wr[MW-1]=1;
eSets=nextESets;
MAP.push(cr);
MAP.push(wr);
};
const getTile=(x,y)=>{if(x<0||x>=MW||y<0)return 1;while(y>=MAP.length)genRow();return MAP[y][x]};
// Data?
let px=1.5,
py=1.5,
cTx=1,
cTy=1,
cdX=0,
cdY=1,
ang=Math.PI/2,
tAng=Math.PI/2,
phase=0,
spd=4.2;
const rB=new Float32Array(4000),
gB=new Float32Array(4000),
bB=new Float32Array(4000),
oI=new Uint8Array(4000);
const step=()=>{
const dt=.033;
const progress=(px-(cTx+.5))*cdX+(py-(cTy+.5))*cdY;
if(progress>=.92){
cTx+=cdX;
cTy+=cdY;
px=cTx+.5;
py=cTy+.5;
const dirs=[[cdX,cdY,3],[-cdY,cdX,2],[cdY,-cdX,2]];
let best=null,
bSc=-1e9;
for(let i=0;i<3;i++){
const d=dirs[i];
if(getTile(cTx+d[0],cTy+d[1])===0){
const sc=d[1]*5+d[2]+R();if(sc>bSc){bSc=sc;best=d}
}
}if(best){cdX=best[0];cdY=best[1]}else{cdX=-cdX;cdY=-cdY}tAng=Math.atan2(cdY,cdX)
}
let dAng=tAng-ang;
while(dAng<-Math.PI)
dAng+=Math.PI*2;
while(dAng>Math.PI)
dAng-=Math.PI*2;
ang+=dAng*Math.min(1,14*dt);
px+=cdX*spd*dt;
py+=cdY*spd*dt;
phase+=dt*(spd*3.5);
const bobY=Math.sin(phase)*.14,
bobX=Math.cos(phase*.5)*.07,
kick=Math.max(0,-Math.sin(phase))*.05,
jx=(R()-.5)*.015,
jy=(R()-.5)*.015,
cAng=ang+bobX*.3+jx,
dx=Math.cos(cAng),
dy=Math.sin(cAng),
plX=-dy*.66,
plY=dx*.66,
pitch=(bobY+kick+jy)*50|0,
hor=25+pitch;
for(let x=0;x<W;x++){
const cx=2*x/W-1,rx=dx+plX*cx,ry=dy+plY*cx;let mx=px|0,my=py|0;const ddx=Math.abs(1/(rx||1e-6)),ddy=Math.abs(1/(ry||1e-6));let sx=rx<0?-1:1,sy=ry<0?-1:1;let sdx=rx<0?(px-mx)*ddx:(mx+1-px)*ddx,sdy=ry<0?(py-my)*ddy:(my+1-py)*ddy;let hit=0,side=0,wT=0;for(let s=0;s<32;s++){if(sdx<sdy){sdx+=ddx;mx+=sx;side=0}else{sdy+=ddy;my+=sy;side=1}wT=getTile(mx,my);if(wT>0){hit=1;break}}let dist=hit?(side===0?(mx-px+(1-sx)/2)/rx:(my-py+(1-sy)/2)/ry):32;if(dist<.1)dist=.1;const lh=hit?(H/dist|0):0,dS=hit?Math.max(0,hor-(lh>>1)|0):hor,dE=hit?Math.min(H-1,hor+(lh>>1)|0):hor-1;let wx=side===0?py+dist*ry:px+dist*rx;wx-=Math.floor(wx);let tx=wx*16|0;if((side===0&&rx>0)||(side===1&&ry<0))tx=15-tx;const tb=(((wT-1)%6+6)%6)*768,ws=side===1?.75:1,wf=1/(1+dist*.22);const cEnd=Math.min(dS,Math.min(H,hor|0));for(let y=0;y<cEnd;y++){const p=hor-y,rd=25/(p||1e-4),fx=px+rd*rx,fy=py+rd*ry,u=fx*4&15,v=fy*4&15,ti=(v*16+u)*3,f=1/(1+rd*.18),idx=y*W+x;rB[idx]=CT[ti]*f+15*(1-f);gB[idx]=CT[ti+1]*f+10*(1-f);bB[idx]=CT[ti+2]*f+25*(1-f)}for(let y=dS;y<=dE;y++){const d=(y-hor)*256,ty=Math.max(0,Math.min(15,((d*16)/lh|0)/256+8|0)),ti=tb+(ty*16+tx)*3,idx=y*W+x;rB[idx]=WT[ti]*ws*wf+8*(1-wf);gB[idx]=WT[ti+1]*ws*wf+6*(1-wf);bB[idx]=WT[ti+2]*ws*wf+18*(1-wf)}const fStart=Math.max(dE+1,Math.max(0,hor|0));for(let y=fStart;y<H;y++){const p=y-hor,rd=25/(p||1e-4),fx=px+rd*rx,fy=py+rd*ry,u=fx*4&15,v=fy*4&15,ti=(v*16+u)*3,f=1/(1+rd*.18),idx=y*W+x;rB[idx]=FT[ti]*f+25*(1-f);gB[idx]=FT[ti+1]*f+35*(1-f);bB[idx]=FT[ti+2]*f+55*(1-f)}
}
for(let y=0;y<H;y++){
const yw=y*W,nyw=(y+1)*W;
for(let x=0;x<W;x++){
const i=yw+x;
let r=rB[i];
if(r<0)
r=0;
else if(r>255)
r=255;
let g=gB[i];
if(g<0)
g=0;
else if(g>255)
g=255;
let b=bB[i];
if(b<0)
b=0;
else if(b>255)
b=255;
const pal=L[((r*.1215686+.5|0)<<10)|((g*.1215686+.5|0)<<5)|(b*.1215686+.5|0)];
oI[i]=pal;
const qr=P[pal*3],
qg=P[pal*3+1],
qb=P[pal*3+2],
er=r-qr,
eg=g-qg,
eb=b-qb;
if(x+1<W){
const e=i+1;
rB[e]+=er*.4375;
gB[e]+=eg*.4375;
bB[e]+=eb*.4375;
}
if(y+1<H){
if(x>0){
const e=nyw+x-1;
rB[e]+=er*.1875;
gB[e]+=eg*.1875;
bB[e]+=eb*.1875;
}
{
const e=nyw+x;
rB[e]+=er*.3125;
gB[e]+=eg*.3125;
bB[e]+=eb*.3125;
}
if(x+1<W){
const e=nyw+x+1;
rB[e]+=er*.0625;
gB[e]+=eg*.0625;
bB[e]+=eb*.0625;
}
}
}
}
};
function Draw() {
requestAnimationFrame(Draw);
frameCount++;
if (frameCount%speedDivider !== 0) return;
step();
for(let y = 0; y < TH; y++) {
const tr = 2 * y * W,
br = (2 * y + 1) * W;
for (let x = 0; x < W; x++) {
ctx.fillStyle = resolveColor(oI[tr + x]);
ctx.fillRect(x * Size, y * 2 * Size, Size, Size);
ctx.fillStyle = resolveColor(oI[br + x]);
ctx.fillRect(x * Size, (y * 2 + 1) * Size, Size, Size);
}
}
}
Draw();
</script></body></html>
By: @probablythebestusernameever
Original: https://www.bytebeat.cloud/post/719490ec-7f5e-412e-adde-55f5b5331217