4
4

広い海で遊ぶゲーム。

Posted at

スクリーンショット 2024-08-17 135750.png

スクリーンショット 2024-08-17 135829.png

広い海で遊ぶゲーム。スペースキーを押すと発射。

カーソルキーで移動です。

import os
import webbrowser
from http.server import SimpleHTTPRequestHandler, HTTPServer
import threading

# HTMLコードを生成
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Car Game with Random Fire</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // シーン、カメラ、レンダラーの初期化
        var scene = new THREE.Scene();
        scene.background = new THREE.Color(0x87CEEB);  // 空の色 (空色)

        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 地面(海の色に設定)
        var groundGeometry = new THREE.PlaneGeometry(1000, 1000);
        var groundMaterial = new THREE.MeshBasicMaterial({ color: 0x1e90ff });
        var ground = new THREE.Mesh(groundGeometry, groundMaterial);
        ground.rotation.x = -Math.PI / 2;
        scene.add(ground);

        // 広い範囲に島を配置
        function createIsland(x, y, z) {
            var islandGeometry = new THREE.CylinderGeometry(2, 5, 3, 32);
            var islandMaterial = new THREE.MeshBasicMaterial({ color: 0x228B22 });  // 島の色 (緑色)
            var island = new THREE.Mesh(islandGeometry, islandMaterial);
            island.position.set(x, y, z);
            scene.add(island);
        }

        // より広い範囲に多数の島をランダムに配置
        for (var i = 0; i < 50; i++) {
            createIsland(
                Math.random() * 1000 - 500,
                1.5,  // 海面からの高さ
                Math.random() * 1000 - 500
            );
        }

        // 車の初期設定
        var carGeometry = new THREE.BoxGeometry(1, 0.5, 2);
        var carMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        var car = new THREE.Mesh(carGeometry, carMaterial);
        scene.add(car);
        camera.position.set(0, 5, -10);
        camera.lookAt(car.position);

        // プロジェクタイル用変数
        var projectiles = [];
        var carSpeed = 0;
        var carRotationSpeed = 0.05;
        var moveForward = false;
        var moveBackward = false;
        var rotateLeft = false;
        var rotateRight = false;

        // キーボード入力処理
        function onKeyDown(event) {
            switch (event.code) {
                case 'ArrowUp': moveForward = true; break;
                case 'ArrowDown': moveBackward = true; break;
                case 'ArrowLeft': rotateLeft = true; break;
                case 'ArrowRight': rotateRight = true; break;
                case 'Space': fireMassProjectiles(); break;
            }
        }

        function onKeyUp(event) {
            switch (event.code) {
                case 'ArrowUp': moveForward = false; break;
                case 'ArrowDown': moveBackward = false; break;
                case 'ArrowLeft': rotateLeft = false; break;
                case 'ArrowRight': rotateRight = false; break;
            }
        }

        // 100発のプロジェクタイルを発射する関数
        function fireMassProjectiles() {
            for (var i = 0; i < 100; i++) {
                var projectileGeometry = new THREE.SphereGeometry(0.2, 16, 16);
                var projectileMaterial = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
                var projectile = new THREE.Mesh(projectileGeometry, projectileMaterial);
                projectile.position.set(
                    car.position.x + Math.sin(car.rotation.y) * 2,
                    car.position.y + 0.5,
                    car.position.z + Math.cos(car.rotation.y) * 2
                );

                // ランダムな角度と距離を持つプロジェクタイルの速度を設定
                var speed = Math.random() * 1.5 + 0.5;
                var randomAngle = (Math.random() - 0.5) * 0.4;
                var velocity = new THREE.Vector3(
                    Math.sin(car.rotation.y + randomAngle) * speed,
                    Math.random() * 0.5, // よりランダムな高さ
                    Math.cos(car.rotation.y + randomAngle) * speed
                );

                projectile.velocity = velocity;
                scene.add(projectile);
                projectiles.push(projectile);
            }
        }

        // プロジェクタイルの更新処理
        function updateProjectiles() {
            for (var i = projectiles.length - 1; i >= 0; i--) {
                var projectile = projectiles[i];
                projectile.position.add(projectile.velocity);
                projectile.velocity.y -= 0.01; // 重力

                // 地面に落ちた場合の処理
                if (projectile.position.y < 0) {
                    scene.remove(projectile);
                    projectiles.splice(i, 1);
                }
            }
        }

        // レンダリングと更新処理のループ関数
        function animate() {
            requestAnimationFrame(animate);

            // 車の移動と回転
            if (moveForward) carSpeed += 0.01;
            if (moveBackward) carSpeed -= 0.01;
            if (rotateLeft) car.rotation.y += carRotationSpeed;
            if (rotateRight) car.rotation.y -= carRotationSpeed;

            car.position.x += Math.sin(car.rotation.y) * carSpeed;
            car.position.z += Math.cos(car.rotation.y) * carSpeed;
            carSpeed *= 0.98;

            // プロジェクタイルの更新
            updateProjectiles();

            // カメラの追従
            camera.position.set(
                car.position.x - Math.sin(car.rotation.y) * 5,
                car.position.y + 2,
                car.position.z - Math.cos(car.rotation.y) * 5
            );
            camera.lookAt(car.position);

            renderer.render(scene, camera);
        }

        // イベントリスナーを設定
        document.addEventListener('keydown', onKeyDown);
        document.addEventListener('keyup', onKeyUp);

        animate();
    </script>
</body>
</html>

"""

# HTMLファイルとして保存
html_file = 'fire_simulation.html'
with open(html_file, 'w') as file:
    file.write(html_content)

# サーバーをバックグラウンドで起動
def run_server():
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
    httpd.serve_forever()

# サーバーを別スレッドで実行
thread = threading.Thread(target=run_server)
thread.daemon = True
thread.start()

# デフォルトのブラウザでHTMLファイルを開く
webbrowser.open(f'http://localhost:8000/{html_file}')

# サーバー停止まで待機
try:
    thread.join()
except KeyboardInterrupt:
    print("Server stopped.")

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4