webgame-engine / index.html
iCoderX's picture
Make it edit the game inside the website itself - Follow Up Deployment
52b2423 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Cube with Sun Flare</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.hidden { display: none; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/objects/Lensflare.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
font-family: 'Inter', sans-serif;
}
canvas {
display: block;
}
#info {
position: absolute;
bottom: 20px;
width: 100%;
text-align: center;
color: white;
background-color: rgba(0,0,0,0.5);
padding: 10px;
border-radius: 8px;
max-width: 500px;
margin: 0 auto;
left: 0;
right: 0;
}
#loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 24px;
z-index: 1000;
}
</style>
</head>
<body class="bg-gray-900">
<div id="loading">Loading 3D scene...</div>
<div id="info" class="hidden">
<p>Click and drag to rotate view</p>
<p>Scroll to zoom in/out</p>
</div>
<div id="editor" class="fixed top-4 right-4 bg-gray-800 bg-opacity-90 p-4 rounded-lg text-white w-64">
<h2 class="text-xl font-bold mb-4">Scene Editor</h2>
<div class="mb-4">
<label class="block mb-2">Background Color</label>
<input type="color" id="bgColor" value="#87CEEB" class="w-full">
</div>
<div class="mb-4">
<label class="block mb-2">Model Rotation Speed</label>
<input type="range" id="rotationSpeed" min="0" max="0.1" step="0.001" value="0.005" class="w-full">
</div>
<div class="mb-4">
<label class="block mb-2">Sun Intensity</label>
<input type="range" id="sunIntensity" min="0" max="3" step="0.1" value="1.5" class="w-full">
</div>
<div class="mb-4">
<label class="block mb-2">Ambient Light</label>
<input type="range" id="ambientIntensity" min="0" max="2" step="0.1" value="0.8" class="w-full">
</div>
<button id="randomize" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded w-full">Randomize</button>
</div>
<script>
// Wait for everything to load
window.addEventListener('load', init);
// Global variables for editor
let model, scene, sunLight, ambientLight;
let rotationSpeed = 0.005;
function init() {
// Hide loading screen
document.getElementById('loading').style.display = 'none';
document.getElementById('info').classList.remove('hidden');
// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // Sky blue skybox
scene.fog = new THREE.FogExp2(0x87CEEB, 0.005); // Less dense fog
// Camera setup
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(5, 5, 5);
// Renderer setup
const renderer = new THREE.WebGLRenderer({
antialias: true,
powerPreference: "high-performance"
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.physicallyCorrectLights = true;
document.body.appendChild(renderer.domElement);
// Controls
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// Available sample models from KhronosGroup/glTF-Sample-Models:
// - Duck: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF/Duck.gltf
// - 2CylinderEngine: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/2CylinderEngine/glTF/2CylinderEngine.gltf
// - Avocado: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Avocado/glTF/Avocado.gltf
// - BarramundiFish: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BarramundiFish/glTF/BarramundiFish.gltf
// - BrainStem: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BrainStem/glTF/BrainStem.gltf
// - Buggy: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Buggy/glTF/Buggy.gltf
// - CesiumMan: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/CesiumMan/glTF/CesiumMan.gltf
// - Corset: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Corset/glTF/Corset.gltf
// - FlightHelmet: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/FlightHelmet/glTF/FlightHelmet.gltf
// - Lantern: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Lantern/glTF/Lantern.gltf
// - MosquitoInAmber: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/MosquitoInAmber/glTF/MosquitoInAmber.gltf
// - WaterBottle: https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/WaterBottle/glTF/WaterBottle.gltf
const loader = new THREE.GLTFLoader();
loader.load(
'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Avocado/glTF/Avocado.gltf',
(gltf) => {
const model = gltf.scene;
model.scale.set(0.5, 0.5, 0.5);
model.position.set(0, 0, 0);
model.rotation.y = Math.PI;
model.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(model);
// Animation loop
function animate() {
requestAnimationFrame(animate);
// Rotate model slightly
model.rotation.y += rotationSpeed;
// Update controls
controls.update();
// Render
renderer.render(scene, camera);
}
animate();
},
undefined,
(error) => {
console.error('Error loading model:', error);
// Fallback to simple geometry if model fails
const geometry = new THREE.ConeGeometry(1, 2, 4);
const material = new THREE.MeshStandardMaterial({ color: 0x00ffff });
const cone = new THREE.Mesh(geometry, material);
scene.add(cone);
}
);
// Ambient light matching skybox
const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
scene.add(ambientLight);
// Sun light (directional)
const sunLight = new THREE.DirectionalLight(0xffffcc, 1.5);
sunLight.position.set(10, 15, 10);
sunLight.castShadow = true;
sunLight.shadow.mapSize.width = 4096;
sunLight.shadow.mapSize.height = 4096;
sunLight.shadow.camera.near = 0.5;
sunLight.shadow.camera.far = 50;
sunLight.shadow.camera.left = -15;
sunLight.shadow.camera.right = 15;
sunLight.shadow.camera.top = 15;
sunLight.shadow.camera.bottom = -15;
sunLight.shadow.bias = -0.0001;
scene.add(sunLight);
// Fill light
const fillLight = new THREE.DirectionalLight(0xccffff, 0.5);
fillLight.position.set(-10, 10, -10);
scene.add(fillLight);
// Back light
const backLight = new THREE.DirectionalLight(0xffffff, 0.3);
backLight.position.set(0, 5, -15);
scene.add(backLight);
// Lens flare effect
const textureLoader = new THREE.TextureLoader();
const textureFlare0 = textureLoader.load('https://threejs.org/examples/textures/lensflare/lensflare0.png');
const textureFlare3 = textureLoader.load('https://threejs.org/examples/textures/lensflare/lensflare3.png');
const lensflare = new THREE.Lensflare();
lensflare.addElement(new THREE.LensflareElement(textureFlare0, 700, 0, sunLight.color));
lensflare.addElement(new THREE.LensflareElement(textureFlare3, 60, 0.6));
lensflare.addElement(new THREE.LensflareElement(textureFlare3, 70, 0.7));
lensflare.addElement(new THREE.LensflareElement(textureFlare3, 120, 0.9));
lensflare.addElement(new THREE.LensflareElement(textureFlare3, 70, 1));
sunLight.add(lensflare);
// Window resize handler
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Editor controls
document.getElementById('bgColor').addEventListener('input', (e) => {
scene.background = new THREE.Color(e.target.value);
});
document.getElementById('rotationSpeed').addEventListener('input', (e) => {
rotationSpeed = parseFloat(e.target.value);
});
document.getElementById('sunIntensity').addEventListener('input', (e) => {
sunLight.intensity = parseFloat(e.target.value);
});
document.getElementById('ambientIntensity').addEventListener('input', (e) => {
ambientLight.intensity = parseFloat(e.target.value);
});
document.getElementById('randomize').addEventListener('click', () => {
// Random colors
scene.background = new THREE.Color(Math.random() * 0xffffff);
sunLight.color.setHSL(Math.random(), 0.7, 0.5);
ambientLight.color.setHSL(Math.random(), 0.2, 0.8);
// Random rotation speed
rotationSpeed = Math.random() * 0.1;
document.getElementById('rotationSpeed').value = rotationSpeed;
// Random intensities
sunLight.intensity = Math.random() * 3;
ambientLight.intensity = Math.random() * 2;
document.getElementById('sunIntensity').value = sunLight.intensity;
document.getElementById('ambientIntensity').value = ambientLight.intensity;
});
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=iCoderX/webgame-engine" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>