import * as THREE from 'three'; import { OrbitControls } from 'https://unpkg.com/three@0.160.0/examples/jsm/controls/OrbitControls.js'; import { GLTFLoader } from 'https://unpkg.com/three@0.160.0/examples/jsm/loaders/GLTFLoader.js'; let scene, camera, renderer, controls, selectedObject, isPlaying = false; let gameObjects = []; function init() { scene = new THREE.Scene(); scene.background = new THREE.Color(0x222222); camera = new THREE.PerspectiveCamera(75, (window.innerWidth - 280) / window.innerHeight, 0.1, 1000); camera.position.set(5, 5, 5); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth - 280, window.innerHeight); document.getElementById('game-container').appendChild(renderer.domElement); controls = new OrbitControls(camera, renderer.domElement); const light = new THREE.HemisphereLight(0xffffff, 0x444444, 1.5); scene.add(light); animate(); } // Criar Cubo window.addBox = () => { const obj = new THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.MeshStandardMaterial({color: 0xcccccc})); setupObject(obj); }; // Configurar objeto na cena function setupObject(obj) { obj.position.y = 0.5; scene.add(obj); gameObjects.push(obj); selectObject(obj); } // Selecionar Objeto ao clicar window.addEventListener('mousedown', (e) => { if (isPlaying) return; const mouse = new THREE.Vector2((e.clientX - 280) / (window.innerWidth - 280) * 2 - 1, -(e.clientY / window.innerHeight) * 2 + 1); const raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(gameObjects, true); if (intersects.length > 0) selectObject(intersects[0].object); }); function selectObject(obj) { selectedObject = obj; document.getElementById('object-settings').style.display = 'block'; document.getElementById('posX').value = obj.position.x; document.getElementById('posY').value = obj.position.y; document.getElementById('posZ').value = obj.position.z; document.getElementById('scaleX').value = obj.scale.x; document.getElementById('scaleY').value = obj.scale.y; } // Atualizar Transform window.updateObject = () => { if (!selectedObject) return; selectedObject.position.set( parseFloat(document.getElementById('posX').value), parseFloat(document.getElementById('posY').value), parseFloat(document.getElementById('posZ').value) ); selectedObject.scale.set( parseFloat(document.getElementById('scaleX').value), parseFloat(document.getElementById('scaleY').value), selectedObject.scale.z ); }; // Aplicar Textura window.applyTexture = (input) => { if (input.files && input.files[0] && selectedObject) { const reader = new FileReader(); reader.onload = (e) => { const texture = new THREE.TextureLoader().load(e.target.result); selectedObject.material.map = texture; selectedObject.material.needsUpdate = true; }; reader.readAsDataURL(input.files[0]); } }; // Importar GLB document.getElementById('glb-upload').addEventListener('change', (e) => { const file = e.target.files[0]; const url = URL.createObjectURL(file); new GLTFLoader().load(url, (gltf) => { setupObject(gltf.scene); }); }); // Modo Jogo window.togglePlayMode = () => { isPlaying = !isPlaying; const btn = document.querySelector('.play-btn'); if (isPlaying) { btn.innerHTML = "⏹ PARAR JOGO"; btn.style.background = "#e74c3c"; document.getElementById('editor-sidebar').style.opacity = "0.3"; } else { btn.innerHTML = "▶ INICIAR JOGO"; btn.style.background = "#2ecc71"; document.getElementById('editor-sidebar').style.opacity = "1"; } }; function animate() { requestAnimationFrame(animate); if (isPlaying) { // Exemplo: no modo jogo, os objetos giram sozinhos gameObjects.forEach(o => o.rotation.y += 0.01); } renderer.render(scene, camera); } init();