Qwen: Qwen3 235B A22B 2507 vs MiniMax M1
Compare Qwen: Qwen3 235B A22B 2507 by Qwen against MiniMax M1 by MiniMax, tested across 19 shared challenges. Updated February 2026.
Compare Qwen: Qwen3 235B A22B 2507 by Qwen against MiniMax M1 by MiniMax, tested across 19 shared challenges. Updated February 2026.
19 challenges
Tests an AI's randomness and creativity
Unique count: 5/5 (All jokes are distinct in structure, topic, and punchline).
Tests an AI's ability to create detailed SVG illustrations of gaming hardware
Tests an AI's ability to generate a complete, working landing page
Recreate an interactive, classic Mario level in a single HTML file.
Couldn't render this response
This model didn't return a displayable web page for this challenge.
<!DOCTYPE html>
<html>
<head>
<title>Super Mario Bros. Level</title>
>
<style>
body {
margin: 0;
overflow: hidden;
background: #87CEEB;
font-family: 'Press Start 2P', system-ui, -apple-system, sans-serif;
}
#gameCanvas {
display: block;
margin: 0 auto;
background: #87CEEB;
}
#score {
position: absolute;
top: 20px;
left: 20px;
color: white;
font-size: 20px;
text-shadow: 2px 2px 0 #000;
}
#instructions {
position: absolute;
bottom: 20px;
left: 20px;
color: white;
font-size: 14px;
text-shadow: 1px 1px 0 #000;
}
</style>
>
</head>
<body<body>
<div id="score">SCORE: 0</div>
<div id="instructions">←→ TO MOVE | ↑ TO JUMP | REACH THE FLAG!!</div>
<canvas id="gameCanvas" width="800" height="600">"></canvas>
>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let score = 0;
const gravity = 0.5;
const friction = 0.8;
// Game objects
const mario = {
x: 50,
y: 450,
width: 40,
height: 60,
speed: 5,
velX: 0,
velY: 0,
grounded: false,
jumping: false,
color: '#FF0000'
};
const platforms = [
{ x: 0, y: 550, width: 800, height: 50, color: '#8B4513' }, // Ground
{ x: 200, y: 450, width: 100, height: 20, color: '#8B4513' }, // Platform 1
{ x: 400, y: 350, width: 100, height: 20, color: '#8B4513' }, // Platform 2
{ x: 600, y: 250, width: 100, height: 20, color: '#8B4513' } // Platform 3
];
const enemies = [
{ x: 250, y: 430, width: 30, height: 30, velX: 2, color: '#000000' },
{ x: 450, y: 330, width: 30, height: 30, velX: 2, color: '#000000' },
{ x: 650, y: 230, width: 30, height: 30, velX: 2, color: '#000000' }
];
const coins = [
{ x: 220, y: 430, width: 20, height: 20, collected: false, color: '#FFD700' },
{ x: 420, y: 330, width: 20, height: 20, collected: false, color: '#FFD700' },
{ x: 620, y: 230, width: 20, height: 20, collected: false, color: '#FFD700' }
];
const flag = { x: 700, y: 200, width: 30, height: 50, color: '#00FF00' };
// Input handling
const keys = {};
document.addEventListener('keydown', e => keys[e.key] = true);
document.addEventListener('keyup', e => keys[e.key] = false);
// Game loop
function gameLoop() {
// Clear canvas
ctx.fillStyle = '#87CEEB';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw clouds
drawClouds();
// Update Mario
updateMario();
// Update enemies
updateEnemies();
// Check collisions
checkCollisions();
// Draw game elements
drawGameElements();
requestAnimationFrame(gameLoop);
}
function updateMario() {
// Movement
if (keys['ArrowLeft']) mario.velX = -mario.speed;
if (keys['ArrowRight']) mario.velX = mario.speed;
if (keys['ArrowUp'] && mario.grounded) {
mario.velY = -12;
mario.grounded = false;
}
// Physics
mario.velX *= friction;
mario.velY += gravity;
mario.x += mario.velX;
mario.y += mario.velY;
// Boundaries
if (mario.x < 0) mario.x = 0;
if (mario.x + mario.width > canvas.width) mario.x = canvas.width - mario.width;
// Reset if fallen off
if (mario.y > canvas.height) {
mario.x = 50;
mario.y = 450;
mario.velY = 0;
}
// Platform collision
mario.grounded = false;
platforms.forEach(p => {
if (mario.x + mario.width > p.x &&
mario.x < p.x + p.width &&
mario.y + mario.height >= p.y &&
mario.y + mario.height <= p.y + 10 &&
mario.velY > 0) {
mario.grounded = true;
mario.y = p.y - mario.height;
mario.velY = 0;
}
});
}
function updateEnemies() {
enemies.forEach((e, index) => {
e.x += e.velX;
// Platform collision
platforms.forEach(p => {
if (e.x + e.width > p.x &&
e.x < p.x + p.width &&
e.y + e.height >= p.y &&
e.y + e.height <= p.y + 5) {
if (e.x <= p.x || e.x + e.width >= p.x + p.width) {
e.velX *= -1;
}
}
});
});
}
function checkCollisions() {
// Enemy collision
enemies.forEach((e, index) => {
if (mario.x + mario.width > e.x &&
mario.x < e.x + e.width &&
mario.y + mario.height > e.y &&
mario.y < e.y + e.height) {
if (mario.velY > 0 && mario.y + mario.height < e.y + e.height) {
enemies.splice(index, 1);
mario.velY = -10;
score += 20;
} else {
mario.x = 50;
mario.y = 450;
mario.velY = 0;
}
}
});
// Coin collection
coins.forEach(c => {
if (!c.collected &&
mario.x + mario.width > c.x &&
mario.x < c.x + c.width &&
mario.y + mario.height > c.y &&
mario.y < c.y + c.height) {
c.collected = true;
score += 10;
}
});
// Flag collision (win condition)
if (mario.x + mario.width > flag.x &&
mario.x < flag.x + flag.width &&
mario.y + mario.height > flag.y &&
mario.y < flag.y + flag.height) {
alert('YOU WIN!\nSCORE: ' + score + '');
resetGame();
}
// Update score display
document.getElementById('score').textContent = 'SCORE: ' + score + '';
}
function drawGameElements() {
// Draw platforms
platforms.forEach(p => {
ctx.fillStyle = p.color;
ctx.fillRect(p.x, p.y, p.width, p.height);
});
// Draw coins
coins.forEach(c => {
if (!c.collected) {
ctx.fillStyle = c.color;
ctx.beginPath();
ctx.arc(c.x + 10, c.y + 10, 10, 0, Math.PI * 2);
ctx.fill();
}
});
// Draw enemies
enemies.forEach(e => {
ctx.fillStyle = e.color;
ctx.fillRect(e.x, e.y, e.width, e.height);
// Draw eyes
ctx.fillStyle = 'white';
ctx.fillRect(e.x + 7, e.y + 8, 5, 5);
ctx.fillRect(e.x + 18, e.y + 8, 5, 5);
});
// Draw flag
ctx.fillStyle = flag.color;
ctx.fillRect(flag.x, flag.y, flag.width, flag.height);
// Flag pole
ctx.strokeStyle = '#654321';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(flag.x, 250);
ctx.lineTo(flag.x, flag.y);
ctx.stroke();
// Draw Mario
ctx.fillStyle = mario.color;
ctx.fillRect(mario.x, mario.y, mario.width, mario.height);
// Mario eyes
ctx.fillStyle = 'white';
ctx.fillRect(mario.x + 10, mario.y + 15, 8, 8);
ctx.fillRect(mario.x + 22, mario.y + 15, 8, 8);
}
function drawClouds() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
// Cloud 1
ctx.beginPath();
ctx.arc(100, 100, 20, 0, Math.PI * 2);
ctx.arc(130, 90, 20, 0, Math.PI * 2);
ctx.arc(160, 100, 20, 0, Math.PI * 2);
ctx.fill();
// Cloud 2
ctx.beginPath();
ctx.arc(600, 150, 20, 0, Math.PI * 2);
ctx.arc(630, 140, 20, 0, Math.PI * 2);
ctx.arc(660, 150, 20, 0, Math.PI * 2);
ctx.fill();
}
function resetGame() {
mario.x = 50;
mario.y = 450;
mario.velY = 0;
coins.forEach(c => c.collected = false);
score = 0;
enemies.push(
{ x: 250, y: 430, width: 30, height: 30, velX: 2, color: '#000000' },
{ x: 450, y: 330, width: 30, height: 30, velX: 2, color: '#000000' },
{ x: 650, y: 230, width: 30, height: 30, velX: 2, color: '#000000' }
);
}
// Start game
gameLoop();
</script>
>
</body>
</htmlhtml>Generate a single-page, self-contained HTML webapp using Tailwind CSS for a randomly chosen category/industry/niche.
Generate SVG art of a randomly chosen animal in a setting of its choosing.
Generate a unique and simple recipe with common ingredients.
Create a starter plan for improving long-term health.
Recreate a classic, retro, macOS Desktop UI — make it interactive and nostalgic, make it as interactive as you can, you can be creative.. Feel free to showcase your skills. The entire application must be a single-page self-contained HTML file.
Develop a cutting-edge 3-month longevity plan for a biohacker.
Comprehensive 3-Month Longevity & Biohacking Optimization Plan
For the Advanced Biohacker — Maximize Longevity, Physical & Cognitive Performance
This 3-month protocol integrates cutting-edge longevity science with personalized biohacking strategies. It is grounded in the hallmarks of aging, including mitochondrial health, cellular senescence, epigenetic regulation, inflammation control, and proteostasis. The plan emphasizes precision tracking, nutritional periodization, time-controlled stress (hormesis), mitochondrial optimization, and neuroplasticity enhancement.
Target Audience: Experienced biohackers with a baseline of fitness, lab-tested biomarkers, and familiarity with supplements and tracking devices.
Key Pillars:
Goal: Establish baselines, optimize metabolic flexibility, reduce inflammation, begin epigenetic reset.
Diet Style: Cyclical Ketogenic Diet (CKD) with Carb-Backloading
Macronutrient Targets (Keto Days):
Carb Sources (Re-Feed Days): Sweet potatoes, white rice, fruit, squash
Fasting Regimen:
Key Foods:
Hydration & Electrolytes:
All supplements non-GMO, third-party tested. Take with fats for fat-soluble compounds.
Daily Stack (All Month):
| Supplement | Dose | Timing | Notes |
|---|---|---|---|
| Omega-3 (EPA/DHA 2:1) | 3g | With lunch | Algae or fish, IFOS-certified |
| Vitamin D3 + K2 (MK-7) | 5000 IU D3 + 200mcg K2 | With breakfast | Adjust based on blood test (target 50–80 ng/mL) |
| Magnesium L-Threonate | 144mg elemental Mg | 1h before bed | Crosses BBB, enhances sleep |
| Zinc Picolinate | 25mg | With dinner | Cycle 5 days on, 2 off |
| Lithium Orotate | 5mg | At night | Neuroprotective, telomere support |
Ketosis & Mitochondrial Support Stack:
| Supplement | Dose | Timing | Notes |
|---|---|---|---|
| MCT Oil (C8) | 15–30g | Morning in coffee/tea | Start low, increase over first 2 weeks |
| Exogenous Ketones (BHB Na/K) | 5–10g | Pre-workout or fast | Enhances cognition, spares glucose |
| CoQ10 (Ubiquinol) | 200mg | With lunch | Mitochondrial electron transport |
| PQQ (Pyrroloquinoline quinone) | 20mg | With breakfast | Stimulates mitochondrial biogenesis |
| ALCAR (Acetyl-L-Carnitine) | 1.5g | Morning | Fatty acid transport into mitochondria |
Inflammation & Senescence Control:
| Supplement | Dose | Timing | Notes |
|---|---|---|---|
| Fisetin | 500mg | 3 days/month (Days 1–3) | Senolytic — clears senescent cells |
| Quercetin + Bromelain | 500mg + 250mg | With fisetin days | Enhances senolytic effect |
| Curcumin (Longvida®) | 400mg | With dinner | Blood-brain barrier penetrating, anti-inflammatory |
Cognitive Enhancers (Daily):
| Supplement | Dose | Timing | Notes |
|---|---|---|---|
| Lion’s Mane (8:1 extract) | 1g | Morning | NGF stimulation, neurogenesis |
| Bacopa Monnieri (50% bacosides) | 300mg | With breakfast | Memory, acetylcholine modulation |
| L-Theanine + Caffeine (2:1) | 200mg + 100mg | Pre-work or focus block | Focus without jitters |
Devices:
Daily Tracking Metrics:
Weekly Schedule:
| Day | Focus | Workout |
|---|---|---|
| Mon | Strength (Upper) | 5x5 Bench, Pull-Ups, Overhead Press, Rows |
| Tue | HIIT + Core | 8x30s sprint (bike/row), 15-min EMOM core |
| Wed | Re-Feed + Active Recovery | 45-min zone 2 cardio (walk/bike), foam roll |
| Thu | Strength (Lower) | 5x5 Squats, Deadlifts, Leg Press, Calf Raises |
| Fri | Metabolic Conditioning | 20-min AMRAP: KB swings, burpees, push-ups |
| Sat | Long Zone 2 | 90-min brisk walk or hike (fasted, pre-noon) |
| Sun | Complete Rest or Yoga | 30-min Yin Yoga + breathwork |
Guidelines:
HRV Training (Daily):
Neurofeedback Concepts (At-Home):
Cognitive Training:
Cold Exposure:
Protocol:
Supplements (30 min before bed):
Goal: Enhance mitochondrial biogenesis, amplify autophagy, increase neuroplasticity.
Goal: Consolidate gains, test performance, refine for long-term sustainability.
Supplement Cycling:
Fasting Maintenance:
Exercise: Continue periodized model, rotate in new stimuli (e.g., parkour, dance)
Tracking:
This 3-month protocol merges precision nutrition, epigenetic modulation, mitochondrial optimization, and cognitive engineering. By integrating real-time data from wearables and labs, the biohacker can personalize and evolve the plan indefinitely. The goal is not just lifespan extension, but healthspan maximization — peak function at 100.
Remember: Longevity is not a sprint. This plan is a launchpad. Iterate, measure, and optimize for life.
Authored with reference to: Rhonda Patrick, Peter Attia, David Sinclair, Andrew Huberman, and clinical longevity research (2020–2024).
Integrating cutting-edge strategies for physical, cognitive, and cellular health.
Goal: Establish baseline metrics, initiate core protocols, and build habits.
Dosages and cycling to maximize efficacy and minimize tolerance.
Cycling Notes:
Ketogenic cycling with fasting for metabolic flexibility and autophagy.
Strength, HIIT, and recovery for mitochondrial health and muscle retention.
Data-driven adjustments for personalized optimization.
HRV training, breathwork, and cold exposure.
Goal: Refine protocols using data, enhance cognitive performance, and deepen autophagy.
Goal: Push performance, refine biomarkers, and integrate cutting-edge biohacks.
This plan balances aggressive longevity strategies with adaptability, leveraging wearables and biomarkers for precision. Always consult a healthcare provider before starting new supplements or protocols.
Design an innovative, multi-component dish worthy of a 3-star Michelin restaurant.
Dish Title: Ember & Petal – A Dialogue Between Earth and Sky
Conceptual Narrative:
Inspired by the elemental contrast between volcanic resurgence and alpine serenity, Ember & Petal explores the tension and harmony of opposing natural forces through taste, texture, and temperature. The dish juxtaposes the deep, umami-rich essence of black garlic—slow-fermented over 40 days—against the ethereal lightness of wild alpine gentian flowers, foraged at peak bloom. Drawing from Japanese kaiseki philosophy and modernist French technique, the dish unfolds in three movements: Earth (fermentation, fire, depth), Air (aromatics, suspension, levity), and Sky (crystalline textures, floral purity). Each component is meticulously engineered to dissolve on the palate while evoking a sensory journey from subterranean warmth to mountain air.
Earth’s Embrace – Umami Caramel with Volcanic Depth
Ingredients:
Technique: Spherification with Fermented Base
Sourcing Note: Black garlic should be sourced from a specialty fermentation producer (e.g., La Belle Mère, France, or Black Garlic Co., UK) ensuring uniform 40-day enzymatic aging. Wild-foraged gentian flowers must be gathered sustainably from alpine regions (e.g., French Alps or Swiss Jura) at 2,000m elevation during July bloom.
Air’s Whisper – Aromatic Foam with Smoky Undertone
Ingredients:
Technique: Emulsified Aromatic Air
Plating Role: This foam is piped at the table via a tempered glass cloche, creating an ephemeral “mist” that settles over the dish like morning fog over mountains.
Rooted Texture – Earthy Crumble with Gilded Fragility
Ingredients:
Technique: Dehydrated Soil Matrix
Sourcing Note: Sunchoke variety Fuseau preferred for nutty flavor. Duck fat from Label Rouge French Moulard duck. White tea must be first flush Gyokuro from Uji, Japan.
Sky’s Core – Delicate Custard with Alpine Clarity
Ingredients:
Technique: Clarified Infusion & Encapsulation
Result: A quivering orb of golden yolk suspended in translucent, faintly tart gelée—resembling a dewdrop on a petal.
Plate: Hand-thrown black stoneware by ceramicist (resembles cooled lava flow), pre-chilled.
Sequence:
Garnish: One fresh gentian blossom (edible, deep blue), placed with tweezers.
Accompaniment: Served with a warm spoon of black garlic dashi (strained, reduced with kelp) poured around the base just before eating.
Ember & Petal is not merely a dish—it is a geological poem, a meditation on transformation, and a testament to the alchemy of fire, time, and altitude.
Dish Name: Oceanic Harmony: Scallop, Yuzu, and Black Garlic
Conceptual Narrative:
This dish embodies the interplay between land and sea, inspired by the Japanese philosophy of shinrin-yoku (forest bathing). The Hokkaido scallop represents the ocean’s bounty, while black garlic (a fermented, earthy ingredient) and yuzu (a citrus fruit) bridge terrestrial and marine elements. A celery root puree adds creaminess, black truffle introduces luxury, and seaweed salad evokes coastal flora. Edible flowers mirror the colors of a forest meadow, creating a dish that is both visually stunning and narratively cohesive.
(Serves 4)
Ingredients:
Technique:
Ingredients:
Technique:
Ingredients:
Technique:
Ingredients:
Technique:
Ingredients:
Technique:
Ingredients:
Assembly:
This dish balances technical mastery, unexpected flavor pairings (scallop + black garlic + yuzu), and artistic presentation, embodying the creativity and precision of a Michelin 3-star experience.
Create an autonomous drone simulator with custom environment using ThreeJS
Couldn't render this response
This model didn't return a displayable web page for this challenge.
```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>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background-color: rgba(0,0,0,0.5);
padding: 10px;
border-radius: 5px;
font-family: Arial, sans-serif;
}
#controls {
position: absolute;
top: 10px;
right: 10px;
color: white;
background-color: rgba(0,0,0,0.5);
padding: 10px;
border-radius: 5px;
font-family: Arial, sans-serif;
}
button {
margin: 5px;
padding: 8px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="info">
<h3>Autonomous Drone Simulator</h3>
<p>Drone is flying autonomously through the environment</p>
<p><strong>Camera:</strong> Drag to rotate, Scroll to zoom</p>
</div>
<div id="controls">
<button id="resetBtn">Reset Drone</button>
<button id="toggleMode">Toggle Creative Mode</button>
<div>
<label for="speedRange">Speed: </label>
<input type="range" id="speedRange" min="0.5" max="5" step="0.5" value="2">
<span id="speedValue">2</span>
</div>
</div>
<script>
// Main variables
let scene, camera, renderer;
let drone, droneBody, droneProps = [];
let controls = {
rotateX: 0,
rotateY: 0,
distance: 80
};
let mouse = { x: 0, y: 0 }, isDragging = false;
let targets = [];
let currentTargetIndex = 0;
let dronePosition, droneVelocity;
let droneSpeed = 2;
let creativeMode = false;
let environmentObjects = [];
// Initialize the simulation
function init() {
// Create scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // Sky blue
// Create camera (isometric perspective)
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
updateCamera();
// Create renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Add lights
const ambientLight = new THREE.AmbientLight(0x404040, 1);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(100, 100, 50);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
scene.add(directionalLight);
// Create environment
createEnvironment();
// Create drone
createDrone();
// Set initial drone position and velocity
dronePosition = new THREE.Vector3(0, 10, 0);
droneVelocity = new THREE.Vector3(0, 0, -1);
// Create targets for the drone to navigate to
createTargets();
// Add event listeners
window.addEventListener('resize', onWindowResize);
window.addEventListener('mousedown', onMouseDown);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('wheel', onMouseWheel);
document.getElementById('resetBtn').addEventListener('click', resetDrone);
document.getElementById('toggleMode').addEventListener('click', toggleCreativeMode);
document.getElementById('speedRange').addEventListener('input', function(e) {
droneSpeed = parseFloat(e.target.value);
document.getElementById('speedValue').textContent = droneSpeed;
});
// Start animation loop
animate();
}
function createEnvironment() {
// Create ground
const groundGeometry = new THREE.PlaneGeometry(200, 200, 32, 32);
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
environmentObjects.push(ground);
// Add some terrain variation
const vertices = groundGeometry.attributes.position;
for (let i = 0; i < vertices.count; i++) {
const x = vertices.getX(i);
const y = vertices.getY(i);
const z = vertices.getZ(i);
// Create hills and valleys
const distortion = 3 * Math.sin(0.05 * x) * Math.cos(0.05 * z);
vertices.setZ(i, distortion);
}
groundGeometry.computeVertexNormals();
// Add buildings in regular mode
if (!creativeMode) {
for (let i = 0; i < 15; i++) {
createBuilding(
Math.random() * 160 - 80,
Math.random() * 4 + 2,
Math.random() * 160 - 80,
Math.random() * 10 + 5,
Math.random() * 10 + 5,
Math.random() * 15 + 5
);
}
}
// Add trees
for (let i = 0; i < 30; i++) {
createTree(
Math.random() * 180 - 90,
0,
Math.random() * 180 - 90
);
}
// Add some decorative elements in creative mode
if (creativeMode) {
createCreativeEnvironment();
}
}
function createBuilding(x, baseY, z, width, depth, height) {
const buildingGeometry = new THREE.BoxGeometry(width, height, depth);
const colors = [0xff5555, 0x55ff55, 0x5555ff, 0xffff55, 0xff55ff, 0x55ffff];
const color = colors[Math.floor(Math.random() * colors.length)];
const buildingMaterial = new THREE.MeshLambertMaterial({ color: color });
const building = new THREE.Mesh(buildingGeometry, buildingMaterial);
building.position.set(x, baseY + height/2, z);
building.castShadow = true;
building.receiveShadow = true;
scene.add(building);
environmentObjects.push(building);
}
function createTree(x, baseY, z) {
// Tree trunk
const trunkGeometry = new THREE.CylinderGeometry(0.5, 0.7, 4, 8);
const trunkMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
trunk.position.set(x, baseY + 2, z);
trunk.castShadow = true;
scene.add(trunk);
environmentObjects.push(trunk);
// Tree leaves
const leavesGeometry = new THREE.ConeGeometry(3, 6, 8);
const leavesMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 });
const leaves = new THREE.Mesh(leavesGeometry, leavesMaterial);
leaves.position.set(x, baseY + 6, z);
leaves.castShadow = true;
scene.add(leaves);
environmentObjects.push(leaves);
}
function createCreativeEnvironment() {
// Add floating platforms
for (let i = 0; i < 8; i++) {
const platformGeometry = new THREE.BoxGeometry(
Math.random() * 15 + 5,
1,
Math.random() * 15 + 5
);
const platformMaterial = new THREE.MeshLambertMaterial({
color: Math.random() * 0xffffff
});
const platform = new THREE.Mesh(platformGeometry, platformMaterial);
platform.position.set(
Math.random() * 120 - 60,
Math.random() * 30 + 15,
Math.random() * 120 - 60
);
platform.castShadow = true;
platform.receiveShadow = true;
scene.add(platform);
environmentObjects.push(platform);
}
// Add floating spheres
for (let i = 0; i < 12; i++) {
const sphereGeometry = new THREE.SphereGeometry(
Math.random() * 3 + 1, 16, 16
);
const sphereMaterial = new THREE.MeshLambertMaterial({
color: Math.random() * 0xffffff,
transparent: true,
opacity: 0.8
});
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(
Math.random() * 160 - 80,
Math.random() * 40 + 5,
Math.random() * 160 - 80
);
sphere.castShadow = true;
scene.add(sphere);
environmentObjects.push(sphere);
}
}
function createDrone() {
// Create drone group
drone = new THREE.Group();
scene.add(drone);
// Drone body
const bodyGeometry = new THREE.BoxGeometry(2, 0.5, 2);
const bodyMaterial = new THREE.MeshLambertMaterial({ color: 0x333333 });
droneBody = new THREE.Mesh(bodyGeometry, bodyMaterial);
droneBody.castShadow = true;
drone.add(droneBody);
// Add camera/lights to drone
const droneLight = new THREE.PointLight(0xffffff, 0.5, 10);
droneLight.position.set(0, -0.5, 0);
drone.add(droneLight);
// Create propellers
const propGeometry = new THREE.BoxGeometry(0.3, 0.3, 1.2);
const propMaterial = new THREE.MeshLambertMaterial({ color: 0x666666 });
// Front-left propeller
const prop1 = new THREE.Mesh(propGeometry, propMaterial);
prop1.position.set(-0.7, 0.5, -0.7);
drone.add(prop1);
droneProps.push(prop1);
// Front-right propeller
const prop2 = new THREE.Mesh(propGeometry, propMaterial);
prop2.position.set(0.7, 0.5, -0.7);
drone.add(prop2);
droneProps.push(prop2);
// Back-left propeller
const prop3 = new THREE.Mesh(propGeometry, propMaterial);
prop3.position.set(-0.7, 0.5, 0.7);
drone.add(prop3);
droneProps.push(prop3);
// Back-right propeller
const prop4 = new THREE.Mesh(propGeometry, propMaterial);
prop4.position.set(0.7, 0.5, 0.7);
drone.add(prop4);
droneProps.push(prop4);
// Add propeller arms
const armGeometry = new THREE.BoxGeometry(1.8, 0.2, 0.2);
const armMaterial = new THREE.MeshLambertMaterial({ color: 0x555555 });
const arm1 = new THREE.Mesh(armGeometry, armMaterial);
arm1.position.set(0, 0.2, -0.7);
drone.add(arm1);
const arm2 = new THREE.Mesh(armGeometry, armMaterial);
arm2.position.set(0, 0.2, 0.7);
arm2.rotation.z = Math.PI;
drone.add(arm2);
}
function createTargets() {
// Clear existing targets
targets.forEach(target => scene.remove(target));
targets = [];
// Create new targets based on mode
if (creativeMode) {
// In creative mode, navigate through floating platforms
environmentObjects.forEach(obj => {
if (obj.geometry instanceof THREE.BoxGeometry && obj.position.y > 10) {
targets.push(new THREE.Vector3(obj.position.x, obj.position.y + 5, obj.position.z));
}
});
// Add some additional targets
for (let i = 0; i < 5; i++) {
targets.push(new THREE.Vector3(
Math.random() * 100 - 50,
Math.random() * 20 + 10,
Math.random() * 100 - 50
));
}
} else {
// In regular mode, navigate around buildings
for (let i = 0; i < 10; i++) {
targets.push(new THREE.Vector3(
Math.random() * 120 - 60,
Math.random() * 15 + 8,
Math.random() * 120 - 60
));
}
}
// Visualize targets
targets.forEach(target => {
const targetGeometry = new THREE.SphereGeometry(0.5, 8, 8);
const targetMaterial = new THREE.MeshBasicMaterial({
color: 0xffff00,
transparent: true,
opacity: 0.7
});
const targetMesh = new THREE.Mesh(targetGeometry, targetMaterial);
targetMesh.position.copy(target);
scene.add(targetMesh);
// Add pulsing animation to targets
targetMesh.userData = {
originalScale: targetMesh.scale.clone(),
pulseFactor: 0.2,
pulseSpeed: 2 + Math.random() * 2
};
});
}
function updateDrone() {
if (!targets.length) return;
// Get current target
const target = targets[currentTargetIndex];
// Calculate direction to target
const direction = new THREE.Vector3().subVectors(target, dronePosition);
const distanceToTarget = direction.length();
// If close to target, switch to next target
if (distanceToTarget < 3) {
currentTargetIndex = (currentTargetIndex + 1) % targets.length;
return;
}
// Normalize direction and apply speed
direction.normalize().multiplyScalar(droneSpeed * 0.05);
droneVelocity.lerp(direction, 0.05);
// Update position
dronePosition.add(droneVelocity);
// Update drone mesh position and rotation
drone.position.copy(dronePosition);
// Orient drone in direction of movement
if (droneVelocity.length() > 0.01) {
drone.lookAt(new THREE.Vector3().addVectors(dronePosition, droneVelocity));
// Add banking effect when turning
const yaw = Math.atan2(droneVelocity.x, droneVelocity.z);
drone.rotation.x = Math.max(Math.min(droneVelocity.length() * 0.2, 0.5), -0.5);
drone.rotation.z = -yaw * 0.2;
}
// Rotate propellers
droneProps.forEach(prop => {
prop.rotation.x += 0.5;
});
// Keep drone above ground
if (dronePosition.y < 2) {
dronePosition.y = 2;
droneVelocity.y = Math.abs(droneVelocity.y);
}
// Check collisions with buildings
for (let obj of environmentObjects) {
if (obj.geometry instanceof THREE.BoxGeometry && obj !== droneBody) {
const box = new THREE.Box3().setFromObject(obj);
const droneBox = new THREE.Box3().setFromObject(drone);
if (droneBox.intersectsBox(box)) {
// Simple collision response - push drone away
const center = box.getCenter(new THREE.Vector3());
const away = new THREE.Vector3().subVectors(dronePosition, center).normalize();
dronePosition.add(away.multiplyScalar(1));
droneVelocity.reflect(away).multiplyScalar(0.5);
}
}
}
}
function animateTargets() {
scene.children.forEach(child => {
if (child.userData && child.userData.originalScale) {
const time = Date.now() * 0.001;
const scale = child.userData.originalScale.clone();
const pulse = 1 + child.userData.pulseFactor * Math.sin(time * child.userData.pulseSpeed);
child.scale.set(scale.x * pulse, scale.y * pulse, scale.z * pulse);
}
});
}
function updateCamera() {
// Isometric-like view with ability to rotate
const x = controls.distance * Math.sin(controls.rotateY) * Math.cos(controls.rotateX);
const y = controls.distance * Math.sin(controls.rotateX);
const z = controls.distance * Math.cos(controls.rotateY) * Math.cos(controls.rotateX);
camera.position.set(x, y, z);
camera.lookAt(0, 10, 0);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onMouseDown(event) {
isDragging = true;
mouse.x = event.clientX;
mouse.y = event.clientY;
}
function onMouseUp() {
isDragging = false;
}
function onMouseMove(event) {
if (isDragging) {
const deltaX = event.clientX - mouse.x;
const deltaY = event.clientY - mouse.y;
controls.rotateY -= deltaX * 0.01;
controls.rotateX += deltaY * 0.01;
// Limit vertical rotation
controls.rotateX =