明るいカラフルな チョコボールがバウンドする ゲームです。
スペースキーを押すとチョコボールが出ます。
コードをメモ帳などのテキストエディタに貼り付け、ファイルを「index.html」などの拡張子が.htmlのファイルとして保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>明るいカラフルなバウンドボール</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<!-- three.jsのCDNを読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
let scene, camera, renderer;
let balls = [];
const gravity = -9.8; // 重力の定数
const floorY = -5; // 床のY軸位置
// シーンの初期化関数
function init() {
// シーンの作成
scene = new THREE.Scene();
// カメラの作成
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 20; // カメラをZ軸に配置
// レンダラーの作成(アンチエイリアス有効)
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight); // ウィンドウサイズに合わせる
document.body.appendChild(renderer.domElement); // レンダラーをHTMLに追加
// 床(不可視)を作成
const floorGeometry = new THREE.PlaneGeometry(200, 200); // 床の大きさ
const floorMaterial = new THREE.MeshBasicMaterial({ visible: false }); // 床は不可視
const floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.rotation.x = -Math.PI / 2; // 床を横に倒す
floor.position.y = floorY; // Y軸上で床を配置
scene.add(floor);
// メタリックなエフェクトを付けるための光源を作成
const light1 = new THREE.DirectionalLight(0xffffff, 1); // 白色の方向光
light1.position.set(5, 10, 7.5).normalize(); // 光の方向
scene.add(light1);
const light2 = new THREE.AmbientLight(0x404040); // 環境光
scene.add(light2);
// 最初に20個のボールを作成
for (let i = 0; i < 20; i++) {
createRandomBall(); // ランダムなボールを作成
}
// スペースキーが押されたときにボールを追加
window.addEventListener('keydown', (event) => {
if (event.code === 'Space') {
createRandomBall(); // スペースキーで新しいボールを追加
}
});
// アニメーションを開始
animate();
}
// ランダムな色、位置、速度、質量を持つボールを作成する関数
function createRandomBall() {
const radius = Math.random() * 0.5 + 0.5; // ボールの半径をランダムに設定(0.5〜1.0)
// ボールの色を明るくカラフルに設定
const brightColor = Math.random() * 0x80ffff + 0x80ff80; // 明るい色の生成
const ballGeometry = new THREE.SphereGeometry(radius, 32, 32); // 球体のジオメトリ作成
const ballMaterial = new THREE.MeshStandardMaterial({
color: brightColor, // 明るい色を指定
metalness: 0.7, // メタリック感
roughness: 0.2 // 滑らかさ
});
const ball = new THREE.Mesh(ballGeometry, ballMaterial); // 球体メッシュを作成
// ランダムな初期位置、速度、質量、バウンド係数
ball.position.set((Math.random() - 0.5) * 20, Math.random() * 10 + 5, (Math.random() - 0.5) * 20); // 位置をランダムに設定
ball.velocity = new THREE.Vector3(Math.random() * 2 - 1, Math.random() * -5, Math.random() * 2 - 1); // ランダムな速度
ball.mass = Math.random() * 2 + 1; // 質量をランダムに設定
ball.bounceFactor = Math.random() * 0.5 + 0.3; // バウンド係数(0.3〜0.8)
balls.push(ball); // 配列にボールを追加
scene.add(ball); // シーンにボールを追加
}
// ボールの位置と速度を更新する関数
function updateBall(ball, deltaTime) {
// 重力を適用
ball.velocity.y += gravity * deltaTime;
// 速度に基づいて位置を更新
ball.position.add(ball.velocity.clone().multiplyScalar(deltaTime));
// 床との衝突判定
if (ball.position.y - ball.geometry.parameters.radius <= floorY) {
ball.velocity.y *= -ball.bounceFactor; // バウンド係数で速度を反転
ball.position.y = floorY + ball.geometry.parameters.radius; // 床を貫通しないように位置を補正
}
}
// シーンをアニメーションする関数
function animate() {
requestAnimationFrame(animate); // 次のフレームをリクエスト
const deltaTime = 0.016; // 60fpsに相当するフレーム間隔
// すべてのボールを更新
for (let i = 0; i < balls.length; i++) {
updateBall(balls[i], deltaTime); // 各ボールを更新
}
renderer.render(scene, camera); // シーンを描画
}
// ウィンドウサイズ変更時にリサイズを処理
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight); // レンダラーのサイズを更新
camera.aspect = window.innerWidth / window.innerHeight; // カメラのアスペクト比を更新
camera.updateProjectionMatrix(); // プロジェクションマトリックスを更新
});
// 初期化関数を実行
init();
</script>
</body>
</html>