Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CraftJS - Minecraft Clone</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #000; overflow: hidden; font-family: monospace; } canvas#c { display: block; } #overlay { position: fixed; inset: 0; pointer-events: none; z-index: 5; } #crosshair { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 30px; font-weight: 100; text-shadow: 1px 1px 2px #000, -1px -1px 2px #000; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; line-height: 1; } #hud { position: absolute; top: 8px; left: 8px; background: rgba(0,0,0,0.6); color: #fff; padding: 8px 12px; border-radius: 4px; font-size: 12px; line-height: 2; } #hud b { color: #7dd; } #xyz { position: absolute; top: 8px; right: 8px; background: rgba(0,0,0,0.6); color: #fff; padding: 8px 12px; border-radius: 4px; font-size: 12px; line-height: 2; } #hotbar { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); display: flex; gap: 3px; } .hslot { width: 50px; height: 50px; border: 2px solid #666; background: rgba(0,0,0,0.65); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; } .hslot.sel { border: 2px solid #fff; box-shadow: 0 0 6px rgba(255,255,255,0.5); } .hslot canvas { image-rendering: pixelated; } .hslot span { font-size: 7px; color: #bbb; text-transform: uppercase; } #breakbar { position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%); width: 140px; height: 7px; background: rgba(0,0,0,0.5); border-radius: 4px; overflow: hidden; display: none; } #breakfill { height: 100%; background: #e06020; width: 0; } #startscreen { position: fixed; inset: 0; background: linear-gradient(160deg, #1a3a5c 0%, #0d1f33 100%); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 100; color: #fff; } #startscreen h1 { font-size: 52px; font-weight: 900; color: #5cf; letter-spacing: 6px; text-shadow: 0 0 40px rgba(85,204,255,0.4); margin-bottom: 4px; } #startscreen p { color: #89a; margin-bottom: 36px; font-size: 14px; letter-spacing: 2px; } #playBtn { background: #2a7a2a; color: #fff; border: none; padding: 14px 44px; font: 16px monospace; letter-spacing: 3px; cursor: pointer; border-radius: 3px; } #playBtn:hover { background: #3a9a3a; } #loading { display: none; color: #7dd; font-size: 14px; margin-top: 16px; letter-spacing: 2px; } </style> </head> <body> <canvas id="c"></canvas> <div id="overlay"> <div id="crosshair">+</div> <div id="hud"> <b>Move:</b> WASD &nbsp; <b>Jump:</b> Space<br> <b>Sprint:</b> Shift &nbsp; <b>Look:</b> Mouse<br> <b>Break:</b> Hold LMB &nbsp; <b>Place:</b> RMB<br> <b>Block:</b> Scroll / 1\u20138 </div> <div id="xyz"></div> <div id="hotbar"></div> <div id="breakbar"><div id="breakfill"></div></div> </div> <div id="startscreen"> <h1>CRAFTJS</h1> <p>Three.js Minecraft Clone</p> <button id="playBtn">PLAY</button> <div id="loading">Generating world...</div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // \u2500\u2500 BLOCK IDS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var B = { AIR:0, GRASS:1, DIRT:2, STONE:3, SAND:4, WOOD:5, LEAVES:6, PLANKS:7, COBBLE:8 }; var BREAK_TIME = {1:0.6, 2:0.5, 3:1.4, 4:0.5, 5:1.0, 6:0.3, 7:0.8, 8:1.3}; // \u2500\u2500 TEXTURES \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 function pxr(x, y, seed) { var s = Math.sin(x*73.1 + y*179.3 + seed*251.7) * 43758.545; return s - Math.floor(s); } function mkTex(fn) { var cv = document.createElement('canvas'); cv.width = cv.height = 16; var ctx = cv.getContext('2d'); fn(ctx); var t = new THREE.CanvasTexture(cv); t.magFilter = THREE.NearestFilter; t.minFilter = THREE.NearestFilter; return { tex: t, cv: cv }; } var TX = {}; TX.grass_top = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,1), g=(80+n*50)|0; ctx.fillStyle='rgb('+(20+n*10|0)+','+g+','+(15+n*8|0)+')'; ctx.fillRect(x,y,1,1); } }); TX.dirt = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,2), v=(95+n*45)|0; ctx.fillStyle='rgb('+(v*.58|0)+','+(v*.38|0)+','+(v*.22|0)+')'; ctx.fillRect(x,y,1,1); } }); TX.grass_side = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,2), v=(95+n*45)|0; ctx.fillStyle='rgb('+(v*.58|0)+','+(v*.38|0)+','+(v*.22|0)+')'; ctx.fillRect(x,y,1,1); } for (var y=0;y<3;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,7), g=(75+n*40)|0; ctx.fillStyle='rgb(20,'+g+',15)'; ctx.fillRect(x,y,1,1); } }); TX.stone = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,3), v=(110+n*55)|0; ctx.fillStyle='rgb('+v+','+v+','+v+')'; ctx.fillRect(x,y,1,1); } ctx.fillStyle='rgba(70,70,70,0.45)'; [[1,3,7,1],[9,6,5,1],[3,10,6,1],[11,1,4,1]].forEach(function(a){ctx.fillRect(a[0],a[1],a[2],a[3]);}); [[1,3,1,7],[9,6,1,5],[3,10,1,4]].forEach(function(a){ctx.fillRect(a[0],a[1],a[2],a[3]);}); }); TX.sand = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,4), v=(200+n*35)|0; ctx.fillStyle='rgb('+v+','+(v*.9|0)+','+(v*.5|0)+')'; ctx.fillRect(x,y,1,1); } }); TX.wood = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,5); var ring=Math.sin((x-8)*.5+(y-8)*.15)*.5+.5; var v=(80+ring*35+n*15)|0; ctx.fillStyle='rgb('+(v*.72|0)+','+(v*.52|0)+','+(v*.28|0)+')'; ctx.fillRect(x,y,1,1); } ctx.fillStyle='rgba(30,15,0,0.3)'; for (var y=0;y<16;y+=3) ctx.fillRect(0,y,16,1); }); TX.leaves = mkTex(function(ctx) { ctx.clearRect(0,0,16,16); for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,6); if (n>0.18) { var g=(65+n*65)|0; ctx.fillStyle='rgba(20,'+g+',15,0.95)'; ctx.fillRect(x,y,1,1); } } }); TX.planks = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,7), row=Math.floor(y/4)|0; var v=(145+n*25+row%2*12)|0; ctx.fillStyle='rgb('+(v*.7|0)+','+(v*.55|0)+','+(v*.3|0)+')'; ctx.fillRect(x,y,1,1); } ctx.fillStyle='rgba(0,0,0,0.3)'; for (var y=0;y<16;y+=4) ctx.fillRect(0,y,16,1); ctx.fillRect(8,0,1,4); ctx.fillRect(0,4,1,4); ctx.fillRect(8,8,1,4); ctx.fillRect(0,12,1,4); }); TX.cobble = mkTex(function(ctx) { for (var y=0;y<16;y++) for (var x=0;x<16;x++) { var n=pxr(x,y,8), v=(95+n*45)|0; ctx.fillStyle='rgb('+v+','+v+','+v+')'; ctx.fillRect(x,y,1,1); } ctx.fillStyle='rgba(50,50,50,0.55)'; [[0,0,8,1],[8,4,8,1],[0,8,5,1],[5,12,11,1], [0,0,1,8],[8,0,1,4],[5,8,1,8]].forEach(function(a){ctx.fillRect(a[0],a[1],a[2],a[3]);}); }); // \u2500\u2500 MATERIALS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 function mml(txo, opts) { var cfg = Object.assign({ map: txo.tex }, opts||{}); return new THREE.MeshLambertMaterial(cfg); } var MATS = {}; MATS[B.GRASS] = [mml(TX.grass_side),mml(TX.grass_side),mml(TX.grass_top),mml(TX.dirt),mml(TX.grass_side),mml(TX.grass_side)]; MATS[B.DIRT] = mml(TX.dirt); MATS[B.STONE] = mml(TX.stone); MATS[B.SAND] = mml(TX.sand); MATS[B.WOOD] = mml(TX.wood); MATS[B.LEAVES] = mml(TX.leaves, {transparent:true, alphaTest:0.15, side:THREE.DoubleSide}); MATS[B.PLANKS] = mml(TX.planks); MATS[B.COBBLE] = mml(TX.cobble); // \u2500\u2500 THREE.JS SETUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var canvas = document.getElementById('c'); var renderer = new THREE.WebGLRenderer({canvas:canvas, antialias:false}); renderer.setPixelRatio(Math.min(devicePixelRatio, 2)); renderer.shadowMap.enabled = true; renderer.setClearColor(0x87ceeb); var scene = new THREE.Scene(); scene.fog = new THREE.Fog(0x87ceeb, 45, 95); var camera = new THREE.PerspectiveCamera(75, 1, 0.05, 200); var sun = new THREE.DirectionalLight(0xfffbe8, 1.1); sun.position.set(50, 80, 30); sun.castShadow = true; sun.shadow.mapSize.set(1024,1024); sun.shadow.camera.left = sun.shadow.camera.bottom = -60; sun.shadow.camera.right = sun.shadow.camera.top = 60; sun.shadow.camera.far = 200; scene.add(sun); scene.add(new THREE.AmbientLight(0x99bbdd, 0.55)); scene.add(new THREE.HemisphereLight(0x87ceeb, 0x447722, 0.35)); function doResize() { renderer.setSize(window.innerWidth, window.innerHeight); camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); } window.addEventListener('resize', doResize); doResize(); // \u2500\u2500 WORLD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var world = {}; var meshMap = {}; function wk(x,y,z) { return x+','+y+','+z; } function getB(x,y,z) { return world[wk(x,y,z)] || 0; } function setB(x,y,z,t) { var k=wk(x,y,z); if (t===B.AIR) delete world[k]; else world[k]=t; } // Smooth noise function sn(x, z, seed) { var ix=Math.floor(x), iz=Math.floor(z); var fx=x-ix, fz=z-iz; function h(a,b) { var v=Math.sin(a*127.1+b*311.7+seed*73.9)*43758.545; return v-Math.floor(v); } var ux=fx*fx*(3-2*fx), uz=fz*fz*(3-2*fz); return h(ix,iz)+(h(ix+1,iz)-h(ix,iz))*ux +(h(ix,iz+1)-h(ix,iz))*uz +(h(ix+1,iz+1)-h(ix+1,iz)-h(ix,iz+1)+h(ix,iz))*ux*uz; } function fbm(x, z, seed) { return sn(x*.04,z*.04,seed)*.60 + sn(x*.09,z*.09,seed+1)*.25 + sn(x*.20,z*.20,seed+2)*.15; } function placeTree(ox, sy, oz) { var h = 4 + (pxr(ox,oz,99)*3)|0; for (var i=0;i<h;i++) setB(ox, sy+i, oz, B.WOOD); var top = sy+h; for (var lx=-2;lx<=2;lx++) for (var lz=-2;lz<=2;lz++) for (var ly=-1;ly<=2;ly++) { if (Math.abs(lx)+Math.abs(lz) > 3) continue; if (lx===0&&lz===0&&ly<0) continue; if (getB(ox+lx,top+ly,oz+lz)===B.AIR) setB(ox+lx,top+ly,oz+lz, B.LEAVES); } } function generateWorld() { var R = 26; for (var x=-R;x<R;x++) for (var z=-R;z<R;z++) { var h = fbm(x, z, 0); var biome = fbm(x+200, z+200, 5); var isSand = biome < 0.35; var isRocky = h > 0.72; var sy = Math.max(2, (h*22+5)|0); for (var y=0;y<=sy;y++) { var t; if (y===sy) t = isSand ? B.SAND : isRocky ? B.STONE : B.GRASS; else if (y>=sy-3) t = isSand ? B.SAND : B.DIRT; else t = B.STONE; setB(x,y,z,t); } if (!isSand && !isRocky && sy>5 && pxr(x,z,55)>0.80) placeTree(x, sy+1, z); } } // \u2500\u2500 MESH BUILDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var boxGeo = new THREE.BoxGeometry(1,1,1); var DIRS6 = [[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]]; function needsMesh(x,y,z) { if (getB(x,y,z)===B.AIR) return false; for (var i=0;i<6;i++) { var d=DIRS6[i]; if (getB(x+d[0],y+d[1],z+d[2])===B.AIR) return true; } return false; } function addMesh(x,y,z) { var k=wk(x,y,z); if (meshMap[k]) { scene.remove(meshMap[k]); delete meshMap[k]; } var type=getB(x,y,z); if (type===B.AIR) return; if (!needsMesh(x,y,z)) return; var m = new THREE.Mesh(boxGeo, MATS[type]); m.position.set(x,y,z); m.castShadow = true; m.receiveShadow = true; m.userData = {x:x,y:y,z:z,type:type}; scene.add(m); meshMap[k] = m; } function removeMesh(x,y,z) { var k=wk(x,y,z); if (meshMap[k]) { scene.remove(meshMap[k]); delete meshMap[k]; } } function rebuildAround(x,y,z) { addMesh(x,y,z); for (var i=0;i<6;i++) { var d=DIRS6[i]; addMesh(x+d[0],y+d[1],z+d[2]); } } function buildAll() { for (var k in world) { var p=k.split(','); addMesh(+p[0],+p[1],+p[2]); } } // \u2500\u2500 PLAYER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var pl = { x:0.5, y:20, z:0.5, vx:0, vy:0, vz:0, yaw:0, pitch:0, onGround:false }; var EYE=1.62, PW=0.28, PH=1.75; var GRAVITY=-26, JUMP_VY=9; function spawnY(x, z) { for (var y=40;y>=0;y--) if (getB(Math.floor(x),y,Math.floor(z))!==B.AIR && getB(Math.floor(x),y+1,Math.floor(z))===B.AIR) return y+1.5; return 20; } function collides(px,py,pz) { var offsets=[[-PW,0.05,-PW],[-PW,0.05,PW],[PW,0.05,-PW],[PW,0.05,PW], [-PW,PH*.5,-PW],[-PW,PH*.5,PW],[PW,PH*.5,-PW],[PW,PH*.5,PW], [-PW,PH-0.05,-PW],[-PW,PH-0.05,PW],[PW,PH-0.05,-PW],[PW,PH-0.05,PW]]; for (var i=0;i<offsets.length;i++) { var o=offsets[i]; if (getB(Math.floor(px+o[0]),Math.floor(py+o[1]),Math.floor(pz+o[2]))!==B.AIR) return true; } return false; } function movePlayer(dt) { var sprint=(keys['ShiftLeft']||keys['ShiftRight']); var spd=sprint?9:5; var sy=Math.sin(pl.yaw), cy=Math.cos(pl.yaw); var mx=0, mz=0; if (keys['KeyW']||keys['ArrowUp']) { mx-=sy; mz-=cy; } if (keys['KeyS']||keys['ArrowDown']) { mx+=sy; mz+=cy; } if (keys['KeyA']||keys['ArrowLeft']) { mx-=cy; mz+=sy; } if (keys['KeyD']||keys['ArrowRight']) { mx+=cy; mz-=sy; } var ml=Math.sqrt(mx*mx+mz*mz); if (ml>0) { mx=mx/ml*spd; mz=mz/ml*spd; } pl.vx=mx; pl.vz=mz; pl.vy+=GRAVITY*dt; if (keys['Space']&&pl.onGround) { pl.vy=JUMP_VY; pl.onGround=false; } pl.x+=pl.vx*dt; if (collides(pl.x,pl.y,pl.z)) { pl.x-=pl.vx*dt; pl.vx=0; } pl.z+=pl.vz*dt; if (collides(pl.x,pl.y,pl.z)) { pl.z-=pl.vz*dt; pl.vz=0; } pl.y+=pl.vy*dt; pl.onGround=false; if (collides(pl.x,pl.y,pl.z)) { if (pl.vy<0) pl.onGround=true; pl.y-=pl.vy*dt; pl.vy=0; } if (pl.y<-10) { pl.y=spawnY(0,0); pl.vy=0; } } // \u2500\u2500 INPUT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var keys={}; var locked=false; document.addEventListener('keydown', function(e){ keys[e.code]=true; }); document.addEventListener('keyup', function(e){ keys[e.code]=false; }); document.addEventListener('pointerlockchange', function(){ locked=!!document.pointerLockElement; }); document.addEventListener('mousemove', function(e){ if (!locked) return; pl.yaw -= e.movementX*0.0022; pl.pitch -= e.movementY*0.0022; pl.pitch = Math.max(-1.55, Math.min(1.55, pl.pitch)); }); // \u2500\u2500 HOTBAR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var HOTBAR=[ {type:B.GRASS, label:'Grass', tx:TX.grass_top}, {type:B.DIRT, label:'Dirt', tx:TX.dirt}, {type:B.STONE, label:'Stone', tx:TX.stone}, {type:B.SAND, label:'Sand', tx:TX.sand}, {type:B.WOOD, label:'Wood', tx:TX.wood}, {type:B.LEAVES,label:'Leaves', tx:TX.leaves}, {type:B.PLANKS,label:'Planks', tx:TX.planks}, {type:B.COBBLE,label:'Cobble', tx:TX.cobble}, ]; var slot=0; function buildHotbar() { var hb=document.getElementById('hotbar'); hb.innerHTML=''; for (var i=0;i<HOTBAR.length;i++) { var item=HOTBAR[i]; var div=document.createElement('div'); div.className='hslot'+(i===slot?' sel':''); var cv=document.createElement('canvas'); cv.width=cv.height=32; cv.style.width='32px'; cv.style.height='32px'; var ctx=cv.getContext('2d'); ctx.imageSmoothingEnabled=false; ctx.drawImage(item.tx.cv, 0,0,32,32); var sp=document.createElement('span'); sp.textContent=item.label; div.appendChild(cv); div.appendChild(sp); hb.appendChild(div); } } document.addEventListener('wheel', function(e){ slot=((slot+(e.deltaY>0?1:-1))+HOTBAR.length)%HOTBAR.length; buildHotbar(); }, {passive:true}); for (var _i=1;_i<=8;_i++) { (function(n){ document.addEventListener('keydown', function(e){ if (e.code==='Digit'+n) { slot=n-1; buildHotbar(); } }); })(_i); } // \u2500\u2500 RAYCAST \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var rc = new THREE.Raycaster(); rc.near=0.1; rc.far=8; function doRaycast() { var dir=new THREE.Vector3(0,0,-1); var eu=new THREE.Euler(pl.pitch, pl.yaw, 0, 'YXZ'); dir.applyEuler(eu); var ori=new THREE.Vector3(pl.x, pl.y+EYE, pl.z); rc.set(ori, dir); var objs=Object.values(meshMap); var hits=rc.intersectObjects(objs, false); return hits.length>0 ? hits[0] : null; } // \u2500\u2500 HIGHLIGHT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 var hlMesh=new THREE.Mesh( new THREE.BoxGeometry(1.005,1.005,1.005), new THREE.MeshBasicMaterial({color:0x000000,wireframe:true,transparent:true,opacity:0.45}) ); scene.add(hlMesh); hlMesh.visible=false; // \u2500\u2500 BREAK/PLACE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

2

Requests

2

Domains

139KB

Transfer Size

610KB

Content Size

278.0ms

Dom Content Loaded

192.0ms

First Paint

278.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...