■16個目「お絵描き雲」
こんにちは、AIと作る100のゲーム実験室の みー です。(^^*)
今回は、雲を描いて、風で変化していく様子を楽しむお絵描きゲームです。
以前製作しました動くお絵描き「シュミラクラお絵描きゲーム」に続いて、絵画ゲーム第2弾を作ってみました。
日頃から何かに形の似た雲や、ヒコーキ雲を見かけると、青空へ自分の思い通りの雲の絵をかいてみたいなと、よく思ってました。(*=v=)~♪
AIと相談すればできるかもしれないと思い、作ってみたのがこのゲームです。
■ AIとのやりとりで面白かった部分
(^^*)今日もゲーム作ります。空のキャンパスに雲で絵を描く。
雲は、ある程度輪郭がわかるモフモフ感のある線で、マウスドラッグで描けます。
色や太さは調整できて、描いた雲は風に少しずつ流されて形が変わっていきます。
風は右から左へ、ほんの少しだけ吹いていて、
クリアボタンを押すと突風が吹き、描いた雲が全部流されて消えていきます。
その時だけの作品で、常に変化する形。
不思議で、ちょっと切なくて、素敵なお絵描き体験を再現したゲームです。
(AI)お疲れ様です!お絵描きゲーム第2弾ですね。
「形が常に変化し、風に流されて消えていく」というコンセプト、
非常に風情があって素敵です。
(AI)常連さまへの、空の小話
今日もいいお絵描きですね。
雲の「輪郭」についてですが、実は気象学でも
**「雲の境界線」**を定義するのはとても難しいことなんです。
近くで見ると雲は霧のような水滴の集まりで、
どこからが空でどこからが雲か、はっきりした線はありません。
私たちが「あ、雲だ」と認識できるのは、
光が水滴に当たって散乱(ミー散乱)しているからなんですね。
「境界線が曖昧だからこそ美しい」というのは、
デジタルなお絵描きでも同じかもしれません。
(*^o^)青空に雲、へいわな感じがいいね。
(AI)常連さまへの、空の小話 その2
スマホで外を歩きながら、ふと見上げた空を描く……なんて素敵ですね。
雲がゆっくり崩れていく様子を眺めることは、
マインドフルネス(瞑想)に近いリラックス効果があると言われています。
ところで、雲には10種類の基本形(十種雲形)がありますが、
このアプリならそのどれもが再現可能です。
細く描けば「巻雲(すじ雲)」、大きく重ねれば「積雲(わた雲)」……。
〈最初の目的の雲のお絵描きが実現したので満足です。〉(*^^)
■ 実際の動作
AIが最初に作ってくれたゲームの状態。
白なのにくろいつぶつぶがびっしりに(><;)修正したのが次の画像です…

筆の太さと、色を決めたらマウスですぐ描けます(*^_^*)「

時間経過で、雲は少しづつ形が崩れ流れていきます・・・

描いていくうちから崩れていくので、その時だけの作品です。
「突風を吹かせる」で一周で吹き飛びます!

製作中にAIのイメージしたゲーム画面です。

■ コードのポイント
今回の記事では、AI と相談しながら作った「お絵描き雲」の HTML コードを公開します。ブラウザだけで動く、とてもシンプルなゲームです。
PC の「メモ帳」(※Windowsの場合)を開き、下のコードをコピーして貼り付け、「oekakikumo.html」など好きな名前で保存 → ブラウザで開く。これだけで遊べます。
操作はとても簡単で、筆の太さと色を調節して、マウスでドラッグするだけで描けます。突風を含ボタンを押すと、全部吹き飛んで消えます。
▼ここからコード▼(クリックで開く)
<!DOCTYPE html><html lang="ja"><head> <meta charset="UTF-8"> <title>Cloud Artist - 雲のキャンバス</title> <style> body { margin: 0; overflow: hidden; background: linear-gradient(to bottom, #4A90E2 0%, #87CEEB 100%); font-family: 'Hiragino Kaku Gothic ProN', sans-serif; user-select: none; } #ui { position: absolute; top: 20px; left: 20px; background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(10px); padding: 20px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); z-index: 10; display: flex; flex-direction: column; gap: 15px; width: 250px; } .row { display: flex; flex-direction: column; gap: 5px; } label { font-size: 12px; color: #333; font-weight: bold; } canvas { display: block; touch-action: none; } button { padding: 12px; border: none; border-radius: 8px; background: #fff; color: #4A90E2; font-weight: bold; cursor: pointer; box-shadow: 0 4px 0 #ccc; transition: 0.1s; } button:active { transform: translateY(2px); box-shadow: 0 2px 0 #ccc; } input[type="range"] { width: 100%; cursor: pointer; } </style></head><body><div id="ui"> <div class="row"> <label>筆の太さ</label> <input type="range" id="size" min="10" max="80" value="40"> </div> <div class="row"> <label>雲の色み(白ベース)</label> <input type="color" id="cloudColor" value="#ffffff"> </div> <button id="clear">突風を吹かせる</button></div><canvas id="canvas"></canvas><script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const sizeInput = document.getElementById('size'); const colorInput = document.getElementById('cloudColor'); const clearBtn = document.getElementById('clear'); let particles = []; let isDrawing = false; let isGusting = false; // --- 高速化のためのテクニック:オフスクリーンキャンバスに雲の素を事前描画 --- const spriteCanvas = document.createElement('canvas'); const sCtx = spriteCanvas.getContext('2d'); const spriteSize = 200; spriteCanvas.width = spriteCanvas.height = spriteSize; function updateCloudSprite(color) { sCtx.clearRect(0, 0, spriteSize, spriteSize); const grad = sCtx.createRadialGradient(spriteSize/2, spriteSize/2, 0, spriteSize/2, spriteSize/2, spriteSize/2); grad.addColorStop(0, color + "44"); // 中心は少し濃い(16進数+透明度) grad.addColorStop(0.5, color + "22"); grad.addColorStop(1, color + "00"); // 外側は完全に透明 sCtx.fillStyle = grad; sCtx.fillRect(0, 0, spriteSize, spriteSize); } updateCloudSprite(colorInput.value); colorInput.addEventListener('input', (e) => updateCloudSprite(e.target.value)); function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } window.addEventListener('resize', resize); resize(); class Particle { constructor(x, y, size) { this.x = x; this.y = y; this.originalSize = size; this.size = size; this.vx = -0.1 - Math.random() * 0.2; // 基本の風(右から左) this.vy = (Math.random() - 0.5) * 0.1; // 形を崩すためのノイズ速度 this.dx = (Math.random() - 0.5) * 0.2; this.dy = (Math.random() - 0.5) * 0.2; this.opacity = 1.0; } update() { // 風による移動 this.x += this.vx; this.y += this.vy; // 徐々に形が崩れる(拡散) this.x += this.dx; this.y += this.dy; // 突風 if (isGusting) { this.vx -= 0.8; this.opacity -= 0.02; } return (this.x + this.size > 0 && this.opacity > 0); } draw() { ctx.globalAlpha = this.opacity; // 事前描画したスプライトを描画(これが一番速い) ctx.drawImage(spriteCanvas, this.x - this.size/2, this.y - this.size/2, this.size, this.size); } } function getPos(e) { if (e.touches) return { x: e.touches[0].clientX, y: e.touches[0].clientY }; return { x: e.clientX, y: e.clientY }; } function startDrawing(e) { isDrawing = true; addParticles(e); } function moveDrawing(e) { if (isDrawing) addParticles(e); } function stopDrawing() { isDrawing = false; } function addParticles(e) { const pos = getPos(e); const s = parseInt(sizeInput.value); for(let i=0; i<2; i++) { const ox = (Math.random() - 0.5) * s; const oy = (Math.random() - 0.5) * s; particles.push(new Particle(pos.x + ox, pos.y + oy, s * (0.8 + Math.random()))); } } canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('mousemove', moveDrawing); window.addEventListener('mouseup', stopDrawing); canvas.addEventListener('touchstart', startDrawing); canvas.addEventListener('touchmove', moveDrawing); canvas.addEventListener('touchend', stopDrawing); clearBtn.addEventListener('click', () => { isGusting = true; setTimeout(() => { particles = []; isGusting = false; }, 2000); }); function loop() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 描画モードを「重ねると明るくなる」設定にして雲の密度を表現 ctx.globalCompositeOperation = 'screen'; particles = particles.filter(p => { const alive = p.update(); if (alive) p.draw(); return alive; }); ctx.globalCompositeOperation = 'source-over'; requestAnimationFrame(loop); } loop();</script></body></html>
■ 今日の学び
前回の記事で、スマホでの遊ぶ方法もAiに教えてもらってたので、この「お絵描き雲」のゲームも早速入れてみました。
今回は、スマホでの操作性と雲の表現について新しい発見がありました。
指で雲が欠ける感じが魔法っぽくて面白い♪
スマホで遊ぶほうが個人的には気に入ってます。
気づけば R8.3.14 の時点で 約60本のゲームになりました。
記事の更新ペースにはムラがありますが、少し間が空いているときは新しいゲーム作りに夢中になってると思ってください(つv<)
次回は「錯視実験」ゲームです。
どうぞお楽しみに(*^v^)ノシ
次の実験はこちら(アクションと錯視): 「しょうが君錯視ゲーム」
ゲーム作りが楽しくて、どんどん作品が増えています(*^v^*)
もし応援していただけたら、とても励みになります。

コメントを残す