// Main JavaScript for SquirrelView 3D Sandbox Explorer // Initialize Feather Icons document.addEventListener('DOMContentLoaded', function() { feather.replace(); // Add smooth scrolling to all links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); // Add animation to feature cards on scroll const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('fade-in'); } }); }, observerOptions); document.querySelectorAll('.feature-card').forEach(card => { observer.observe(card); }); // Download button functionality const downloadButton = document.querySelector('button:contains("Download Full Script")'); if (downloadButton) { downloadButton.addEventListener('click', function() { // Create and trigger download of the Python script const pythonScript = `import ursina as u from ursina.prefabs.first_person_controller import FirstPersonController import os from ursina import scene class SquirrelViewSandbox: def __init__(self): # Initialize application self.app = u.Ursina() # Window settings u.window.title = "SquirrelView 3D Sandbox Explorer" u.window.borderless = False u.window.fullscreen = False # World setup self.setup_world() self.setup_player() self.setup_ui() self.setup_controller() def setup_world(self): # Create ground self.ground = u.Entity( model='plane', scale=(200, 1, 200), texture='white_cube', texture_scale=(40, 40), collider='box' ) # Sky self.sky = u.Sky() # Initial environment objects self.create_environment() def create_environment(self): # Trees for i in range(20): tree = u.Entity( model='cube', position=(u.random.uniform(-50, 50), 2, u.random.uniform(-50, 50)), scale=(1, 4, 1), color=u.color.brown ) # Buildings building_positions = [(-20, 0, -20), (20, 0, 20), (-20, 0, 20)] for pos in building_positions: building = u.Entity( model='cube', position=pos, scale=(5, 8, 5), color=u.color.gray ) # Squirrel NPC self.squirrel = u.Entity( model='cube', position=(10, 0.5, 0), scale=(1, 1, 1), color=u.color.orange, collider='box' ) def setup_player(self): # Player controller self.player = FirstPersonController() self.player.speed = 8 self.player.jump_height = 2 self.player.cursor.visible = False def setup_controller(self): # PS4 controller mapping self.controller_enabled = True def setup_ui(self): # HUD elements self.hud = u.Entity(parent=u.camera.ui) # Inventory panel (initially hidden) self.inventory_panel = u.Entity( parent=self.hud, model='quad', scale=(0.8, 0.6), position=(0, 0, -1), color=u.color.color(0, 0, 0, 0.8), enabled=False ) # Squirrel interaction dialog self.dialog_box = u.Entity( parent=self.hud, model='quad', scale=(0.6, 0.3), position=(0, 0.2, -1), color=u.color.color(0.1, 0.1, 0.1, 0.9), enabled=False ) def load_model(self, filepath): # Supported formats supported_formats = ['.glb', '.obj', '.stl'] file_ext = os.path.splitext(filepath)[1].lower() if file_ext in supported_formats: try: model = u.Entity( model=filepath, position=self.player.position + self.player.forward * 3, scale=1, collider='mesh' ) return model except Exception as e: print(f"Error loading model: {e}") return None else: print(f"Unsupported format: {file_ext}") return None def update(self): # Controller input handling if self.controller_enabled: self.handle_controller_input() # Squirrel interaction check self.check_squirrel_interaction() def handle_controller_input(self): # PS4 controller axis mapping if u.held_keys['gamepad left stick x']: self.player.x += u.time.dt * u.held_keys['gamepad left stick x'] * self.player.speed if u.held_keys['gamepad left stick y']: self.player.z += u.time.dt * u.held_keys['gamepad left stick y'] * self.player.speed # Button mappings if u.held_keys['gamepad a']: self.jump() if u.held_keys['gamepad x']: self.toggle_inventory() def check_squirrel_interaction(self): # Check if player is near squirrel distance = (self.player.position - self.squirrel.position).length() if distance < 3: self.show_dialog("Press X to open model loader!") if u.held_keys['gamepad x'] or u.held_keys['e']: self.open_model_loader() def show_dialog(self, message): self.dialog_box.enabled = True # Add text to dialog box here def open_model_loader(self): # Implement file browser for model loading pass def toggle_inventory(self): self.inventory_panel.enabled = not self.inventory_panel.enabled def run(self): self.app.run() # Start the application if __name__ == "__main__": sandbox = SquirrelViewSandbox() sandbox.run()`; const blob = new Blob([pythonScript], { type: 'text/x-python' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'squirrelview_sandbox.py'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); // Show success message alert('Python script downloaded successfully!'); }); } // Add loading animation to buttons document.querySelectorAll('button').forEach(button => { button.addEventListener('click', function() { const originalText = this