File size: 7,264 Bytes
80c0783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// 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