猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果

发布于:2025-03-30 ⋅ 阅读:(30) ⋅ 点赞:(0)

我的罗里吧嗦的,根据小朋友的要求,边听边写边输入的提示词:

请生成一段完整的在网页中用html5和javascript代码模拟“我的世界”中游戏场景的互动画面,要求提供若干人物选项可以选择,请自行选择需要使用哪些库或框架来实现该功能,但希望能够保存之后,用浏览器打开就能够使用。希望能够实现若干个人物的选择,其中可供选择的人物要具有动作演示的效果,请自己选一些实现动画效果的JavaScript库,可以直接在线使用,无须其它依赖和安装,此功能可以支持两个人同时操作。请提供完整的可以直接在浏览器中打开就能够简单实现的代码

结果打开之后是这样的,真能操控:

在这里插入图片描述
代码也是毫不吝啬,一口气输出这么多:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Minecraft-Style 3D Game</title>
    <link href="https://fastly.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
    <link href="https://fastly.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/css/all.min.css" rel="stylesheet">
    <style>
        body {
            margin: 0;
            overflow: hidden;
            font-family: 'Minecraft', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #333;
        }

        @font-face {
            font-family: 'Minecraft';
            src: url('https://fastly.jsdelivr.net/npm/minecraft-font@1.0.0/assets/fonts/minecraft.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
        }

        #game-container {
            position: relative;
            width: 100vw;
            height: 100vh;
        }

        #render-canvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .interface {
            position: absolute;
            z-index: 10;
            color: white;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
        }

        .character-selection {
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.6);
            border: 2px solid #555;
            padding: 15px;
            border-radius: 8px;
            width: 90%;
            max-width: 800px;
        }

        .controls {
            bottom: 20px;
            background-color: rgba(0, 0, 0, 0.6);
            border: 2px solid #555;
            padding: 10px;
            border-radius: 8px;
            width: 250px;
        }

        #player1-controls {
            left: 20px;
        }

        #player2-controls {
            right: 20px;
        }

        .status-bar {
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.6);
            border: 2px solid #555;
            padding: 10px;
            border-radius: 8px;
            width: 90%;
            max-width: 500px;
            text-align: center;
        }

        .character-option {
            display: inline-block;
            margin: 5px;
            cursor: pointer;
            transition: all 0.3s;
            vertical-align: top;
            text-align: center;
        }

        .character-option img {
            width: 60px;
            height: 120px;
            object-fit: cover;
            border: 3px solid transparent;
            border-radius: 4px;
            filter: brightness(0.7);
            transition: all 0.3s;
        }

        .character-option:hover img {
            border-color: #aaa;
            filter: brightness(1);
        }

        .character-option.selected img {
            border-color: #5cf;
            filter: brightness(1);
        }

        .key {
            display: inline-block;
            background-color: rgba(255, 255, 255, 0.2);
            border: 1px solid rgba(255, 255, 255, 0.4);
            padding: 5px 8px;
            margin: 2px;
            border-radius: 4px;
            font-weight: bold;
        }

        .loading-screen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: #333;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 100;
            color: white;
            font-size: 24px;
        }

        .progress-bar {
            width: 300px;
            height: 20px;
            background-color: #222;
            border: 2px solid #555;
            margin-top: 20px;
            border-radius: 10px;
            overflow: hidden;
        }

        .progress {
            height: 100%;
            background-color: #5cf;
            width: 0%;
            transition: width 0.3s;
        }

        .dirt-block {
            display: inline-block;
            width: 30px;
            height: 30px;
            background-image: url('https://images.unsplash.com/photo-1607513746994-51f730a44832?q=80&w=30&auto=format&fit=crop');
            background-size: cover;
            margin: 0 5px;
            border-radius: 2px;
            vertical-align: middle;
        }

        @media (max-width: 768px) {
            .character-selection {
                padding: 10px;
            }
            
            .character-option img {
                width: 40px;
                height: 80px;
            }
            
            .controls {
                width: 150px;
                font-size: 12px;
            }
            
            .status-bar {
                font-size: 12px;
            }
        }
    </style>
</head>
<body>
    <!-- Loading Screen -->
    <div id="f2305d93-bcef-4e15-b7ce-a63c8d491b52" class="loading-screen">
        <div id="d40cd4d8-4c0e-48e4-a4d0-05bbfd6fa7db" class="dirt-block"></div>
        <span id="916207e2-1aa4-49bc-b83c-c3eece7a44c2">Loading Minecraft-Style Game...</span>
        <div id="b83699d9-78e5-4708-b801-716a85eef33f" class="progress-bar">
            <div id="39d52c16-9215-4ebf-a6a0-25c67b5a8de1" class="progress"></div>
        </div>
    </div>

    <!-- Game Container -->
    <div id="a24df7c4-8bb6-4ac3-9e3b-91aa2a63136f" class="game-container">
        <!-- Canvas for Three.js rendering -->
        <canvas id="render-canvas"></canvas>

        <!-- Character Selection UI -->
        <div id="6c1abfc1-2331-40ab-a1e5-5eeb687d8092" class="interface character-selection">
            <div id="cf8ae90c-cf05-40b4-af8a-faf0b60c47cb" class="grid grid-cols-2 md:grid-cols-4 gap-2">
                <div id="b05e2f3c-5dbe-444f-9fa0-0e9a1e637919" class="text-center col-span-2 md:col-span-4 mb-2">
                    <h2 id="c815cc5e-5ff2-46f5-9342-c4118cb0ecd7" class="text-xl font-bold">Select Characters</h2>
                    <div id="8268f04e-2325-4c9e-aa64-44bb6acb32c0" class="mt-1">
                        <span id="1cff1ae5-0e54-4f3f-bf0b-ab87bce5408f" class="text-blue-300">Player 1:</span> 
                        <span id="player1-character">Steve</span> | 
                        <span id="5f21f725-c5c0-4034-bb01-a7f56da3f128" class="text-green-300">Player 2:</span> 
                        <span id="player2-character">Alex</span>
                    </div>
                </div>
                <div id="character-options"></div>
            </div>
        </div>

        <!-- Player 1 Controls -->
        <div id="player1-controls" class="interface controls">
            <h3 id="0376da1d-f2a0-4b95-907e-936476a841a1" class="text-blue-300 font-bold">Player 1 Controls:</h3>
            <div id="d2bc2fb3-0502-4f5d-86b3-0f2a5f028a3a">
                <div id="a0294bc3-bcc8-4f28-b001-e9fc0ea2f56a" class="mb-1"><span id="cd96b41c-00d3-4309-b805-f2befdda40c9" class="key">W</span> Forward</div>
                <div id="369be69d-d537-4bc3-a11e-2411ca8ee159" class="mb-1">
                    <span id="9ae1c1c2-6f71-4575-8dd1-dc0fccd922e3" class="key">A</span>
                    <span id="d7053019-0309-433e-be51-603a9a10cb23" class="key">S</span>
                    <span id="1f78a456-bc7e-4bb2-9c52-7efc4c2c65c4" class="key">D</span> Move
                </div>
                <div id="27312d5e-377e-4469-9802-7c3b846846f3" class="mb-1"><span id="0c01c5d2-b55a-4e2c-b21b-bdd32152b755" class="key">Space</span> Jump</div>
                <div id="15cfdb30-6696-4cfd-b61c-6ac80e730ebe"><span id="6a42c7fc-dc00-442c-9478-8c5d295bd8b5" class="key">E</span> Action</div>
            </div>
        </div>

        <!-- Player 2 Controls -->
        <div id="player2-controls" class="interface controls">
            <h3 id="140c646d-11b9-4ea8-82ad-bf915bd8b8f0" class="text-green-300 font-bold">Player 2 Controls:</h3>
            <div id="9dba0abc-4a53-4299-92b3-2c6319cfe33d">
                <div id="0c620c17-2910-430a-b0c5-428c2e86fbc8" class="mb-1"><span id="80c340f8-c8d9-41d0-9e71-0d14ea07e90e" class="key"></span> Forward</div>
                <div id="007bccc6-d4fb-4658-98cf-6b5c88d491be" class="mb-1">
                    <span id="086ae8b2-c512-4ad3-8a35-4d60e8a441ae" class="key"></span>
                    <span id="e4222974-a876-490d-aa4b-c2f4188ac164" class="key"></span>
                    <span id="0a94ad7f-9ef5-440e-a144-a875a790ffb0" class="key"></span> Move
                </div>
                <div id="fb07362d-4363-40d3-b520-3b56722fbea1" class="mb-1"><span id="9a900166-a068-4c4c-b1a6-59bcc0304d38" class="key">Enter</span> Jump</div>
                <div id="bac976e5-fa44-462a-902e-bf729516482e"><span id="d6c0bf9a-6007-4f5f-a530-a9b64c6f6c11" class="key">/</span> Action</div>
            </div>
        </div>

        <!-- Status Bar -->
        <div id="de6f85ed-466b-4bd7-9e51-5b778908622d" class="interface status-bar">
            <div id="game-status">Use WASD+Space and Arrow+Enter to move around and explore the world!</div>
        </div>
    </div>

    <!-- Scripts -->
    <script src="https://fastly.jsdelivr.net/npm/three@0.142.0/build/three.min.js"></script>
    <script src="https://fastly.jsdelivr.net/npm/three@0.142.0/examples/js/controls/OrbitControls.js"></script>
    <script src="https://fastly.jsdelivr.net/npm/@tweenjs/tween.js@18.6.4/dist/tween.umd.js"></script>
    <script>
        // Main game class
        class MinecraftStyleGame {
            constructor() {
                // Core properties
                this.scene = null;
                this.camera = null;
                this.renderer = null;
                this.clock = new THREE.Clock();
                
                // Game state
                this.players = [
                    { id: 1, character: 'Steve', model: null, position: new THREE.Vector3(0, 1, 0), velocity: new THREE.Vector3(), isJumping: false, onGround: true },
                    { id: 2, character: 'Alex', model: null, position: new THREE.Vector3(3, 1, 0), velocity: new THREE.Vector3(), isJumping: false, onGround: true }
                ];
                
                this.keys = {
                    player1: {
                        forward: false,
                        backward: false,
                        left: false,
                        right: false,
                        jump: false,
                        action: false
                    },
                    player2: {
                        forward: false,
                        backward: false,
                        left: false,
                        right: false,
                        jump: false,
                        action: false
                    }
                };

                // Game world parameters
                this.worldSize = 20;
                this.blockSize = 1;
                this.gravity = 0.02;
                this.jumpForce = 0.2;
                this.moveSpeed = 0.1;
                
                // Character options
                this.characterOptions = [
                    { name: 'Steve', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/steve.png', playerID: 1 },
                    { name: 'Alex', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/alex.png', playerID: 2 },
                    { name: 'Zombie', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/zombie.png', playerID: null },
                    { name: 'Skeleton', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/skeleton.png', playerID: null },
                    { name: 'Creeper', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/creeper.png', playerID: null },
                    { name: 'Enderman', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/enderman.png', playerID: null },
                    { name: 'Villager', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/villager.png', playerID: null },
                    { name: 'Pig', texture: 'https://minecraft-heads.com/media/com_minecraft/skins/original/pig.png', playerID: null }
                ];

                // Resources to load
                this.textures = {
                    dirt: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1607513746994-51f730a44832?q=80&w=200&auto=format&fit=crop'),
                    grass: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1626269555171-153a1bca85f7?q=80&w=200&auto=format&fit=crop'),
                    stone: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1588371758051-e93a5ce1b5f4?q=80&w=200&auto=format&fit=crop'),
                    wood: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1599751449128-eb7249c3d6b1?q=80&w=200&auto=format&fit=crop'),
                    leaves: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1570822153940-2b3b795f54cf?q=80&w=200&auto=format&fit=crop')
                };

                // Loading progress
                this.resourcesLoaded = 0;
                this.totalResources = Object.keys(this.textures).length + this.characterOptions.length;

                // Initialize the game
                this.init();
            }

            init() {
                // Initialize Three.js scene
                this.initScene();
                
                // Handle loading
                this.loadResources();
                
                // UI setup
                this.setupCharacterSelection();

                // Setup event listeners
                this.setupEventListeners();
                
                // Start animation loop
                this.animate();
            }

            initScene() {
                // Create scene
                this.scene = new THREE.Scene();
                this.scene.background = new THREE.Color(0x87CEEB); // Sky blue
                
                // Create camera
                this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
                this.camera.position.set(10, 10, 10);
                this.camera.lookAt(0, 0, 0);
                
                // Create renderer
                this.renderer = new THREE.WebGLRenderer({ 
                    canvas: document.getElementById('render-canvas'),
                    antialias: true 
                });
                this.renderer.setSize(window.innerWidth, window.innerHeight);
                this.renderer.shadowMap.enabled = true;
                
                // Add light
                const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
                this.scene.add(ambientLight);
                
                const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
                directionalLight.position.set(10, 20, 10);
                directionalLight.castShadow = true;
                directionalLight.shadow.mapSize.width = 2048;
                directionalLight.shadow.mapSize.height = 2048;
                this.scene.add(directionalLight);

                // Add controls for debugging
                // this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
            }

            loadResources() {
                // Track texture loading
                const loadingManager = new THREE.LoadingManager();
                
                loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
                    this.resourcesLoaded++;
                    this.updateLoadingProgress();
                };
                
                loadingManager.onLoad = () => {
                    // All textures are loaded
                    this.createWorld();
                    setTimeout(() => {
                        document.getElementById('f2305d93-bcef-4e15-b7ce-a63c8d491b52').style.display = 'none';
                    }, 500);
                };
                
                // Create texture loader with the loading manager
                const textureLoader = new THREE.TextureLoader(loadingManager);
                
                // Load all textures
                Object.keys(this.textures).forEach(key => {
                    const url = this.textures[key].source?.data?.src;
                    if (url) {
                        this.textures[key] = textureLoader.load(url);
                        this.textures[key].wrapS = THREE.RepeatWrapping;
                        this.textures[key].wrapT = THREE.RepeatWrapping;
                    }
                });
                
                // Load character textures
                this.characterOptions.forEach(char => {
                    textureLoader.load(char.texture, () => {
                        this.resourcesLoaded++;
                        this.updateLoadingProgress();
                    });
                });
            }

            updateLoadingProgress() {
                const progress = Math.min((this.resourcesLoaded / this.totalResources) * 100, 100);
                document.getElementById('39d52c16-9215-4ebf-a6a0-25c67b5a8de1').style.width = `${progress}%`;
            }

            createWorld() {
                // Create ground
                this.createTerrain();
                
                // Create various structures
                this.createStructures();
                
                // Create player characters
                this.createPlayerCharacters();
            }

            createTerrain() {
                // Create base terrain
                const groundGeometry = new THREE.BoxGeometry(this.worldSize, 1, this.worldSize);
                const groundMaterial = new THREE.MeshStandardMaterial({ map: this.textures.grass });
                const ground = new THREE.Mesh(groundGeometry, groundMaterial);
                ground.position.y = -0.5;
                ground.receiveShadow = true;
                this.scene.add(ground);
                
                // Create random terrain variations
                for (let x = -this.worldSize/2; x < this.worldSize/2; x += this.blockSize) {
                    for (let z = -this.worldSize/2; z < this.worldSize/2; z += this.blockSize) {
                        // Skip the center area for player spawn
                        if (Math.abs(x) < 4 && Math.abs(z) < 4) continue;
                        
                        if (Math.random() < 0.1) {
                            const height = Math.floor(Math.random() * 3) + 1;
                            
                            for (let y = 0; y < height; y++) {
                                const material = y === height - 1 ? 
                                    new THREE.MeshStandardMaterial({ map: this.textures.grass }) : 
                                    new THREE.MeshStandardMaterial({ map: this.textures.dirt });
                                
                                this.createBlock(x, y, z, material);
                            }
                        }
                        
                        // Create trees
                        if (Math.random() < 0.02) {
                            this.createTree(x, 0, z);
                        }
                    }
                }
            }

            createBlock(x, y, z, material) {
                const geometry = new THREE.BoxGeometry(this.blockSize, this.blockSize, this.blockSize);
                const block = new THREE.Mesh(geometry, material);
                
                block.position.set(x, y, z);
                block.castShadow = true;
                block.receiveShadow = true;
                
                this.scene.add(block);
                return block;
            }

            createTree(x, y, z) {
                // Tree trunk
                const trunkHeight = 4 + Math.floor(Math.random() * 3);
                const woodMaterial = new THREE.MeshStandardMaterial({ map: this.textures.wood });
                
                for (let i = 0; i < trunkHeight; i++) {
                    this.createBlock(x, y + i, z, woodMaterial);
                }
                
                // Tree leaves
                const leavesMaterial = new THREE.MeshStandardMaterial({ 
                    map: this.textures.leaves,
                    transparent: true,
                    alphaTest: 0.8
                });
                
                const leavesSize = 3;
                for (let lx = -leavesSize; lx <= leavesSize; lx++) {
                    for (let ly = 0; ly <= leavesSize + 1; ly++) {
                        for (let lz = -leavesSize; lz <= leavesSize; lz++) {
                            // Create spherical-ish shape for leaves
                            if (lx*lx + (ly-1)*(ly-1) + lz*lz <= leavesSize*leavesSize) {
                                // Don't place leaves where trunk is
                                if (!(lx === 0 && lz === 0 && ly < leavesSize)) {
                                    this.createBlock(
                                        x + lx, 
                                        y + trunkHeight - 1 + ly, 
                                        z + lz, 
                                        leavesMaterial
                                    );
                                }
                            }
                        }
                    }
                }
            }

            createStructures() {
                // Create a small house
                const housePosX = 8;
                const housePosZ = 8;
                const houseSizeX = 5;
                const houseSizeZ = 4;
                const wallHeight = 3;
                
                const stoneMaterial = new THREE.MeshStandardMaterial({ map: this.textures.stone });
                const woodMaterial = new THREE.MeshStandardMaterial({ map: this.textures.wood });

                // Floor
                for (let x = 0; x < houseSizeX; x++) {
                    for (let z = 0; z < houseSizeZ; z++) {
                        this.createBlock(housePosX + x, 0, housePosZ + z, stoneMaterial);
                    }
                }
                
                // Walls
                for (let x = 0; x < houseSizeX; x++) {
                    for (let y = 1; y <= wallHeight; y++) {
                        // Front and back walls
                        if (!(x === 2 && y < 3)) { // Door in front wall
                            this.createBlock(housePosX + x, y, housePosZ, woodMaterial); // Front wall
                        }
                        this.createBlock(housePosX + x, y, housePosZ + houseSizeZ - 1, woodMaterial); // Back wall
                    }
                }
                
                for (let z = 0; z < houseSizeZ; z++) {
                    for (let y = 1; y <= wallHeight; y++) {
                        // Side walls
                        this.createBlock(housePosX, y, housePosZ + z, woodMaterial); // Left wall
                        this.createBlock(housePosX + houseSizeX - 1, y, housePosZ + z, woodMaterial); // Right wall
                    }
                }
                
                // Roof
                for (let x = -1; x <= houseSizeX; x++) {
                    for (let z = -1; z <= houseSizeZ; z++) {
                        this.createBlock(housePosX + x, wallHeight + 1, housePosZ + z, stoneMaterial);
                    }
                }

                // Create a small mining area
                const minePosX = -8;
                const minePosZ = -8;
                
                // Create pit
                for (let x = 0; x < 4; x++) {
                    for (let z = 0; z < 4; z++) {
                        // Remove blocks to create a pit
                        // but leave some stone blocks at the bottom
                        if (!(x === 1 && z === 1) && !(x === 2 && z === 2)) {
                            this.createBlock(minePosX + x, -3, minePosZ + z, stoneMaterial);
                        }
                    }
                }
                
                // Add some stone around the pit
                for (let i = 0; i < 10; i++) {
                    const rx = minePosX + Math.floor(Math.random() * 6) - 1;
                    const rz = minePosZ + Math.floor(Math.random() * 6) - 1;
                    const ry = Math.floor(Math.random() * 2);
                    this.createBlock(rx, ry, rz, stoneMaterial);
                }
            }

            createPlayerCharacters() {
                // We'll create simple block player models for now
                // In a real implementation, you would load Minecraft character models
                
                // Player 1
                this.createPlayerModel(this.players[0]);
                
                // Player 2
                this.createPlayerModel(this.players[1]);
            }

            createPlayerModel(player) {
                // Get character info from options
                const characterInfo = this.characterOptions.find(c => c.name === player.character);
                
                if (!characterInfo) return;
                
                // Create character group
                const playerModel = new THREE.Group();
                
                // Load character texture
                const textureLoader = new THREE.TextureLoader();
                const texture = textureLoader.load(characterInfo.texture);
                
                // Create body parts with correct proportions
                // Head
                const headGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
                const headMaterial = new THREE.MeshStandardMaterial({ map: texture });
                const head = new THREE.Mesh(headGeometry, headMaterial);
                head.position.y = 1.4;
                head.castShadow = true;
                playerModel.add(head);
                
                // Body
                const bodyGeometry = new THREE.BoxGeometry(0.6, 1.2, 0.4);
                const bodyMaterial = new THREE.MeshStandardMaterial({ 
                    map: texture,
                    color: player.id === 1 ? 0x3090ff : 0x60d060 
                });
                const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
                body.position.y = 0.6;
                body.castShadow = true;
                playerModel.add(body);
                
                // Arms
                const armGeometry = new THREE.BoxGeometry(0.3, 1.0, 0.3);
                const armMaterial = new THREE.MeshStandardMaterial({ 
                    map: texture,
                    color: player.id === 1 ? 0x2080dd : 0x50c050
                });
                
                const leftArm = new THREE.Mesh(armGeometry, armMaterial);
                leftArm.position.set(-0.45, 0.5, 0);
                leftArm.castShadow = true;
                playerModel.add(leftArm);
                
                const rightArm = new THREE.Mesh(armGeometry, armMaterial);
                rightArm.position.set(0.45, 0.5, 0);
                rightArm.castShadow = true;
                playerModel.add(rightArm);
                
                // Legs
                const legGeometry = new THREE.BoxGeometry(0.3, 1.0, 0.3);
                const legMaterial = new THREE.MeshStandardMaterial({ 
                    map: texture,
                    color: 0x3060b0
                });
                
                const leftLeg = new THREE.Mesh(legGeometry, legMaterial);
                leftLeg.position.set(-0.2, -0.5, 0);
                leftLeg.castShadow = true;
                playerModel.add(leftLeg);
                
                const rightLeg = new THREE.Mesh(legGeometry, legMaterial);
                rightLeg.position.set(0.2, -0.5, 0);
                rightLeg.castShadow = true;
                playerModel.add(rightLeg);
                
                // Position the player model
                playerModel.position.copy(player.position);
                
                // Store limbs for animation
                playerModel.userData = {
                    head,
                    leftArm,
                    rightArm,
                    leftLeg,
                    rightLeg,
                    animationTime: 0
                };
                
                // Add to scene and assign to player
                this.scene.add(playerModel);
                player.model = playerModel;
            }

            setupCharacterSelection() {
                const container = document.getElementById('character-options');
                
                this.characterOptions.forEach((char, index) => {
                    const option = document.createElement('div');
                    option.className = 'character-option';
                    if (char.playerID === 1) option.classList.add('selected');
                    
                    const img = document.createElement('img');
                    img.src = char.texture;
                    img.alt = char.name;
                    
                    const name = document.createElement('div');
                    name.textContent = char.name;
                    
                    option.appendChild(img);
                    option.appendChild(name);
                    
                    option.addEventListener('click', () => {
                        // Show character selection dialog
                        this.selectCharacter(char, index);
                    });
                    
                    container.appendChild(option);
                });
            }

            selectCharacter(character, index) {
                // Create a simple modal for character selection
                const selection = prompt(`Assign ${character.name} to:\n1: Player 1\n2: Player 2\n0: Cancel`);
                
                if (selection === '1' || selection === '2') {
                    const playerIndex = parseInt(selection) - 1;
                    const player = this.players[playerIndex];
                    
                    // Update selectedPlayerID on old character
                    const oldCharOption = this.characterOptions.find(c => c.name === player.character);
                    if (oldCharOption) oldCharOption.playerID = null;
                    
                    // Update player character
                    player.character = character.name;
                    character.playerID = parseInt(selection);
                    
                    // Update UI
                    document.getElementById(`player${selection}-character`).textContent = character.name;
                    
                    // Remove old player model and create a new one
                    if (player.model) {
                        this.scene.remove(player.model);
                    }
                    this.createPlayerModel(player);
                    
                    // Update character selection UI
                    const options = document.querySelectorAll('.character-option');
                    options.forEach((opt, idx) => {
                        if (this.characterOptions[idx].playerID === 1 || this.characterOptions[idx].playerID === 2) {
                            opt.classList.add('selected');
                        } else {
                            opt.classList.remove('selected');
                        }
                    });
                }
            }

            setupEventListeners() {
                // Keyboard controls
                document.addEventListener('keydown', (event) => this.handleKeyDown(event));
                document.addEventListener('keyup', (event) => this.handleKeyUp(event));
                
                // Window resize
                window.addEventListener('resize', () => this.handleResize());
            }

            handleKeyDown(event) {
                // Player 1 controls (WASD + Space)
                switch(event.code) {
                    case 'KeyW': this.keys.player1.forward = true; break;
                    case 'KeyS': this.keys.player1.backward = true; break;
                    case 'KeyA': this.keys.player1.left = true; break;
                    case 'KeyD': this.keys.player1.right = true; break;
                    case 'Space': 
                        event.preventDefault();
                        this.keys.player1.jump = true; 
                        break;
                    case 'KeyE': this.keys.player1.action = true; break;
                }
                
                // Player 2 controls (Arrow keys + Enter)
                switch(event.code) {
                    case 'ArrowUp': this.keys.player2.forward = true; break;
                    case 'ArrowDown': this.keys.player2.backward = true; break;
                    case 'ArrowLeft': this.keys.player2.left = true; break;
                    case 'ArrowRight': this.keys.player2.right = true; break;
                    case 'Enter': this.keys.player2.jump = true; break;
                    case 'Slash': this.keys.player2.action = true; break;
                }
            }

            handleKeyUp(event) {
                // Player 1 controls
                switch(event.code) {
                    case 'KeyW': this.keys.player1.forward = false; break;
                    case 'KeyS': this.keys.player1.backward = false; break;
                    case 'KeyA': this.keys.player1.left = false; break;
                    case 'KeyD': this.keys.player1.right = false; break;
                    case 'Space': this.keys.player1.jump = false; break;
                    case 'KeyE': this.keys.player1.action = false; break;
                }
                
                // Player 2 controls
                switch(event.code) {
                    case 'ArrowUp': this.keys.player2.forward = false; break;
                    case 'ArrowDown': this.keys.player2.backward = false; break;
                    case 'ArrowLeft': this.keys.player2.left = false; break;
                    case 'ArrowRight': this.keys.player2.right = false; break;
                    case 'Enter': this.keys.player2.jump = false; break;
                    case 'Slash': this.keys.player2.action = false; break;
                }
            }

            handleResize() {
                const width = window.innerWidth;
                const height = window.innerHeight;
                
                this.camera.aspect = width / height;
                this.camera.updateProjectionMatrix();
                
                this.renderer.setSize(width, height);
            }

            updatePlayer(player, controls, deltaTime) {
                if (!player.model) return;
                
                // Movement direction
                const moveDir = new THREE.Vector3(0, 0, 0);
                
                if (controls.forward) moveDir.z -= 1;
                if (controls.backward) moveDir.z += 1;
                if (controls.left) moveDir.x -= 1;
                if (controls.right) moveDir.x += 1;
                
                // Normalize movement direction
                if (moveDir.length() > 0) {
                    moveDir.normalize();
                    
                    // Calculate movement
                    const movement = moveDir.multiplyScalar(this.moveSpeed * deltaTime * 60);
                    
                    // Update position
                    player.position.x += movement.x;
                    player.position.z += movement.z;
                    
                    // Update animation state
                    player.model.userData.animationTime += deltaTime * 10;
                    
                    // Animate legs and arms while walking
                    this.animateWalking(player.model, player.model.userData.animationTime);
                    
                    // Face direction of movement
                    if (movement.x !== 0 || movement.z !== 0) {
                        player.model.rotation.y = Math.atan2(movement.x, movement.z);
                    }
                } else {
                    // Reset animation when not moving
                    this.resetAnimation(player.model);
                }
                
                // Jumping
                if (controls.jump && player.onGround) {
                    player.velocity.y = this.jumpForce;
                    player.isJumping = true;
                    player.onGround = false;
                    
                    // Update game status
                    document.getElementById('game-status').textContent = `Player ${player.id} jumped!`;
                }
                
                // Apply gravity
                player.velocity.y -= this.gravity;
                player.position.y += player.velocity.y;
                
                // Ground collision detection
                if (player.position.y <= 1) {
                    player.position.y = 1;
                    player.velocity.y = 0;
                    player.onGround = true;
                    player.isJumping = false;
                }
                
                // World boundaries
                const boundaryLimit = this.worldSize / 2 - 1;
                player.position.x = Math.max(-boundaryLimit, Math.min(boundaryLimit, player.position.x));
                player.position.z = Math.max(-boundaryLimit, Math.min(boundaryLimit, player.position.z));
                
                // Update model position
                player.model.position.copy(player.position);
                
                // Perform action if requested
                if (controls.action) {
                    this.performAction(player);
                }
            }

            performAction(player) {
                // Simple action feedback
                document.getElementById('game-status').textContent = `Player ${player.id} is performing an action!`;
                
                // Animate action (e.g. arm swing)
                if (player.model) {
                    const rightArm = player.model.userData.rightArm;
                    
                    // Create a simple animation for the arm swing
                    const startRotation = { x: 0 };
                    const endRotation = { x: -Math.PI / 2 };
                    
                    // Animate swing down
                    const swingDown = new TWEEN.Tween(startRotation)
                        .to(endRotation, 200)
                        .easing(TWEEN.Easing.Quadratic.Out)
                        .onUpdate(() => {
                            rightArm.rotation.x = startRotation.x;
                        });
                    
                    // Animate swing back
                    const swingBack = new TWEEN.Tween(endRotation)
                        .to({ x: 0 }, 200)
                        .easing(TWEEN.Easing.Quadratic.In)
                        .onUpdate(() => {
                            rightArm.rotation.x = endRotation.x;
                        });
                    
                    // Chain the animations
                    swingDown.chain(swingBack);
                    swingDown.start();
                }
            }
            
            animateWalking(model, time) {
                if (!model || !model.userData) return;
                
                const { leftLeg, rightLeg, leftArm, rightArm } = model.userData;
                
                // Animate legs
                if (leftLeg && rightLeg) {
                    leftLeg.rotation.x = Math.sin(time) * 0.5;
                    rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5;
                }
                
                // Animate arms
                if (leftArm && rightArm) {
                    leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5;
                    rightArm.rotation.x = Math.sin(time) * 0.5;
                }
            }
            
            resetAnimation(model) {
                if (!model || !model.userData) return;
                
                const { leftLeg, rightLeg, leftArm, rightArm } = model.userData;
                
                // Reset all rotations
                if (leftLeg) leftLeg.rotation.set(0, 0, 0);
                if (rightLeg) rightLeg.rotation.set(0, 0, 0);
                if (leftArm) leftArm.rotation.set(0, 0, 0);
                if (rightArm) rightArm.rotation.set(0, 0, 0);
            }

            updateCamera() {
                // Calculate center position between players
                const center = new THREE.Vector3();
                this.players.forEach(player => {
                    center.add(player.position);
                });
                center.divideScalar(this.players.length);
                
                // Calculate distance between players
                let maxDistance = 0;
                this.players.forEach(player => {
                    const distance = player.position.distanceTo(center);
                    maxDistance = Math.max(maxDistance, distance);
                });
                
                // Adjust camera position based on player positions
                const cameraDistance = Math.max(10, maxDistance * 3);
                const cameraHeight = Math.max(6, maxDistance * 1.5);
                
                // Smoothly move camera to new position
                const targetCameraPos = new THREE.Vector3(
                    center.x + cameraDistance * Math.sin(Date.now() * 0.0001),
                    cameraHeight,
                    center.z + cameraDistance * Math.cos(Date.now() * 0.0001)
                );
                
                this.camera.position.lerp(targetCameraPos, 0.02);
                this.camera.lookAt(center);
            }

            animate() {
                requestAnimationFrame(() => this.animate());
                
                const deltaTime = this.clock.getDelta();
                
                // Update players
                this.updatePlayer(this.players[0], this.keys.player1, deltaTime);
                this.updatePlayer(this.players[1], this.keys.player2, deltaTime);
                
                // Update camera to follow players
                this.updateCamera();
                
                // Update animations
                TWEEN.update();
                
                // Render scene
                this.renderer.render(this.scene, this.camera);
            }
        }

        // Initialize the game when page is loaded
        window.addEventListener('load', () => {
            const game = new MinecraftStyleGame();
        });
    </script>
</body>
</html>

在这里插入图片描述