4 models have responded to the "Autonomous Drone Simulator" challenge. Compare their approaches side-by-side on RIVAL. This response is part of RIVAL's open dataset of 5,600+ AI model responses.
Create an autonomous drone simulator with custom environment using ThreeJS
Create an autonomous drone simulator (drone flies by itself, isometric god like view, optionally interactive. With a custom environment (optionally creative), using ThreeJS, output a single-page self-contained HTML.
Couldn't render this response
This model didn't return a displayable web page for this challenge.
I'll create an autonomous drone simulator with a futuristic neon city environment. The drone will navigate automatically through waypoints while avoiding obstacles, and you can interact with it by clicking to set new destinations.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Autonomous Drone Simulator</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
overflow: hidden;
background: #000;
}
#canvas-container {
position: relative;
width: 100vw;
height: 100vh;
}
.ui-panel {
position: absolute;
background: rgba(0, 0, 0, 0.8);
border: 1px solid #00ffff;
border-radius: 10px;
padding: 20px;
color: #00ffff;
font-size: 14px;
backdrop-filter: blur(10px);
box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
}
.status-panel {
top: 20px;
left: 20px;
min-width: 250px;
}
.controls-panel {
top: 20px;
right: 20px;
min-width: 200px;
}
.info-panel {
bottom: 20px;
left: 20px;
max-width: 400px;
}
.status-item {
margin: 10px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.status-label {
color: #00cccc;
}
.status-value {
font-weight: bold;
color: #00ff88;
}
.control-btn {
background: linear-gradient(135deg, #00ffff, #0088ff);
border: none;
border-radius: 5px;
padding: 10px 20px;
color: #000;
font-weight: bold;
cursor: pointer;
margin: 5px;
transition: all 0.3s ease;
font-size: 14px;
}
.control-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 255, 255, 0.5);
}
.control-btn:active {
transform: translateY(0);
}
.control-btn.active {
background: linear-gradient(135deg, #ff00ff, #ff0088);
}
.slider-container {
margin: 15px 0;
}
.slider {
width: 100%;
height: 5px;
border-radius: 5px;
background: #333;
outline: none;
-webkit-appearance: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #00ffff;
cursor: pointer;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: #00ffff;
cursor: pointer;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}
.waypoint-indicator {
position: absolute;
width: 20px;
height: 20px;
background: radial-gradient(circle, #ff00ff, transparent);
border-radius: 50%;
pointer-events: none;
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(2); opacity: 0; }
}
.title {
font-size: 24px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}
.speed-indicator {
width: 100%;
height: 8px;
background: #333;
border-radius: 4px;
overflow: hidden;
margin-top: 5px;
}
.speed-bar {
height: 100%;
background: linear-gradient(90deg, #00ff00, #ffff00, #ff0000);
transition: width 0.3s ease;
border-radius: 4px;
}
</style>
</head>
<body>
<div id="canvas-container">
<div class="ui-panel status-panel">
<div class="title">DRONE STATUS</div>
<div class="status-item">
<span class="status-label">Mode:</span>
<span class="status-value" id="mode">AUTONOMOUS</span>
</div>
<div class="status-item">
<span class="status-label">Altitude:</span>
<span class="status-value" id="altitude">0m</span>
</div>
<div class="status-item">
<span class="status-label">Speed:</span>
<span class="status-value" id="speed">0 m/s</span>
</div>
<div class="speed-indicator">
<div class="speed-bar" id="speed-bar" style="width: 0%"></div>
</div>
<div class="status-item">
<span class="status-label">Waypoint:</span>
<span class="status-value" id="waypoint">1/5</span>
</div>
<div class="status-item">
<span class="status-label">Battery:</span>
<span class="status-value" id="battery">100%</span>
</div>
</div>
<div class="ui-panel controls-panel">
<div class="title">CONTROLS</div>
<button class="control-btn active" id="auto-btn">AUTO MODE</button>
<button class="control-btn" id="manual-btn">MANUALbutton>
<button class="control-btn" id="reset-btn">RESET</button>
<button class="control-btn" id="add-waypoint">ADD WAYPOINT</button>
<div class="slider-container">
<label class="status-label">Speed Multiplier</label>
<input type="range" class="slider" id="speed-slider" min="0.5" max="3" step="0.1" value="1">
<span class="status-value" id="speed-value">1.0x</span>
</div>
<div class="slider-container">
<label class="status-label">Camera Height</label>
<input type="range" class="slider" id="height-slider" min="50" max="200" step="10" value="100">
<span class="status-value" id="height-value">100m</span>
</div>
</div>
<div class="ui-panel info-panel">
<div class="title">INSTRUCTIONS</div>
<p style="color: #00cccc; line-height: 1.5;">
🚁 The drone flies autonomously through waypoints in the neon city.<br>
🖱️ Click anywhere to add a new waypoint.<br>
🎮 Use controls to switch between auto/manual mode.<br>
⚡ Adjust speed and camera height with sliders.<br>
🎯 Watch as the drone avoids obstacles automatically.
</p>
</div>
</div>
<script>
// Scene setup
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x000000, 50, 300);
// Camera setup (isometric view)
const camera = new THREE.OrthographicCamera(
window.innerWidth / -50,
window.innerWidth / 50,
window.innerHeight / -50,
window.innerHeight / 50,
1,
500
);
camera.position.set(50, 100, 50);
camera.lookAt(0, 0, 0);
// Renderer setup
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.getElementById('canvas-container').appendChild(renderer.domElement);
// Lighting
const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(50, 100, 50);
directionalLight.castShadow = true;
directionalLight.shadow.camera.left = -100;
directionalLight.shadow.camera.right = 100;
directionalLight.shadow.camera.top = 100;
directionalLight.shadow.camera.bottom = -100;
scene.add(directionalLight);
// Ground
const groundGeometry = new THREE.PlaneGeometry(200, 200);
const groundMaterial = new THREE.MeshStandardMaterial({
color: 0x0a0a0a,
roughness: 0.8,
metalness: 0.2
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// Grid helper
const gridHelper = new THREE.GridHelper(200, 40, 0x00ffff, 0x004444);
scene.add(gridHelper);
// Drone class
class Drone {
constructor() {
this.group = new THREE.Group();
// Drone body
const bodyGeometry = new THREE.BoxGeometry(2, 0.5, 2);
const bodyMaterial = new THREE.MeshStandardMaterial({
color: 0x00ffff,
emissive: 0x004444,
emissiveIntensity: 0.5
});
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
body.castShadow = true;
this.group.add(body);
// Drone arms and rotors
const armGeometry = new THREE.BoxGeometry(3, 0.2, 0.2);
const armMaterial = new THREE.MeshStandardMaterial({ color: 0x333333 });
const rotorGeometry = new THREE.CylinderGeometry(1, 1, 0.1, 8);
const rotorMaterial = new THREE.MeshStandardMaterial({
color: 0x666666,
emissive: 0x00ff00,
emissiveIntensity: 0.3
});
this.rotors = [];
for (let i = 0; i < 4; i++) {
const angle = (Math.PI / 2) * i;
const arm = new THREE.Mesh(armGeometry, armMaterial);
arm.position.x = Math.cos(angle) * 1.5;
arm.position.z = Math.sin(angle) * 1.5;
arm.rotation.y = angle;
this.group.add(arm);
const rotor = new THREE.Mesh(rotorGeometry, rotorMaterial);
rotor.position.x = Math.cos(angle) * 1.5;
rotor.position.z = Math.sin(angle) * 1.5;
rotor.position.y = 0.3;
rotor.rotation.x = Math.PI / 2;
this.group.add(rotor);
this.rotors.push(rotor);
}
// LED lights
const ledGeometry = new THREE.SphereGeometry(0.1, 8, 8);
const ledMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const led = new THREE.Mesh(ledGeometry, ledMaterial);
led.position.y = -0.3;
this.group.add(led);
this.position = new THREE.Vector3(0, 20, 0);
this.velocity = new THREE.Vector3(0, 0, 0);
this.targetPosition = new THREE.Vector3(0, 20, 0);
this.waypoints = [];
this.currentWaypointIndex = 0;
this.speed = 0.5;
this.battery = 100;
this.mode = 'auto';
this.rotorSpeed = 0;
scene.add(this.group);
}
update(deltaTime) {
// Update rotor rotation
this.rotors.forEach((rotor, index) => {
rotor.rotation.z += this.rotorSpeed * (index % 2 === 0 ? 1 : -1);
});
if (this.mode === 'auto' && this.waypoints.length > 0) {
// Navigate to current waypoint
const target = this.waypoints[this.currentWaypointIndex];
const direction = new THREE.Vector3()
.subVectors(target, this.position)
.normalize();
const distance = this.position.distanceTo(target);
if (distance > 2) {
this.velocity = direction.multiplyScalar(this.speed);
} else {
// Reached waypoint, move to next
this.currentWaypointIndex = (this.currentWaypointIndex + 1) % this.waypoints.length;
this.velocity.multiplyScalar(0.1);
}
}
// Apply velocity with some smoothing
this.position.add(this.velocity);
this.velocity.multiplyScalar(0.95);
// Update battery
this.battery -= deltaTime * 0.5;
if (this.battery < 0) this.battery = 0;
// Update rotor speed based on movement
this.rotorSpeed = this.velocity.length() * 20 + 5;
// Update drone visual position
this.group.position.copy(this.position);
this.group.rotation.y = Math.atan2(this.velocity.x, this.velocity.z);
// Keep drone above ground
if (this.position.y < 5) {
this.position.y = 5;
this.velocity.y = Math.abs(this.velocity.y) * 0.5;
}
}
addWaypoint(position) {
this.waypoints.push(position.clone());
}
setWaypoints(points) {
this.waypoints = points.map(p => p.clone());
this.currentWaypointIndex = 0;
}
reset() {
this.position.set(0, 20, 0);
this.velocity.set(0, 0, 0);
this.battery = 100;
this.currentWaypointIndex = 0;
}
}
// Building creation
function createBuilding(x, z, width, height, depth) {
const geometry = new THREE.BoxGeometry(width, height, depth);
const material = new THREE.MeshStandardMaterial({
color: new THREE.Color().setHSL(Math.random() * 0.1 + 0.5, 0.5, 0.3),
emissive: new THREE.Color().setHSL(Math.random() * 0.1 + 0.5, 0.8, 0.2),
emissiveIntensity: 0.3
});
const building = new THREE.Mesh(geometry, material);
building.position.set(x, height / 2, z);
building.castShadow = true;
building.receiveShadow = true;
// Add windows
const windowGeometry = new THREE.PlaneGeometry(width * 0.8, height * 0.05);
const windowMaterial = new THREE.MeshBasicMaterial({
color: 0x00ffff,
emissive: 0x00ffff,
emissiveIntensity: 0.8
});
for (let i = 0; i < Math.floor(height / 5); i++) {
const window = new THREE.Mesh(windowGeometry, windowMaterial);
window.position.set(0, i * 5 - height / 2 + 2.5, depth / 2 + 0.01);
building.add(window);
}
scene.add(building);
return building;
}
// Create city environment
function createCity() {
const buildings = [];
// Create buildings in a grid pattern
for (let x = -80; x <= 80; x += 20) {
for (let z = -80; z <= 80; z += 20) {
if (Math.random() > 0.3) {
const height = Math.random() * 30 + 10;
const width = Math.random() * 10 + 10;
const depth = Math.random() * 10 + 10;
buildings.push(createBuilding(x, z, width, height, depth));
}
}
}
// Create some neon towers
for (let i = 0; i < 5; i++) {
const angle = (Math.PI * 2 / 5) * i;
const x = Math.cos(angle) * 60