WEBLEB
Home
AI Editor
Chat
Challenge
Login
Pro
English
English
Français
Español
Sneaky Neighbor!
56
0
Games
Mad_Official
Follow
0
Remix
Open In Editor
Fullscreen
Discuss
Publish Your Code
0
HTML
Copy
Sneaky Neighbor
PRODUCED BY
Mad_Official
&
arghhh
Sneaky
Neighbor
Start Sneaking
Difficulty
Easy
Normal
Hard
Detail & Shadows
Low
Medium
High
Credits
Esc
BACK
PRODUCED BY
Mad_Official
&
arghhh
Click or press Esc to go back
Your neighbor is hiding something in that basement…
OBJECTIVE
Sneak into the yard and find a way toward the basement door.
Click to resume
BUSTED!
Try Again
YOU’RE IN!
The basement door creaks open…
Play Again
CSS
Copy
:root{--ink:#06122b;--panel:rgba(10,14,30,.78);--txt:#fff;--gold:#ffc83d;--font:'Bangers',Impact,'Arial Black',sans-serif} *{box-sizing:border-box} html,body{height:100%;margin:0;background:#000;overflow:hidden;font-family:system-ui,'Segoe UI',sans-serif;color:var(--txt)} canvas{display:block;position:fixed;inset:0} .ov{position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;z-index:10;transition:opacity 1s} .hide{opacity:0;pointer-events:none} /* ---- credits / intro ---- */ #intro,#credits{background:#000;z-index:40;gap:6px} #credits{display:none;cursor:pointer} .cr-small{font-family:var(--font);letter-spacing:6px;font-size:clamp(16px,3vw,26px);color:#9db4ff;opacity:0;animation:fade 1s .2s forwards} .cr-big{font-family:var(--font);letter-spacing:4px;font-size:clamp(44px,10vw,100px);color:var(--gold);text-shadow:4px 4px 0 #3b1466;opacity:0;animation:fade 1s .7s forwards} #intro .cr-small:nth-child(3){animation-delay:1.3s}#intro .cr-big:nth-child(4){animation-delay:1.7s} #credits *{animation-delay:.1s!important}.dim{margin-top:30px;opacity:.5!important;font-size:14px;letter-spacing:2px} @keyframes fade{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}} /* ---- main menu (painted room like the reference) ---- */ #menu{align-items:flex-start;justify-content:flex-start;text-align:left;z-index:30;background:#03091a} #room{position:absolute;inset:0;overflow:hidden} #wall{position:absolute;inset:0 0 22% 0;background: radial-gradient(ellipse at 18% 90%,rgba(255,30,30,.35),transparent 45%), radial-gradient(ellipse at 75% 20%,rgba(120,190,255,.35),transparent 40%), repeating-linear-gradient(90deg,#0a2a6e 0 4.5vw,#133a96 4.5vw 5.3vw,#0a2564 5.3vw 6vw)} #wall::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 35%,rgba(0,0,10,.75) 100%)} #floor{position:absolute;left:0;right:0;bottom:0;height:22%;background:repeating-linear-gradient(90deg,#1d1208 0 7vw,#2b1b0d 7vw 7.4vw),#1d1208;box-shadow:inset 0 30px 40px rgba(0,0,0,.7)} #door{position:absolute;left:46%;width:25vw;bottom:22%;height:64vh;background: linear-gradient(0deg,rgba(0,0,0,.4),transparent),repeating-linear-gradient(90deg,#4a2a14 0 3vw,#3a2010 3vw 3.3vw); border:1.2vw solid #7a1f1a;border-bottom:none;box-shadow:-3vw 0 6vw rgba(255,40,40,.45),0 0 4vw #000;transform:skewY(-1.5deg)} #door::before{content:"";position:absolute;left:-1vw;right:-1vw;top:46%;height:4vh;background:#2a1a12;transform:rotate(-5deg);border:2px solid #111} #door::after{content:"";position:absolute;right:2vw;top:50%;width:1.4vw;height:3vh;background:#222;border-radius:3px} #fusebox{position:absolute;left:38%;bottom:36%;width:5vw;height:16vh;background:#c9d4dc;border:.5vw solid #d96a1d;border-radius:4px;box-shadow:0 0 3vw rgba(255,60,40,.4)} #table{position:absolute;left:12%;bottom:15%;width:16vw;height:6vh;background:#f2b21b;border:3px solid #6b4c08;border-radius:4px;box-shadow:0 20px 30px #000} #table::after{content:"";position:absolute;left:8%;right:8%;top:100%;height:12vh;border-left:.6vw solid #c68b0a;border-right:.6vw solid #c68b0a} #lamp{position:absolute;right:11%;bottom:17%;width:12vw;height:60vh} #lamp b{position:absolute;left:0;right:0;top:0;height:18vh;background:linear-gradient(90deg,#c9c7ff,#fff,#d7d6ff);clip-path:polygon(22% 0,78% 0,100% 100%,0 100%);filter:drop-shadow(0 0 30px #8fd0ff)} #lamp u{position:absolute;left:49%;top:18vh;width:.7vw;bottom:0;background:#0b0b12} #lamp::after{content:"";position:absolute;left:25%;right:25%;bottom:0;height:1.6vh;background:#0b0b12;border-radius:50%} #logo{position:absolute;left:0;top:0;width:min(46vw,520px);padding:22px 70px 26px 26px;background:#000;clip-path:polygon(0 0,100% 0,84% 100%,0 100%);font-family:var(--font);font-size:clamp(26px,4.2vw,52px);letter-spacing:2px;color:#fff;line-height:1} .ring{display:inline-block;width:.55em;height:.55em;margin:0 .12em;border:.12em solid var(--gold);border-radius:50%;vertical-align:-.02em} #items{list-style:none;margin:0;padding:0;position:absolute;left:5vw;top:30vh} #items li{font-size:clamp(13px,1.7vw,19px);letter-spacing:3px;text-transform:uppercase;padding:9px 0;color:#fff;cursor:pointer;text-shadow:0 2px 6px #000;transition:transform .12s,color .12s} #items li:hover{color:var(--gold);transform:translateX(8px)} select{margin-left:10px;background:transparent;color:var(--gold);border:0;border-bottom:1px dashed #6a82c8;font:inherit;letter-spacing:2px;text-transform:uppercase;cursor:pointer} select option{background:#0a1030;color:#fff} #back{position:absolute;right:20px;bottom:calc(16px + env(safe-area-inset-bottom,0px));font-size:13px;letter-spacing:2px;opacity:.85} kbd{background:#fff;color:#000;border-radius:4px;padding:3px 6px;font-weight:700;margin-right:6px} /* ---- cutscene bars ---- */ #bars{position:fixed;inset:0;pointer-events:none;z-index:8;opacity:0;transition:opacity .8s} #bars.on{opacity:1} #bars i{position:absolute;left:0;right:0;height:11vh;background:#000}#bars i:first-child{top:0}#bars i:nth-child(2){bottom:0} #caption{position:absolute;bottom:14vh;width:100%;text-align:center;font-family:var(--font);letter-spacing:4px;font-size:clamp(18px,3vw,32px);text-shadow:3px 3px 0 #000} /* ---- HUD ---- */ #hud{position:fixed;inset:0;pointer-events:none;display:none;z-index:5} #obj{position:absolute;left:16px;top:16px;max-width:390px;background:var(--panel);border-left:4px solid var(--gold);padding:10px 14px;border-radius:8px;font-size:14px;line-height:1.4} #obj b{font-family:var(--font);font-weight:400;letter-spacing:2px;color:var(--gold);font-size:18px} #cross{position:absolute;left:50%;top:50%;width:6px;height:6px;margin:-3px;border-radius:50%;background:#fff;box-shadow:0 0 0 2px rgba(0,0,0,.45)} #status{position:absolute;right:16px;top:16px;font-family:var(--font);letter-spacing:3px;font-size:26px;text-shadow:2px 2px 0 #000} #hint{position:absolute;bottom:28px;width:100%;text-align:center;font-size:15px;text-shadow:0 2px 4px #000} #danger{position:absolute;inset:0;opacity:0;background:radial-gradient(ellipse at center,transparent 45%,rgba(255,0,30,.65) 100%);transition:opacity .25s} #pause{display:none;background:rgba(5,5,20,.75);cursor:pointer;font-family:var(--font);font-size:44px;letter-spacing:3px} button{font-family:var(--font);font-size:clamp(26px,4vw,40px);letter-spacing:3px;background:var(--gold);color:#3b1466;border:4px solid #3b1466;border-radius:16px;padding:12px 40px;cursor:pointer;box-shadow:0 8px 0 #3b1466} button:active{transform:translateY(4px);box-shadow:0 3px 0 #3b1466} #busted{display:none;background:rgba(120,0,10,.92);z-index:20} #busted.show{display:flex;animation:flash .3s 3} @keyframes flash{50%{background:#fff}} #busted svg{width:min(60vmin,420px);animation:zoom .5s ease-out both} @keyframes zoom{from{transform:scale(.1) rotate(-20deg)}to{transform:none}} #busted h2,#win h2{font-family:var(--font);font-weight:400;font-size:clamp(60px,16vw,150px);margin:0 0 16px;color:#fff;-webkit-text-stroke:3px #000;text-shadow:6px 6px 0 #000;animation:shake .12s infinite} @keyframes shake{25%{transform:translate(4px,-3px) rotate(1deg)}75%{transform:translate(-4px,3px) rotate(-1deg)}} #win{display:none;background:rgba(20,60,30,.92);z-index:20}#win.show{display:flex}#win h2{animation:none;color:var(--gold)} #win .cr-small{opacity:1;animation:none;margin-bottom:20px} #obj i{display:block;margin-top:7px;color:#ffc4c4;font-size:13px}
JS
Copy
/* Framed photos for the neighbor's living room (embedded so they load without a server) */ window.PHOTOS = ["data:image/jpeg;base64,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", "data:image/jpeg;base64,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"]; /* Sneaky Neighbor - game logic (Three.js r128) */ (() => { const $ = id => document.getElementById(id); const clamp = THREE.MathUtils.clamp, lerp = THREE.MathUtils.lerp; /* ---------- Settings ---------- */ const DIFF = { easy: {patrol:2.0, chase:4.6, view:15, fov:0.9, lose:4}, normal: {patrol:2.6, chase:5.8, view:21, fov:1.05, lose:6}, hard: {patrol:3.2, chase:6.9, view:28, fov:1.2, lose:8} }; let D = DIFF.normal; /* ---------- Renderer / scene / sky ---------- */ const renderer = new THREE.WebGLRenderer({antialias:true}); document.body.appendChild(renderer.domElement); const FOG = 0xc2a2b8; const scene = new THREE.Scene(); scene.fog = new THREE.FogExp2(FOG, 0.0085); const camera = new THREE.PerspectiveCamera(70, innerWidth/innerHeight, 0.1, 200); camera.rotation.order = 'YXZ'; function tex(w,h,draw,rep){ const c = document.createElement('canvas'); c.width = w; c.height = h; draw(c.getContext('2d'),w,h); const t = new THREE.CanvasTexture(c); t.wrapS = t.wrapT = THREE.RepeatWrapping; t.anisotropy = 4; if(rep) t.repeat.set(rep[0],rep[1]); return t; } // Sky dome: blue to warm peach horizon const skyTex = tex(8,256,(g,w,h)=>{const gr=g.createLinearGradient(0,0,0,h);gr.addColorStop(0,'#4f6fb5');gr.addColorStop(.55,'#9fa6d0');gr.addColorStop(.85,'#e8b9a6');gr.addColorStop(1,'#c2a2b8');g.fillStyle=gr;g.fillRect(0,0,w,h);}); skyTex.wrapS = skyTex.wrapT = THREE.ClampToEdgeWrapping; const sky = new THREE.Mesh(new THREE.SphereGeometry(180,24,16), new THREE.MeshBasicMaterial({map:skyTex,side:THREE.BackSide,fog:false})); scene.add(sky); scene.add(new THREE.HemisphereLight(0xffd9b0, 0x4a3f78, 0.8)); const sun = new THREE.DirectionalLight(0xffb070, 1.2); sun.position.set(-40,45,30); sun.castShadow = true; Object.assign(sun.shadow.camera,{left:-60,right:60,top:60,bottom:-60,near:1,far:160}); sun.shadow.bias = -0.0006; scene.add(sun); /* ---------- Procedural textures ---------- */ const plankTex = tex(256,256,(g,w,h)=>{ const n=8, ph=h/n; for(let i=0;i<n;i++){const l=205+Math.random()*40|0;g.fillStyle=`rgb(${l},${l},${l})`;g.fillRect(0,i*ph,w,ph); g.fillStyle='rgba(0,0,0,.35)';g.fillRect(0,i*ph+ph-3,w,3); for(let k=0;k<6;k++){g.strokeStyle='rgba(0,0,0,.12)';g.beginPath();const y=i*ph+Math.random()*ph;g.moveTo(Math.random()*w,y);g.lineTo(Math.random()*w,y+2);g.stroke();} g.fillStyle='rgba(0,0,0,.3)';g.fillRect(Math.random()*w,i*ph,3,ph-3);} },[3,2]); const brickTex = tex(128,128,(g,w,h)=>{g.fillStyle='#caa';g.fillRect(0,0,w,h);const rh=h/8; for(let r=0;r<8;r++)for(let c=-1;c<5;c++){const l=185+Math.random()*60|0;g.fillStyle=`rgb(${l},${l-30|0},${l-35|0})`;g.fillRect(c*32+(r%2?16:0)+2,r*rh+2,28,rh-3);}},[3,1]); const shingleTex = tex(128,128,(g,w,h)=>{g.fillStyle='#777';g.fillRect(0,0,w,h);const rh=h/8; for(let r=0;r<8;r++)for(let c=-1;c<6;c++){const l=170+Math.random()*70|0;g.fillStyle=`rgb(${l},${l},${l})`;g.fillRect(c*24+(r%2?12:0)+1,r*rh+1,22,rh-2);}},[4,2]); const grassTex = tex(256,256,(g,w,h)=>{g.fillStyle='#fff';g.fillRect(0,0,w,h); for(let i=0;i<2500;i++){const l=150+Math.random()*100|0;g.strokeStyle=`rgba(${l*.8|0},${l},${l*.5|0},.55)`;g.beginPath();const x=Math.random()*w,y=Math.random()*h;g.moveTo(x,y);g.lineTo(x+Math.random()*4-2,y-3-Math.random()*5);g.stroke();}},[70,70]); const argyle = tex(128,128,(g,w,h)=>{g.fillStyle='#8f93dc';g.fillRect(0,0,w,h); for(let i=0;i<2;i++)for(let j=0;j<2;j++){const cx=i*64+32,cy=j*64+32;g.fillStyle='#bcbff5';g.beginPath();g.moveTo(cx,cy-30);g.lineTo(cx+22,cy);g.lineTo(cx,cy+30);g.lineTo(cx-22,cy);g.fill();g.strokeStyle='rgba(255,255,255,.7)';g.stroke();}},[2,2]); const M = (c,o={}) => new THREE.MeshStandardMaterial(Object.assign({color:c,roughness:.85},o)); const wall = c => M(c,{map:plankTex}), roofM = c => M(c,{map:shingleTex}), brickM = c => M(c,{map:brickTex}); function box(w,h,d,mat,x,y,z,parent=scene){ const m = new THREE.Mesh(new THREE.BoxGeometry(w,h,d),mat); m.position.set(x,y,z); m.castShadow = m.receiveShadow = true; parent.add(m); return m; } function gable(w,h,d,mat){ const s = new THREE.Shape(); s.moveTo(-w/2,0); s.lineTo(w/2,0); s.lineTo(0,h); s.closePath(); const g = new THREE.ExtrudeGeometry(s,{depth:d,bevelEnabled:false}); g.translate(0,0,-d/2); const m = new THREE.Mesh(g,mat); m.castShadow = m.receiveShadow = true; return m; } /* ---------- Collision / line of sight ---------- */ const solids = [], blockers = []; function solid(cx,cz,w,d,los=true,lv){ const b = {x0:cx-w/2,x1:cx+w/2,z0:cz-d/2,z1:cz+d/2,lv}; solids.push(b); if(los) blockers.push(b); } function resolve(p,r,lv){ for(const b of solids){ if(b.lv !== undefined && b.lv !== lv) continue; // furniture only blocks its own floor const cx = Math.max(b.x0,Math.min(p.x,b.x1)), cz = Math.max(b.z0,Math.min(p.z,b.z1)); const dx = p.x-cx, dz = p.z-cz, d2 = dx*dx+dz*dz; if(d2 < r*r){ if(d2 > 1e-6){ const d = Math.sqrt(d2); p.x = cx+dx/d*r; p.z = cz+dz/d*r; } else{ const l=p.x-b.x0, rt=b.x1-p.x, t=p.z-b.z0, bt=b.z1-p.z, m=Math.min(l,rt,t,bt); if(m===l)p.x=b.x0-r; else if(m===rt)p.x=b.x1+r; else if(m===t)p.z=b.z0-r; else p.z=b.z1+r; } } } } function los(a,b){ const dx=b.x-a.x, dz=b.z-a.z, d=Math.hypot(dx,dz)||1; for(let t=0;t<=d;t+=.6){ const x=a.x+dx*t/d, z=a.z+dz*t/d; for(const k of blockers) if(x>k.x0&&x<k.x1&&z>k.z0&&z<k.z1) return false; } return true; } /* ---------- Ground ---------- */ const ground = new THREE.Mesh(new THREE.PlaneGeometry(400,400), M(0x7fb04a,{map:grassTex,roughness:1})); ground.rotation.x = -Math.PI/2; ground.receiveShadow = true; scene.add(ground); box(3,.05,24,M(0xb08a5a),0,.03,40); // dirt path between the houses box(160,.04,6,M(0x55535a,{roughness:1}),0,.02,36); // street /* ---------- Shared bits ---------- */ const white = M(0xf7f3ea), glassDark = M(0x16202c,{emissive:0x05080c}), glassLit = new THREE.MeshBasicMaterial({color:0xffcf70}); function windowAt(g,x,y,z,w,h,lit){ box(w+.3,h+.3,.18,white,x,y,z,g); box(w,h,.22,lit?glassLit:glassDark,x,y,z,g); box(.08,h,.26,white,x,y,z,g); box(w,.08,.26,white,x,y,z,g); } /* ---------- Neighbor's crazy wonky house (bigger, hollow, walk-in) ---------- */ const S = 1.3, NH = new THREE.Group(); NH.scale.setScalar(S); scene.add(NH); const teal = 0x2bb7b0, yellow = 0xd8d93c, orange = M(0xd2561f), floorM = M(0x8a5a32,{map:plankTex}), tealM = wall(teal), yelM = wall(yellow); function wallBox(cx,cz,w,d,h,mat,y0=0,col=true){ box(w,h,d,mat,cx,y0+h/2,cz,NH); if(col) solid(cx*S,cz*S,w*S,d*S); } // main body walls (front wall has a doorway at x -3.9..-2.1) and the opening into the tower wallBox(-3,-4.8,12,.4,8,tealM); wallBox(-8.8,0,.4,10,8,tealM); wallBox(-6.45,4.8,5.1,.4,8,tealM); wallBox(.45,4.8,5.1,.4,8,tealM); wallBox(-3,4.8,1.8,.4,4.8,tealM,3.2,false); wallBox(3,-3,.4,3.6,8,tealM); wallBox(3,3,.4,3.6,8,tealM); wallBox(3,0,.4,2.4,4.8,tealM,3.2,false); // tall yellow tower wallBox(6.25,3.5,6.5,.4,12,yelM); wallBox(6.25,-3.5,6.5,.4,12,yelM); wallBox(9.3,0,.4,7.4,12,yelM); box(11.8,.2,9.6,floorM,-3,.1,0,NH); box(6.3,.2,7,floorM,6.25,.1,0,NH); box(6.5,.3,7.4,M(0xe9dcc0),6.25,4.2,0,NH); [[-9,5],[3,5],[-9,-5],[3,-5]].forEach(([x,z]) => box(.3,8,.3,white,x,4,z,NH)); [[3,3.7],[9.5,3.7],[3,-3.7],[9.5,-3.7]].forEach(([x,z]) => box(.3,12,.3,white,x,6,z,NH)); // trim band / interior ceiling let r = gable(11.6,3.2,12.6,roofM(0x6b4a36)); r.rotation.y = Math.PI/2; r.position.set(-3,8,0); NH.add(r); r = gable(7.6,7.5,8.4,M(0xd0d23a,{map:plankTex})); r.position.set(6.25,12,0); NH.add(r); r = gable(8,5.5,9.4,wall(teal)); r.rotation.y = Math.PI/2; r.rotation.z = 0.05; r.position.set(6.25,12.2,0); NH.add(r); const dia = box(1.6,1.6,.2,white,6.25,15.5,4.2,NH); dia.rotation.z = Math.PI/4+.2; box(1.5,4.2,1.5,brickM(0xb4503a),-6.5,10,-2.5,NH); box(.08,2.4,.08,M(0x333333),-1.2,9.4,-2,NH); box(1.4,.06,.06,M(0x333333),-1.2,10.2,-2,NH); // balcony + porch box(12,.25,2.4,white,-3,4.05,6.2,NH); for(let i=0;i<=12;i++) box(.1,1.1,.1,orange,-9+i,4.7,7.3,NH); box(12,.1,.14,orange,-3,5.25,7.3,NH); box(12,.3,2.8,white,-3,.15,6.4,NH); for(let i=0;i<=12;i++) box(.1,.9,.1,white,-9+i,.75,7.7,NH); box(12,.1,.14,white,-3,1.2,7.7,NH); box(2.6,.3,1.3,M(0xd0482c),-3,.1,8.2,NH); // front door standing open const hinge = new THREE.Group(); hinge.position.set(-3.9,0,4.85); hinge.rotation.y = -1.25; NH.add(hinge); box(1.8,3.2,.15,M(0x4a3020),.9,1.6,0,hinge); [-6.5,-3,0.5].forEach(x => windowAt(NH,x,6,5.1,1.1,2.2,x>-4&&x<0)); windowAt(NH,-6.3,2.4,5.1,2.4,2.0,true); windowAt(NH,0,2.4,5.1,2,2,false); windowAt(NH,6.25,3.2,3.75,1.6,2.4,true); windowAt(NH,6.25,8,3.75,1.6,2.4,false); windowAt(NH,6.25,3.2,-3.75,1.6,2.4,false); // Basement door (east face of the tower) const BASEMENT = new THREE.Vector3(9.9*S,1,-1*S); box(.3,3.2,2.6,white,9.6,1.6,-1,NH); box(.3,2.8,2,M(0x2b1a12),9.75,1.4,-1,NH); box(.1,.4,.4,M(0xffc83d,{metalness:.8,roughness:.3}),9.95,1.4,-.2,NH); const glow = new THREE.PointLight(0x66ffcc,1.4,10); glow.position.set(14.5,2.6,-1.3); scene.add(glow); // Furnished interior function furn(lx,lz,w,d,h,mat,col=true,y=0){ box(w,h,d,mat,lx,y+h/2,lz,NH); if(col){ const lv = y>1?1:0; solid(lx*S,lz*S,w*S,d*S,lv===0,lv); } } const fab = M(0x9a2f4a), wd = M(0x5a3a22); box(4,.03,3,M(0xa03030),-4.5,.22,.2,NH); furn(-6,-3.9,3.4,1.3,.9,fab); furn(-6,-4.45,3.4,.4,1.7,fab,false); furn(-4.6,-1.4,1.7,.9,.5,wd); furn(-1,-4.45,3.2,.6,3,wd); for(let i=0;i<8;i++) box(.25,.7,.4,M(Math.random()*0xffffff),-2.4+i*.4,.9+(i%3)*.8,-4.1,NH); furn(8.4,-2.4,1.4,1.2,3.2,M(0x6b4a36)); furn(5.5,2.6,1.6,.8,.8,wd); // wardrobe = hiding spot, desk const lampL = new THREE.PointLight(0xffc070,1.5,16); lampL.position.set(-3.9,3.5,0); scene.add(lampL); const lampT = new THREE.PointLight(0xffc070,1.2,12); lampT.position.set(8.1,3.5,0); scene.add(lampT); // ===== Upstairs: floor slab with a stairwell, steps, bedroom, framed photos ===== const UPY = 4.15, wood2 = M(0xb8814a,{map:plankTex}); box(9.7,.3,10,floorM,-1.85,4,0,NH); box(2.3,.3,2.8,floorM,-7.85,4,-3.6,NH); // upstairs floor (hole at x -8.6..-6.7) box(12,.3,10,M(0xe9dcc0),-3,7.85,0,NH); // upstairs ceiling box(12.4,.3,.12,white,-3,4,5.05,NH); box(12.4,.3,.12,white,-3,4,-5.05,NH); box(.12,.3,10.2,white,-9.05,4,0,NH); // outside trim band for(let i=0;i<10;i++){ const h = UPY*(i+1)/10; box(1.6,h,.62,wood2,-7.8,h/2,4.0-.62*(i+.5),NH); } // stairs solid(-6.85*S,.2*S,.3*S,4.8*S,false); box(.1,.9,4.8,wd,-6.85,UPY+.45,.2,NH); box(.1,.9,4.6,wd,-6.85,.5,1.7,NH); // railings furn(-3.8,-3.1,2.4,3.4,.7,M(0x3a6ea5),true,UPY); box(1,.2,.6,white,-3.8,UPY+.8,-4.2,NH); // bed furn(1.9,-3.9,1.6,.8,1.4,wd,true,UPY); furn(1.9,1.5,.9,1.8,.8,wd,true,UPY); furn(-.5,-4.35,2,.7,3,M(0x6b4a36),true,UPY); box(3,.03,2.4,M(0x2f7a3a),-2.2,UPY+.02,1.2,NH); const lampU = new THREE.PointLight(0xffc070,1.4,14); lampU.position.set(-3.9,9.6,0); scene.add(lampU); // two framed photos above the living-room couch function framed(idx,lx,ly,pw,ph){ box(pw+.3,ph+.3,.12,M(0x3a2410),lx,ly,-4.5,NH); if(window.PHOTOS && PHOTOS[idx]){ const m = new THREE.Mesh(new THREE.PlaneGeometry(pw,ph),new THREE.MeshBasicMaterial({map:new THREE.TextureLoader().load(PHOTOS[idx])})); m.position.set(lx,ly,-4.43); NH.add(m); } } framed(0,-6.9,2.55,1.05,1.4); framed(1,-5.1,2.55,1.1,1.3); /* ---------- Player's house (beige, brick base, red roof) ---------- */ const PH = new THREE.Group(); PH.position.set(0,0,56); PH.rotation.y = Math.PI; scene.add(PH); // faces the neighbor box(12,6,9,wall(0xf1e6c8),0,3,0,PH); box(12.15,1,9.15,brickM(0xc55a45),0,.5,0,PH); solid(0,56,12.4,9.4); r = gable(10.6,3.8,13.2,roofM(0xc0392b)); r.rotation.y = Math.PI/2; r.position.set(0,6,0); PH.add(r); box(1.4,3.5,1.4,brickM(0xe4d0b0),3,7.6,-1.5,PH); box(3.4,.3,2.8,M(0xd9a86a),0,.15,5.6,PH); box(2.8,.25,1.2,M(0xd9a86a),0,.1,7.4,PH); box(.25,3.4,.25,M(0xd9a86a),-1.4,1.9,6.8,PH); box(.25,3.4,.25,M(0xd9a86a),1.4,1.9,6.8,PH); r = gable(3.8,1.6,2.8,roofM(0xc0392b)); r.rotation.y = Math.PI; r.position.set(0,3.6,5.6); PH.add(r); box(1.3,2.6,.15,M(0x6f6a52),0,1.6,4.55,PH); windowAt(PH,-3.8,3.2,4.55,1.4,1.9,true); windowAt(PH,3.8,3.2,4.55,1.4,1.9,false); const porchLight = new THREE.PointLight(0xffc070,1.3,16); porchLight.position.set(0,3.4,50); scene.add(porchLight); /* ---------- White picket fence ---------- */ const picket = M(0xf7f3ea); function fence(x0,z0,x1,z1){ const len = Math.hypot(x1-x0,z1-z0), n = Math.floor(len/.9), ang = Math.atan2(x1-x0,z1-z0); for(let i=0;i<=n;i++){ const t=i/n; box(.3,1.4,.12,picket,x0+(x1-x0)*t,.7,z0+(z1-z0)*t).rotation.y = ang; } const rl = new THREE.Group(); rl.position.set((x0+x1)/2,0,(z0+z1)/2); rl.rotation.y = ang; box(.1,.12,len,picket,0,.4,0,rl); box(.1,.12,len,picket,0,1.0,0,rl); scene.add(rl); solid((x0+x1)/2,(z0+z1)/2,Math.abs(x1-x0)+.5,Math.abs(z1-z0)+.5,false); } fence(-30,-30,30,-30); fence(-30,-30,-30,30); fence(30,-30,30,30); fence(-30,30,-2.5,30); fence(2.5,30,30,30); box(.5,2,.5,picket,-2.5,1,30); box(.5,2,.5,picket,2.5,1,30); /* ---------- Props: crates, mailbox, gnomes, bulbous trees ---------- */ const crateMat = M(0xb5793a,{map:plankTex}); [[10,10,2],[-6,16,2.2],[18,-4,1.8],[-20,1,2.4],[5,-17,2],[-24,-14,2.2],[20,18,1.8],[-12,-19,2],[-9,25,1.6]] .forEach(([x,z,s]) => { box(s,s,s,crateMat,x,s/2,z); box(s*.7,s*.7,s*.7,crateMat,x+.3,s*1.35,z); solid(x,z,s,s); }); function mailbox(x,z){ box(.15,1.3,.15,M(0x8a5a2a),x,.65,z); const b = box(.5,.5,.9,white,x,1.5,z); b.scale.set(1,1,1); box(.06,.4,.06,M(0xd32a2a),x+.32,1.7,z-.1); solid(x,z,.5,.5); } mailbox(4,40); function gnome(x,z,rot){ const g = new THREE.Group(); g.position.set(x,0,z); g.rotation.y = rot; g.scale.setScalar(1.3); [[new THREE.CylinderGeometry(.3,.38,.7,10),0x2b6cb0,.35],[new THREE.ConeGeometry(.3,.8,10),0xe02b2b,1.35]].forEach(([geo,c,y]) => { const m = new THREE.Mesh(geo,M(c)); m.position.y = y; m.castShadow = true; g.add(m); }); const b = new THREE.Mesh(new THREE.SphereGeometry(.3,10,8),M(0xffffff)); b.position.set(0,.8,.12); g.add(b); scene.add(g); solid(x,z,.7,.7); } [[-7,27,.4],[6,14,-.5],[-15,8,2],[14,-12,1],[-8,-8,3],[22,2,-1.5],[-26,-6,.8]].forEach(a => gnome(...a)); function tree(x,z){ const t = new THREE.Mesh(new THREE.CylinderGeometry(.25,.5,7,7),M(0x5a3a22)); t.position.set(x,3.5,z); t.rotation.z = (Math.random()-.5)*.15; t.castShadow = true; scene.add(t); for(let i=0;i<4;i++){ const c = new THREE.Mesh(new THREE.IcosahedronGeometry(2.6,1),M(0x8c9a2c,{flatShading:true})); c.position.set(x+(Math.random()-.5)*3,7+Math.random()*2,z+(Math.random()-.5)*3); c.scale.set(1+Math.random()*.4,.75,1+Math.random()*.4); c.castShadow = true; scene.add(c); } solid(x,z,1,1); } [[-26,-26],[26,-26],[-26,24],[26,24],[-18,-8],[16,-20],[22,8],[-8,-24],[-14,44],[15,45]].forEach(a => tree(...a)); /* ---------- Cooler yard: stone path, bushes, flower beds, pond, car, scarecrow, shed ---------- */ for(let i=0;i<10;i++){ const t = i/9; box(1.7,.1,1.1,M(0x9a9aa6),lerp(0,-3.9,t)+Math.sin(t*6)*.6,.06,lerp(29,11.5,t)).rotation.y = Math.sin(t*6)*.3; } function bush(x,z,rad=1.1,c=0x2f7a3a){ const b = new THREE.Mesh(new THREE.IcosahedronGeometry(rad,1),M(c,{flatShading:true})); b.position.set(x,rad*.8,z); b.scale.y = .85; b.castShadow = true; scene.add(b); solid(x,z,rad*1.5,rad*1.5); } for(let z=20;z<=28;z+=1.9){ bush(-4.5,z); bush(4.5,z); } // hedge avenue from the gate [[-27,-27],[-20,-28],[27,-20],[28,-6],[-28,10],[-28,20],[27,26],[20,28],[-11,28],[11,28]].forEach(([x,z]) => bush(x,z,1.4,0x3d8a3a)); // flower beds (instanced blossoms) const beds = [[-10,16],[10,17],[-18,-22],[16,-26]], blooms = [0xff4d6d,0xffd23f,0xff8fab,0xffffff,0xb388ff,0xff7a2f]; const fl = new THREE.InstancedMesh(new THREE.SphereGeometry(.17,6,5),M(0xffffff),beds.length*45), dm = new THREE.Object3D(), cc = new THREE.Color(); beds.forEach(([bx,bz],bi) => { const d = new THREE.Mesh(new THREE.CylinderGeometry(2.3,2.5,.2,18),M(0x4a3020)); d.position.set(bx,.1,bz); d.receiveShadow = true; scene.add(d); for(let i=0;i<45;i++){ const a = Math.random()*6.28, rr = Math.sqrt(Math.random())*2.1; dm.position.set(bx+Math.cos(a)*rr,.45+Math.random()*.25,bz+Math.sin(a)*rr); dm.updateMatrix(); fl.setMatrixAt(bi*45+i,dm.matrix); fl.setColorAt(bi*45+i,cc.setHex(blooms[Math.random()*blooms.length|0])); } }); scene.add(fl); // pond with rocks and lily pads const pond = new THREE.Mesh(new THREE.CylinderGeometry(3.4,3.4,.1,24),M(0x2a7fb8,{roughness:.1,metalness:.3,emissive:0x0a2a40})); pond.position.set(-15,.06,19); scene.add(pond); for(let i=0;i<14;i++){ const a = i/14*6.28, rk = new THREE.Mesh(new THREE.IcosahedronGeometry(.45+Math.random()*.25,0),M(0x888890,{flatShading:true})); rk.position.set(-15+Math.cos(a)*3.6,.25,19+Math.sin(a)*3.6); rk.castShadow = true; scene.add(rk); } for(let i=0;i<6;i++){ const lp = new THREE.Mesh(new THREE.CylinderGeometry(.4,.4,.03,10),M(0x3a9a3a)); lp.position.set(-15+(Math.random()-.5)*4,.13,19+(Math.random()-.5)*4); scene.add(lp); } solid(-15,19,5.2,5.2,false); // rusty red car (like the reference screenshot) const car = new THREE.Group(); car.position.set(17,0,24); car.rotation.y = .4; scene.add(car); box(4.4,.9,2,M(0xc4382a,{roughness:.5}),0,.85,0,car); box(2.2,.8,1.8,M(0xa82e22),-.2,1.65,0,car); box(2,.6,1.85,M(0x1a2430),-.2,1.65,0,car); [[-1.4,.9],[1.4,.9],[-1.4,-.9],[1.4,-.9]].forEach(([x,z]) => { const w = new THREE.Mesh(new THREE.CylinderGeometry(.45,.45,.3,14),M(0x111111)); w.rotation.x = Math.PI/2; w.position.set(x,.45,z); w.castShadow = true; car.add(w); }); solid(17,24,4.6,3.6); // scarecrow const sc = new THREE.Group(); sc.position.set(-18,0,-3); scene.add(sc); box(.12,3,.12,wd,0,1.5,0,sc); box(2,.12,.12,wd,0,2.4,0,sc); box(.9,1,.4,M(0xc0392b),0,2.1,0,sc); const sh2 = new THREE.Mesh(new THREE.SphereGeometry(.35,10,8),M(0xe8c47a)); sh2.position.y = 3.1; sc.add(sh2); const sht = new THREE.Mesh(new THREE.ConeGeometry(.5,.7,10),M(0x5a3a22)); sht.position.y = 3.6; sc.add(sht); solid(-18,-3,.8,.8); // garden shed + pumpkins + lamp posts box(4,3,3.4,wall(0x8a6a4a),24,1.5,-20); r = gable(4.8,1.8,4,roofM(0x553322)); r.rotation.y = Math.PI/2; r.position.set(24,3,-20); scene.add(r); solid(24,-20,4.2,3.6); for(let i=0;i<6;i++){ const p = new THREE.Mesh(new THREE.SphereGeometry(.45,10,8),M(0xf07a1a)); p.scale.y = .8; p.position.set(-9+i*.7+Math.random()*.4,.35,12.5+Math.random()*1.2); p.castShadow = true; scene.add(p); } [[-1.9,27],[1.9,27],[-3.2,15],[0.2,19]].forEach(([x,z]) => { box(.12,2.2,.12,M(0x222222),x,1.1,z); const b = new THREE.Mesh(new THREE.SphereGeometry(.22,8,6),new THREE.MeshBasicMaterial({color:0xffe08a})); b.position.set(x,2.3,z); scene.add(b); }); const yardLight = new THREE.PointLight(0xffd080,1.1,18); yardLight.position.set(0,2.4,23); scene.add(yardLight); /* ---------- Neighborhood: houses, trees, church and factory in the haze ---------- */ function smallHouse(x,z,col,roofCol,w=9,d=8,h=5,side=false){ const g = new THREE.Group(); g.position.set(x,0,z); g.rotation.y = Math.atan2(-x,-z); scene.add(g); box(w,h,d,wall(col),0,h/2,0,g); const rf = side ? gable(d+1.4,3.4,w+1.4,roofM(roofCol)) : gable(w+1.4,3.4,d+1.4,roofM(roofCol)); if(side) rf.rotation.y = Math.PI/2; rf.position.y = h; g.add(rf); box(1.2,2.4,.12,M(0x4a3020),0,1.2,d/2+.05,g); windowAt(g,-w/3,2.9,d/2+.08,1.3,1.5,Math.random()<.35); windowAt(g,w/3,2.9,d/2+.08,1.3,1.5,Math.random()<.35); if(Math.random()<.6) box(1.1,3,1.1,brickM(0xb4503a),w/4,h+2.2,-d/4,g); const sq = Math.max(w,d)+1.5; solid(x,z,sq,sq); } const hc = [0xd6892e,0x4a6aa8,0xc8423a,0x3aa6a0,0xe0b43a,0x7a5aa8], rc = [0x3a2f3f,0x5a2a3a,0x2f3a5a,0x4a3a2a]; [[-28,58],[28,59],[-47,56],[47,57],[-50,22],[-52,-4],[-48,-32],[50,24],[52,-2],[48,-30],[-32,-54],[2,-58],[34,-52],[-14,-72],[20,-74],[-60,40],[60,38]] .forEach(([x,z],i) => smallHouse(x,z,hc[i%hc.length],rc[i%rc.length],8+i%3*1.5,7+i%2*2,4.6+i%3*.5,i%2===0)); [[-40,-18],[40,-14],[-40,34],[42,36],[-56,10],[56,12],[-20,-46],[22,-46],[-6,-44],[44,-42],[-44,-44],[-40,50],[40,52]].forEach(a => tree(...a)); // church + factory with striped chimneys, far behind the neighbor's house const mist = c => M(c,{roughness:1}); box(14,14,22,mist(0xe6e6ee),-50,7,-92); const spire = new THREE.Mesh(new THREE.ConeGeometry(4.6,14,4),mist(0x4a2a4a)); spire.position.set(-50,28,-100); spire.rotation.y = Math.PI/4; scene.add(spire); box(6,20,6,mist(0xe6e6ee),-50,10,-100); r = gable(16,6,22,mist(0x4a2a4a)); r.position.set(-50,14,-92); scene.add(r); box(34,12,16,mist(0xaab4cc),38,6,-95); box(12,16,12,mist(0xe2706b),18,8,-95); [[26,-102],[32,-102]].forEach(([x,z]) => { for(let i=0;i<9;i++){ const c = new THREE.Mesh(new THREE.CylinderGeometry(2,2.1,4,12),mist(i%2?0xffffff:0xd93a3a)); c.position.set(x,2+i*4,z); scene.add(c); } }); const OBJ0 = 'Unlock the basement door on the east side of the neighbor’s house. Find the red key.<i>Riddle: “I wear a hat but have no head. I have arms but cannot hug. I guard the crops yet never move. The red key rests where I plant my feet.”</i>'; $('objtxt').innerHTML = OBJ0; /* ---------- Collectible key ---------- */ const key = new THREE.Group(); const gold = M(0xd0161e,{metalness:.6,roughness:.3,emissive:0x550000}); // the red key key.add(new THREE.Mesh(new THREE.TorusGeometry(.3,.08,8,16),gold)); box(.1,.7,.1,gold,0,-.5,0,key); box(.3,.1,.1,gold,.12,-.7,0,key); key.position.set(-18,.9,-1.6); // at the scarecrow's feet scene.add(key); const keyLight = new THREE.PointLight(0xff3030,1,7); keyLight.position.copy(key.position); scene.add(keyLight); /* ---------- THE NEIGHBOR: modelled after the character sheet ---------- */ function makeNeighbor(){ const root = new THREE.Group(); const skin = M(0xf1bf9f), yel = M(0xf6e27a), glove = M(0x1c2036), orng = M(0xee6a1c), vest = M(0xffffff,{map:argyle}), hairM = M(0x6b2418), shoe = M(0x2f3550); const mesh = (geo,mat,x,y,z,p) => { const m = new THREE.Mesh(geo,mat); m.position.set(x,y,z); m.castShadow = true; p.add(m); return m; }; const hips = new THREE.Group(); hips.position.y = 1.35; root.add(hips); mesh(new THREE.CylinderGeometry(.42,.38,.36,14),orng,0,0,0,hips); const torso = new THREE.Group(); torso.position.y = .1; hips.add(torso); mesh(new THREE.CylinderGeometry(.62,.58,1.05,20),vest,0,.5,0,torso).scale.z = .7; mesh(new THREE.SphereGeometry(1,16,12),vest,0,.22,.1,torso).scale.set(.6,.42,.5); // argyle vest mesh(new THREE.CylinderGeometry(.55,.64,.22,20),yel,0,1.05,0,torso).scale.z = .68; mesh(new THREE.CylinderGeometry(.14,.17,.22,10),skin,0,1.15,0,torso); // yellow shirt shoulders const head = new THREE.Group(); head.position.y = 1.22; head.scale.setScalar(1.25); torso.add(head); mesh(new THREE.SphereGeometry(1,22,16),skin,0,.42,0,head).scale.set(.34,.44,.37); // big egg head const hair = mesh(new THREE.SphereGeometry(1,22,12,0,Math.PI*2,0,Math.PI*.42),hairM,0,.5,-.01,head); hair.scale.set(.36,.46,.4); hair.rotation.x = -.3; const nose = mesh(new THREE.ConeGeometry(.07,.28,8),M(0xe8a98a),0,.36,.4,head); nose.rotation.x = Math.PI/2; [-1,1].forEach(s => { mesh(new THREE.SphereGeometry(.08,10,8),M(0xffffff),s*.13,.5,.33,head).scale.z = .6; mesh(new THREE.SphereGeometry(.04,8,6),M(0xb9c23a),s*.13,.5,.385,head); mesh(new THREE.SphereGeometry(.02,8,6),M(0x000000),s*.13,.5,.415,head); const br = mesh(new THREE.BoxGeometry(.17,.04,.04),M(0x4a1a10),s*.13,.62,.36,head); br.rotation.z = -s*.35; const mu = mesh(new THREE.SphereGeometry(1,10,8),M(0x3a1608),s*.1,.26,.39,head); mu.scale.set(.13,.05,.05); mu.rotation.z = s*.3; mesh(new THREE.SphereGeometry(.07,8,6),skin,s*.34,.42,0,head); }); const arm = s => { const sh = new THREE.Group(); sh.position.set(s*.74,1.0,0); torso.add(sh); mesh(new THREE.CylinderGeometry(.18,.16,.5,12),yel,0,-.25,0,sh); const el = new THREE.Group(); el.position.y = -.5; sh.add(el); mesh(new THREE.CylinderGeometry(.14,.115,.45,12),skin,0,-.22,0,el); const hd = new THREE.Group(); hd.position.y = -.47; el.add(hd); mesh(new THREE.BoxGeometry(.3,.34,.18),glove,0,-.12,0,hd); [-.09,0,.09].forEach(x => mesh(new THREE.BoxGeometry(.065,.2,.07),glove,x,-.34,0,hd)); return {sh,el}; }; const leg = s => { const hp = new THREE.Group(); hp.position.set(s*.2,-.15,0); hips.add(hp); mesh(new THREE.CylinderGeometry(.17,.12,.65,12),orng,0,-.32,0,hp); const kn = new THREE.Group(); kn.position.y = -.65; hp.add(kn); mesh(new THREE.CylinderGeometry(.12,.09,.65,12),orng,0,-.32,0,kn); const an = new THREE.Group(); an.position.y = -.65; kn.add(an); mesh(new THREE.BoxGeometry(.27,.17,.48),shoe,0,-.04,.1,an); mesh(new THREE.BoxGeometry(.29,.05,.5),M(0xffffff),0,-.12,.1,an); return {hp,kn}; }; const L = arm(-1), R = arm(1), lL = leg(-1), lR = leg(1); root.userData = {hips,torso,head,L,R,lL,lR}; root.scale.setScalar(.98); scene.add(root); return root; } const N = makeNeighbor(); /* Animation: locomotion cycle (walk -> jog with pumping fists, from the walk video) blended with an idle "searching" loop (head scan + hand-to-chin, from the idle video). */ const cur = {}; let phase = 0, spd = 0; function animateNeighbor(speed,dt,t){ spd += (speed-spd)*Math.min(1,dt*8); const k = clamp((spd-2)/4.5,0,1), ph = phase, s = Math.sin(ph), s2 = -s, c = Math.cos(ph); const amp = lerp(.55,.95,k), knee = lerp(.7,1.7,k), elb = lerp(-.5,-1.55,k), aSw = lerp(.5,.9,k); const loc = {hipY:1.35+Math.abs(c)*lerp(.03,.09,k), sway:s*.05, twist:s*lerp(.12,.28,k), lean:lerp(.06,.38,k), thL:-s*amp, thR:-s2*amp, knL:Math.max(0,c)*knee, knR:Math.max(0,-c)*knee, shL:s*aSw, shR:s2*aSw, elL:elb, elR:elb, headY:-s*.1, headX:-lerp(.02,.3,k)}; const cc = (t%6)/6, up = clamp((cc-.15)/.15,0,1)*(1-clamp((cc-.7)/.15,0,1)); const e = up*up*(3-2*up); // hand-to-chin beat const idle = {hipY:1.35+Math.sin(t*1.6)*.006, sway:0, twist:Math.sin(t*.5)*.08, lean:.04+Math.sin(t*1.6)*.01, thL:0, thR:0, knL:.02, knR:.02, shL:Math.sin(t*1.6)*.03, shR:lerp(0,-.75,e), elL:-.08, elR:lerp(-.08,-2.2,e), headY:Math.sin(t*.7)*.6, headX:.05+e*.18}; const w = clamp(spd/1.2,0,1), u = N.userData; for(const key in loc){ const tv = lerp(idle[key],loc[key],w); cur[key] = cur[key] === undefined ? tv : cur[key]+(tv-cur[key])*Math.min(1,dt*12); } u.hips.position.y = cur.hipY; u.hips.rotation.z = cur.sway; u.hips.rotation.y = -cur.twist*.6; u.torso.rotation.x = cur.lean; u.torso.rotation.y = cur.twist; u.head.rotation.y = cur.headY; u.head.rotation.x = cur.headX; u.lL.hp.rotation.x = cur.thL; u.lR.hp.rotation.x = cur.thR; u.lL.kn.rotation.x = cur.knL; u.lR.kn.rotation.x = cur.knR; u.L.sh.rotation.x = cur.shL; u.R.sh.rotation.x = cur.shR; u.L.el.rotation.x = cur.elL; u.R.el.rotation.x = cur.elR; } /* ---------- Neighbor AI ---------- */ const WP = [[16,12],[16,-14],[-17,-14],[-17,12],[0,18],[-2.6,0]]; // last waypoint is inside his house const DIN = {x:-3.9,z:3.9}, DOUT = {x:-3.9,z:9.6}; let via = 0, sv = 0; const SB = {x:-7.6*S,z:3.6*S}, ST = {x:-7.8*S,z:-3.0*S}; // stair bottom / top points const RAMP = {x0:-8.6*S,x1:-7.0*S,zT:-2.2*S,zB:4.0*S}, UPH = 4.15*S, HOLE = {x1:-6.7*S,z0:-2.2*S,z1:4.8*S}; let pFloor = 0, pLv = 0, nFloor = 0, nLv = 0, lastSeenLv = 0; const inHouse = (x,z) => (x>-11.7&&x<3.9&&z>-6.24&&z<6.24) || (x>=3.9&&x<12.35&&z>-4.81&&z<4.81); const inUpper = (x,z) => x>-8.6*S && x<2.8*S && z>-4.6*S && z<4.6*S && !(x<HOLE.x1 && z>HOLE.z0 && z<HOLE.z1); function surface(x,z,cur){ // height of the floor under (x,z): ground, stair ramp or upstairs if(x>RAMP.x0 && x<RAMP.x1 && z>RAMP.zT && z<RAMP.zB) return UPH*(RAMP.zB-z)/(RAMP.zB-RAMP.zT); return (cur > UPH*.5 && inUpper(x,z)) ? UPH : 0; } function route(p,tx,tz,tl){ // stairs inside the house, front door between inside and outside const pin = inHouse(p.x,p.z), tin = inHouse(tx,tz); const needStairs = pin && (tin ? nLv !== tl : nLv === 1); if(needStairs){ const a = nLv===0 ? SB : ST, b = nLv===0 ? ST : SB; if(!sv && Math.hypot(p.x-a.x,p.z-a.z) < 1.3) sv = 1; return sv ? [b.x,b.z] : [a.x,a.z]; } sv = 0; if(pin === tin){ via = 0; return [tx,tz]; } const a = pin ? DIN : DOUT, b = pin ? DOUT : DIN; if(!via && Math.hypot(p.x-a.x,p.z-a.z) < 1.5) via = 1; return via ? [b.x,b.z] : [a.x,a.z]; } let wi = 0, nState = 'patrol', wait = 0, lostT = 0, stuck = 0, steer = 0, steerT = 0; const lastSeen = new THREE.Vector3(); N.position.set(16,0,12); function updateNeighbor(dt,live,t){ const p = N.position, pl = camera.position; const dx = pl.x-p.x, dz = pl.z-p.z, dist = Math.hypot(dx,dz) || 1; const sameLv = nLv === pLv; let seen = false; if(live){ const inCone = (dx*Math.sin(N.rotation.y)+dz*Math.cos(N.rotation.y))/dist > Math.cos(D.fov); const clear = sameLv && los(p,pl); const sight = clear && dist < D.view && inCone; const heard = dist < (moving ? (crouch ? 1.5 : sprint ? 11 : 4.5) : 1.5) && (sameLv || dist < 5); const keep = nState === 'chase' && clear && dist < D.view*1.3; seen = sight || heard || keep; if(seen && nState !== 'chase'){ nState = 'chase'; lostT = 0; } if(seen){ lastSeen.copy(pl); lastSeenLv = pLv; lostT = 0; } else if(nState === 'chase'){ lostT += dt; if(lostT > D.lose) nState = 'patrol'; } if(dist < 1.5 && sameLv && state === 'play') return busted(); const st = $('status'); st.textContent = nState === 'chase' ? (seen ? 'SPOTTED!' : 'SEARCHING…') : (crouch ? 'Hidden' : 'Sneaking'); st.style.color = nState === 'chase' ? '#ff4a5a' : '#9dffb0'; $('danger').style.opacity = nState === 'chase' ? (seen ? 1 : .45) : 0; } let tx, tz, sp, tl = 0; if(nState === 'chase'){ const tg = seen ? pl : lastSeen; tx = tg.x; tz = tg.z; sp = D.chase; tl = seen ? pLv : lastSeenLv; if(!seen && Math.hypot(tx-p.x,tz-p.z) < 1.3 && nLv === tl) sp = 0; // reached last known spot: stand and search } else { const w = WP[wi]; tx = w[0]; tz = w[1]; sp = D.patrol; if(Math.hypot(tx-p.x,tz-p.z) < 1.8 && nLv === 0){ wait += dt; sp = 0; if(wait > 1.6){ wait = 0; wi = (wi+1)%WP.length; } } } if(sp > 0){ const rt = route(p,tx,tz,tl); tx = rt[0]; tz = rt[1]; } let moved = 0; if(sp > 0){ const want = Math.atan2(tx-p.x,tz-p.z) + steer; let da = want - N.rotation.y; da = Math.atan2(Math.sin(da),Math.cos(da)); N.rotation.y += da*Math.min(1,dt*7); const ox = p.x, oz = p.z; p.x += Math.sin(N.rotation.y)*sp*dt; p.z += Math.cos(N.rotation.y)*sp*dt; resolve(p,.7,nLv); moved = Math.hypot(p.x-ox,p.z-oz); if(moved < sp*dt*.35) stuck += dt; else stuck = Math.max(0,stuck-dt); if(stuck > .3 && steerT <= 0){ steer = (Math.random()<.5?-1:1)*1.3; steerT = .7; stuck = 0; } if(steerT > 0){ steerT -= dt; if(steerT <= 0) steer = 0; } } nFloor += (surface(p.x,p.z,nFloor)-nFloor)*Math.min(1,dt*12); nLv = nFloor > UPH*.5 ? 1 : 0; p.y = nFloor; const speed = dt > 0 ? moved/dt : 0; phase += moved*lerp(2.8,1.9,clamp((speed-2)/4.5,0,1)); animateNeighbor(speed,dt,t); } /* ---------- Player ---------- */ const controls = new THREE.PointerLockControls(camera,document.body); const keys = {}; let moving = false, sprint = false, crouch = false, bobT = 0, eye = 1.7, dragMode = false, hasKey = false; const START = new THREE.Vector3(0,1.7,44); addEventListener('keydown',e => { keys[e.code] = true; if(e.code === 'KeyC') crouch = !crouch; if(e.code === 'Escape') closeCredits(); if(state === 'cutscene' && (e.code === 'Space' || e.code === 'Enter')) endCutscene(); }); addEventListener('keyup',e => keys[e.code] = false); addEventListener('mousemove',e => { if(dragMode && state === 'play' && (e.buttons & 1)){ camera.rotation.y -= e.movementX*.0025; camera.rotation.x = clamp(camera.rotation.x - e.movementY*.0025,-1.4,1.4); } }); document.addEventListener('pointerlockerror',() => { dragMode = true; $('pause').style.display = 'none'; $('hint').textContent = 'Pointer lock unavailable: hold left mouse and drag to look.'; }); controls.addEventListener('lock',() => $('pause').style.display = 'none'); controls.addEventListener('unlock',() => { if(state === 'play' && !dragMode) $('pause').style.display = 'flex'; }); $('pause').onclick = () => controls.lock(); const paused = () => !(controls.isLocked || dragMode); function updatePlayer(dt){ sprint = !!(keys.ShiftLeft || keys.ShiftRight) && !crouch; const f = (keys.KeyW||keys.ArrowUp?1:0)-(keys.KeyS||keys.ArrowDown?1:0), s = (keys.KeyD||keys.ArrowRight?1:0)-(keys.KeyA||keys.ArrowLeft?1:0); const len = Math.hypot(f,s) || 1, sp = crouch ? 2 : sprint ? 7.2 : 4.2; moving = f !== 0 || s !== 0; controls.moveForward(f/len*sp*dt); controls.moveRight(s/len*sp*dt); pFloor += (surface(camera.position.x,camera.position.z,pFloor)-pFloor)*Math.min(1,dt*12); pLv = pFloor > UPH*.5 ? 1 : 0; resolve(camera.position,.45,pLv); camera.position.x = clamp(camera.position.x,-60,60); camera.position.z = clamp(camera.position.z,-60,64); eye += ((crouch?1.0:1.7)-eye)*Math.min(1,dt*10); if(moving) bobT += dt*sp*1.9; camera.position.y = pFloor + eye + (moving ? Math.sin(bobT)*.05 : Math.sin(performance.now()/900)*.01); } function checkGoals(){ if(!hasKey && camera.position.distanceTo(key.position) < 1.8){ hasKey = true; key.visible = keyLight.visible = false; $('objtxt').textContent = 'Red key found! Sneak to the basement door on the east side of the neighbor’s house.'; } const dd = Math.hypot(camera.position.x-BASEMENT.x,camera.position.z-BASEMENT.z); if(dd < 2.6){ if(hasKey){ state = 'over'; controls.unlock(); $('win').classList.add('show'); } else $('hint').textContent = 'Locked. Solve the riddle to find the red key.'; } else if(!dragMode) $('hint').textContent = ''; } /* ---------- Game flow ---------- */ let state = 'intro', trans = 0, t = 0, ct = 0; const fromPos = new THREE.Vector3(), fromQuat = new THREE.Quaternion(), toQuat = new THREE.Quaternion(); function sting(){ try{ const a = new (window.AudioContext||window.webkitAudioContext)(), o = a.createOscillator(), g = a.createGain(); o.type = 'sawtooth'; o.frequency.setValueAtTime(900,a.currentTime); o.frequency.exponentialRampToValueAtTime(60,a.currentTime+.7); g.gain.setValueAtTime(.5,a.currentTime); g.gain.exponentialRampToValueAtTime(.001,a.currentTime+.8); o.connect(g); g.connect(a.destination); o.start(); o.stop(a.currentTime+.85); }catch(e){} } function busted(){ state = 'over'; controls.unlock(); sting(); $('danger').style.opacity = 0; $('busted').classList.add('show'); } function reset(){ hasKey = false; key.visible = keyLight.visible = true; crouch = false; camera.position.copy(START); camera.rotation.set(0,0,0); N.position.set(16,0,12); nState = 'patrol'; wi = 0; lostT = 0; $('objtxt').innerHTML = OBJ0; pFloor = 0; pLv = 0; nFloor = 0; nLv = 0; sv = 0; via = 0; N.position.y = 0; $('busted').classList.remove('show'); $('win').classList.remove('show'); $('pause').style.display = 'none'; state = 'play'; if(!dragMode) controls.lock(); } $('retry').onclick = reset; $('again').onclick = reset; function applyQuality(q){ const pr = window.devicePixelRatio || 1; renderer.setPixelRatio(q==='low' ? 1 : q==='medium' ? Math.min(pr,1.5) : Math.min(pr,2)); renderer.shadowMap.enabled = q !== 'low'; renderer.shadowMap.type = q === 'high' ? THREE.PCFSoftShadowMap : THREE.PCFShadowMap; const sz = q === 'high' ? 2048 : 1024; if(sun.shadow.mapSize.x !== sz){ sun.shadow.mapSize.set(sz,sz); if(sun.shadow.map){ sun.shadow.map.dispose(); sun.shadow.map = null; } } scene.traverse(o => { if(o.material) o.material.needsUpdate = true; }); renderer.setSize(innerWidth,innerHeight); } $('lod').onchange = () => applyQuality($('lod').value); $('diff').onchange = () => D = DIFF[$('diff').value]; applyQuality('medium'); addEventListener('resize',() => { camera.aspect = innerWidth/innerHeight; camera.updateProjectionMatrix(); renderer.setSize(innerWidth,innerHeight); }); // Intro credits -> menu function toMenu(){ if(state !== 'intro') return; state = 'menu'; $('intro').classList.add('hide'); setTimeout(() => $('intro').style.display = 'none',1000); } setTimeout(toMenu,4800); $('intro').onclick = toMenu; // Credits screen from the menu $('credBtn').onclick = () => { $('credits').style.display = 'flex'; }; function closeCredits(){ $('credits').style.display = 'none'; } $('credits').onclick = closeCredits; // Start -> cinematic orbit of the neighbor's house -> glide to the player's porch $('start').onclick = () => { D = DIFF[$('diff').value]; applyQuality($('lod').value); $('menu').classList.add('hide'); setTimeout(() => $('menu').style.display = 'none',1000); $('bars').classList.add('on'); state = 'cutscene'; ct = 0; }; addEventListener('click',() => { if(state === 'cutscene' && ct > 1) endCutscene(); }); function endCutscene(){ fromPos.copy(camera.position); fromQuat.copy(camera.quaternion); toQuat.identity(); trans = 0; state = 'transition'; $('bars').classList.remove('on'); } function orbit(time){ const a = Math.PI/2 - time*.17, rad = 46 - time*.8; camera.position.set(Math.cos(a)*rad,8+Math.sin(time*.4)*3,Math.sin(a)*rad); camera.lookAt(1,6+Math.sin(time*.3)*1.5,0); } /* ---------- Main loop ---------- */ const clock = new THREE.Clock(); function loop(){ requestAnimationFrame(loop); const dt = Math.min(clock.getDelta(),.05); t += dt; key.rotation.y += dt*2; key.position.y = .9+Math.sin(t*2)*.12; if(state === 'cutscene'){ ct += dt; orbit(ct); updateNeighbor(dt,false,t); if(ct > 7) endCutscene(); } else if(state === 'transition'){ trans += dt/2.6; const k = Math.min(trans,1), e = k*k*(3-2*k); camera.position.lerpVectors(fromPos,START,e); camera.quaternion.copy(fromQuat).slerp(toQuat,e); updateNeighbor(dt,false,t); if(k >= 1){ state = 'play'; camera.rotation.set(0,0,0); $('hud').style.display = 'block'; controls.lock(); setTimeout(() => { if(state === 'play' && !controls.isLocked && !dragMode) $('pause').style.display = 'flex'; },500); } } else if(state === 'play' && !paused()){ updatePlayer(dt); updateNeighbor(dt,true,t); checkGoals(); } if(state !== 'intro' && state !== 'menu') renderer.render(scene,camera); } loop(); })();
Comments
0
Log in to join the discussion
…