実験 #23:回転・遠心力・重力・推進力:(ジターリングの物理)

■23個目「ジターリングの物理

こんにちは、AIと作る100のゲーム実験室の みー です。(*^_^*)/

今日は「ジターリングの物理」という、ちょっと実験要素の強いゲーム?を作りました。

ジターリングは、みーの趣味のひとつです。
いつものように夢中で練習していたら、気づけば上手になっていました。
たくさんある技はだいたいできるようになって、
今ではオリジナル技もいくつかあります。 ”◯、(^^*)

ただ……みんなジターリングを知らない(><、)

金属の輪を回して遊ぶ、丈夫なおもちゃなのですが、
手が金属の粉で黒くなったり、
音がうるさかったりして、
あまり普及しなかったみたいです。

今では「知る人ぞ知る」存在になっていると思います。

そんなジターリングの不思議な動きについて、
今回のゲーム実験は進めています。

■ AIとのやりとりで面白かった部分

(^^*)html形式で動かせるゲームを作りたいんだけど、
ジターリングの物理演算って再現できるのかな。

 〈よくAIが使っている「物理演算」という言葉を、
  かっこつけて言ってみました(`・_・)〉

(AI)ジターリングの物理演算をHTML(JavaScript)で再現するのは、
非常に面白い挑戦ですね!

 結論から言うと、「ベジェ曲線」や「極座標」を用いた
擬似的な物理演算を組み合わせることで、
ブラウザ上でもあの独特な回転と振動をかなりリアルに再現できます。

 ジターリングの動きは、単なる円運動ではなく、
以下の3つの要素が複雑に絡み合っています。

・リングの自転(Spin):ビーズがリング上を滑る動き
・リングの首振り運動(Precession):リング自体が波打つように動くジャイロ効果
・遠心力と摩擦の均衡:回転速度が上がるとリングが安定する性質

Σ(  ゜v ゜;)
〈かっこつけて物理演算なんて言葉を使ったからか、
 急に難しいことを言いだしました。
 ちなみにこのあと1~4まで説明が続きますが、
 長くて難しめなので省略〉

(^^;)
コードの叩き台を作成おねがい。

(AI)ジターリングの物理演算をブラウザで再現するための、
HTML5 CanvasとJavaScriptを用いたコードの叩き台を作成しました。

このコードでは、「マウス(またはタッチ)の上下の振り」を検知して、
リング上のビーズに遠心力(加速)を与えるロジックを組み込んでいます。

〈コードのことはよく分からないですが、
 ジターリングのことはよく知っているので、強気に返答してます。〉

(^^*)
それっぽく見えます。
横向きのローラーコースターの状態なので、
ザ・ジターの縦の状態で5つの小輪は重力の影響を受け、
ジター状態ではゆっくり下降します。

アルミの大輪の、時計の針で言うと6~9時の間で
真鍮製の5つの小輪がジター状態で回る。
6~9時の間を維持できなくなると止まります。

大輪を手前にバランスよく引くことで小輪の位置が保たれ、
その場でジター状態が維持されます。

(AI)なるほど、さすが実機を知り尽くしている方の視点ですね!
先ほどの「横向き(ローラーコースター)」の状態から、
ジターリングの真髄である「縦持ち(ザ・ジター)」の物理挙動へ
一気に寄せていきましょう。

仰る通り、垂直に持った大輪(アルミ)に対して、
小輪(真鍮)が重力で下(6時方向)へ落ちようとする力と、
大輪を「手前に引く」ことで生まれる慣性・摩擦のバランスが重要になりますね。

〈話が伝わってる…みたいです〉(>v<*)

■ 実際の動作

 これが実物のジターリングです。

 AIと相談して最初に出してくれた状態です。
 ビーズが何もしなくても高速でぐるぐると回っています。

今回の仕上がり状態です。
手前側のわっかをマウスでクリックすると回り始め、
奥の色違いの部分にビーズが来たタイミングで
もう一度クリックすると、どんどんパワフルに回転していきます。

■ コードのポイント

 今回の記事では、AI と相談しながら作った 「ジターリングの物理」の HTML コードを公開します。

  ブラウザだけで動く、とてもシンプルなゲームです。

  PC の「メモ帳」(※Windowsの場合)を開き、 下のコードをコピーして貼り付「jita.html」など 好きな名前で保存してください。

 保存したファイルをブラウザで開くだけで遊べます。

【操作方法】
・大きなリングの手前側をマウスでクリックすると回り始めます。
 タイミングよくクリックすることで、
 グルんぐるんとパワフルに回転していきます。

  コードといっても難しい部分はありません。
  貼り付けて保存するだけで動きます。

▼ここからコード▼(クリックで開く)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Jitter Ring: The Jitter Mode</title>
<style>
body { margin: 0; background: #0f0f0f; color: #e0e0e0; overflow: hidden; font-family: 'Courier New', Courier, monospace; }
canvas { display: block; }
#hud { position: absolute; top: 20px; left: 20px; pointer-events: none; }
.hint { color: #888; font-size: 0.8em; }
.active { color: #ffdf00; font-weight: bold; }
</style>
</head>
<body>
<div id="hud">
<h2>THE JITTER (縦持ち)</h2>
<div id="status">Status: IDLE</div>
<div id="speed">Power: 0</div>
<p class="hint">ビーズが<span id="zone-text">6時〜9時</span>の時にクリック(引く)!</p>
</div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let width, height;
let angle = Math.PI * 0.5; // 最初は6時(底)の位置
let speed = 0;
const gravity = 0.012; // 重力の強さ
const friction = 0.994; // 空気抵抗
const pullPower = 0.08; // 引いた時の加速量
let isPulling = false;
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
// 「手前に引く」操作
window.addEventListener('mousedown', () => { isPulling = true; });
window.addEventListener('mouseup', () => { isPulling = false; });
window.addEventListener('touchstart', (e) => { isPulling = true; e.preventDefault(); });
window.addEventListener('touchend', () => { isPulling = false; });
resize();
function update() {
// --- 物理演算 ---
// 1. 重力の影響: 角度(angle)のサイン成分で加速・減速
// 0=3時, 0.5π=6時, π=9時, 1.5π=12時
speed += Math.cos(angle) * gravity;
// 2. 摩擦
speed *= friction;
// 3. 入力判定(スイートスポット: 6時〜9時)
const currentPos = angle % (Math.PI * 2);
const inZone = currentPos > Math.PI * 0.5 && currentPos < Math.PI;
const zoneLabel = document.getElementById('zone-text');
if (inZone) {
zoneLabel.classList.add('active');
if (isPulling) {
speed += pullPower; // 加速!
isPulling = false; // 1クリック1加速
}
} else {
zoneLabel.classList.remove('active');
}
angle += speed;
// 4. ステータス更新
document.getElementById('speed').innerText = `Power: ${(speed * 100).toFixed(1)}`;
document.getElementById('status').innerText = speed > 0.2 ? "JITTERING!" : "KEEP PULLING...";
}
function draw() {
ctx.clearRect(0, 0, width, height);
const cx = width / 2;
const cy = height / 2;
const rx = 60; // 大輪の横幅(狭い)
const ry = 200; // 大輪の縦幅(長い)
// 大輪(アルミリング)の描画
ctx.beginPath();
ctx.strokeStyle = '#555';
ctx.lineWidth = 10;
ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
ctx.stroke();
// スイートスポットのガイド表示(薄く)
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 223, 0, 0.1)';
ctx.lineWidth = 15;
ctx.ellipse(cx, cy, rx, ry, 0, Math.PI * 0.5, Math.PI);
ctx.stroke();
// 小輪(ビーズ 5個)の描画
for (let i = 0; i < 5; i++) {
// わずかに間隔を開ける
const beadAngle = angle - (i * 0.08);
const bx = cx + Math.cos(beadAngle) * rx;
const by = cy + Math.sin(beadAngle) * ry;
// 奥行き表現
const z = Math.cos(beadAngle);
const size = 12 + (z * 4);
ctx.beginPath();
// 真鍮(ゴールド)っぽい色
const grad = ctx.createRadialGradient(bx-2, by-2, 2, bx, by, size);
grad.addColorStop(0, '#fff48d');
grad.addColorStop(1, '#b8860b');
ctx.fillStyle = grad;
ctx.arc(bx, by, size, 0, Math.PI * 2);
ctx.fill();
}
update();
requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>

■ 今日の学び

 今回は、大好きな趣味のひとつ「ジターリング」をテーマにしました。

 ゲーム自体は、実際のジターリングの動きとは違いますが、
ここまでの仕上がりでとりあえず満足です。(* ̄o ̄*)

 ゲームを作る前に、AIとジターリングについて色々話したのですが、
前回のクイズの記事でも書いたように、
「AIは自信をもって嘘をつくことがある」
というのを、また少し感じました。

 正確性には疑問がありましたが、
そもそもジターリングを知っている人が周りにほとんどいないので、
むしろ楽しい会話になりました。(^v^*)

 それと、記事を書くためにAIとのやり取りを読み返していたら、
最後にこんなことを言っていました。

(AI)
次は、この「ジター状態」が一定時間続いたら、
レベルが上がってマスターの口調が変わるような
「常連システム」を組み込んでみますか?

 どうやら、このあたりから
AIの口調が変化していったみたいです。(つ_<`)

■ 次回は、ゲーム実験室その2です。

「できるかな」をもとに作ってみたゲームたちを紹介します。
実験的な要素が強めの、ちょっとクセのあるゲームたち・その2です。

次の記事も、どんな動きをするのか、どんな仕組みなのか……
作っている本人もワクワクしながら試した実験です。

お楽しみに。(*^v^)ノシ

次の実験はこちら(水とドライアイス・昇華と演歌):
「ドライアイス演歌」



 ゲーム作りが楽しくて、どんどん作品が増えています(*^v^*)
 もし応援していただけたら、とても励みになります。

~このブログについて~

AIと一緒に遊び、
100の実験でゲームを育てるブログ

🌈初めての方へ
🌱このブログについて
🌳実験一覧
🍃プライバシーポリシー


AIと作る100のゲーム実験室(*^v^*)をもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む