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"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Roblox Web Obby - Fixed Physics</title> <style> body { margin: 0; overflow: hidden; background: #87CEEB; font-family: sans-serif; } #ui { position: absolute; top: 20px; left: 20px; color: white; text-shadow: 2px 2px 4px #000; font-size: 24px; pointer-events: none; z-index: 10; } #msg { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; background: rgba(0,0,0,0.8); padding: 30px; border-radius: 15px; text-align: center; cursor: pointer; z-index: 20; } </style> </head> <body> <div id="ui">Level: <span id="lvl-txt">1</span></div> <div id="msg"><h1>ROBLOX OBBY</h1><p>CLICK TO START</p><p>WASD to Move | Space to Jump</p></div> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.160.0/build/three.module.js" } } </script> <script type="module"> import * as THREE from 'three'; let scene, camera, renderer, clock, player, charModel, camPivot, portal; let platforms = [], currentLevel = 1; const keys = { w: false, a: false, s: false, d: false, space: false }; let velocity = new THREE.Vector3(), canJump = false; // Player height constants const PLAYER_HEIGHT = 1.0; init(); animate(); function init() { scene = new THREE.Scene(); scene.background = new THREE.Color(0x87CEEB); scene.fog = new THREE.Fog(0x87CEEB, 20, 200); clock = new THREE.Clock(); // Lighting scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 1.8)); const sun = new THREE.DirectionalLight(0xffffff, 1); sun.position.set(10, 50, 10); scene.add(sun); // Player Group player = new THREE.Group(); scene.add(player); // Camera Setup (Third Person) camPivot = new THREE.Group(); player.add(camPivot); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 6, 15); camera.lookAt(0, 2, 0); camPivot.add(camera); createNoob(); buildLevel(1); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Input Listeners document.addEventListener('keydown', (e) => { let key = e.code.toLowerCase().replace('key',''); if(key === 'space') keys.space = true; if(keys.hasOwnProperty(key)) keys[key] = true; }); document.addEventListener('keyup', (e) => { let key = e.code.toLowerCase().replace('key',''); if(key === 'space') keys.space = false; if(keys.hasOwnProperty(key)) keys[key] = false; }); document.body.addEventListener('click', () => { document.body.requestPointerLock(); document.getElementById('msg').style.display='none'; }); document.addEventListener('mousemove', (e) => { if(document.pointerLockElement) camPivot.rotation.y -= e.movementX * 0.005; }); window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); } function createNoob() { charModel = new THREE.Group(); const yellow = new THREE.MeshStandardMaterial({ color: 0xFFD700 }); const blue = new THREE.MeshStandardMaterial({ color: 0x0055FF }); const green = new THREE.MeshStandardMaterial({ color: 0x4CAF50 }); const torso = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.4, 0.7), blue); torso.position.y = 1.7; charModel.add(torso); const head = new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.8, 0.8), yellow); head.position.y = 2.8; charModel.add(head); const armL = new THREE.Mesh(new THREE.BoxGeometry(0.5, 1.4, 0.5), yellow); armL.position.set(-0.9, 1.7, 0); charModel.add(armL); const armR = armL.clone(); armR.position.x = 0.9; charModel.add(armR); const legL = new THREE.Mesh(new THREE.BoxGeometry(0.6, 1, 0.6), green); legL.position.set(-0.35, 0.5, 0); charModel.add(legL); const legR = legL.clone(); legR.position.x = 0.35; charModel.add(legR); player.add(charModel); } function buildLevel(num) { platforms.forEach(p => scene.remove(p)); platforms = []; if(portal) scene.remove(portal); if(num === 1) { spawnPlatform(0, 0, 0, 15, 1, 15, 0xaaaaaa); // Spawn spawnPlatform(0, 2, -20, 8, 1, 8, 0x9b59b6); // Purple spawnPlatform(10, 4, -30, 8, 1, 8, 0x3498db); // Blue createPortal(10, 5, -30); } else { // LEVEL 2 - RAINBOW OBBY spawnPlatform(0, 0, 0, 15, 1, 15, 0x3498db); const colors = [0xff0000, 0xffa500, 0xffff00, 0x008000, 0x0000ff, 0x4b0082]; for(let i=0; i<colors.length; i++) { spawnPlatform(-10 + (i*4), i*2, -20 - (i*6), 6, 0.6, 6, colors[i]); } // Spheres for(let i=0; i<4; i++) { const sphere = new THREE.Mesh(new THREE.SphereGeometry(2.5, 32, 32), new THREE.MeshStandardMaterial({color: 0x2ecc71})); sphere.position.set(10, 12, -60 - (i*10)); scene.add(sphere); platforms.push(sphere); } // Rainbow Tube (Inside floor) for(let i=0; i<25; i++) { spawnPlatform(0, 15, -100 - i, 6, 0.2, 1, i%2===0 ? 0xff0000 : 0xffff00); } spawnPlatform(0, 15, -135, 20, 1, 20, 0xffd700); // Winner Gold } player.position.set(0, 10, 0); // Spawn from sky velocity.set(0,0,0); } function spawnPlatform(x,y,z,w,h,d,color) { const p = new THREE.Mesh(new THREE.BoxGeometry(w,h,d), new THREE.MeshStandardMaterial({color: color})); p.position.set(x,y,z); scene.add(p); platforms.push(p); } function createPortal(x,y,z) { portal = new THREE.Mesh(new THREE.TorusGeometry(2.5, 0.3, 16, 100), new THREE.MeshBasicMaterial({color: 0x00ffff, wireframe: true})); portal.position.set(x,y+3,z); scene.add(portal); } function animate() { requestAnimationFrame(animate); const delta = Math.min(clock.getDelta(), 0.1); if (document.pointerLockElement) { // Gravity velocity.y -= 40 * delta; player.position.y += velocity.y * delta; // --- IMPROVED COLLISION --- canJump = false; const playerBox = new THREE.Box3().setFromCenterAndSize( player.position, new THREE.Vector3(1, 0.1, 1) // Small check at feet ); platforms.forEach(p => { const pBox = new THREE.Box3().setFromObject(p); // Check if player is above platform and falling into it if (player.position.x > pBox.min.x - 0.5 && player.position.x < pBox.max.x + 0.5 && player.position.z > pBox.min.z - 0.5 && player.position.z < pBox.max.z + 0.5) { if (player.position.y <= pBox.max.y + 0.1 && player.position.y >= pBox.max.y - 1.0) { if (velocity.y <= 0) { velocity.y = 0; player.position.y = pBox.max.y; canJump = true; } } } }); // Movement let mx = 0, mz = 0; if(keys.w) mz -= 1; if(keys.s) mz += 1; if(keys.a) mx -= 1; if(keys.d) mx += 1; if(mx !== 0 || mz !== 0) { const rot = camPivot.rotation.y; const dx = (mx * Math.cos(rot) + mz * Math.sin(rot)); const dz = (mz * Math.cos(rot) - mx * Math.sin(rot)); player.position.x += dx * 15 * delta; player.position.z += dz * 15 * delta; charModel.rotation.y = Math.atan2(dx, dz); } if(keys.space && canJump) { velocity.y = 18; canJump = false; } // Portal Transition if(portal && player.position.distanceTo(portal.position) < 4) { currentLevel = 2; document.getElementById('lvl-txt').innerText = "2"; buildLevel(2); } // Fall Off Respawn if(player.position.y < -30) buildLevel(currentLevel); } if(portal) portal.rotation.z += 0.05; renderer.render(scene, camera); } </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

2

Requests

2

Domains

262KB

Transfer Size

1253KB

Content Size

338.0ms

Dom Content Loaded

116.0ms

First Paint

338.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...