実験#36:癒しの時間とゲーム(コーヒーハンドドリップシミュレーター)

■36個目「コーヒーハンドドリップシミュレーター

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

今回は、コーヒーのハンドドリップをシミュレーションするゲームを作ってみました。粉砕から抽出まで、本格的な“至高の一杯”を目指す小さな実験です。

選べるのは、お豆の種類・粒度・お湯の温度。 準備ができたら、
マウスをドラッグして、少しずつお湯を注いでいきます。

今回こだわったポイントは「蒸らし」の時間。(=v=*)
画面にタイマーを出さず、自分の感覚だけで20秒を測るという、
ちょっとストイックな仕様にしてみました。
(20秒の感覚は、実験#11「目隠し波動砲」で鍛えられますよ。)

(画像:実験#11「目隠し波動砲」

選べるコーヒー豆は3種類。それぞれ個性が違います。

  1. ブラジル … ナッツのような香ばしさの王道
  2. モカ … 果実のようなフルーティーな酸味
  3. ブルーマウンテン … 上品で滑らかな黄金バランス

お湯を注ぐと「コポコポ」と心地よい音が響き、抽出に合わせて液面の色も変化。
まるで香りまで漂ってきそうな臨場感で、ドリップが進んでいきます。

そして抽出が終わると…… その日の淹れ具合に応じた 「テイスティング日記」 が読めちゃいます。 どんなポエムが飛び出すか、お楽しみに!


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

(^^*)今日もゲームを作ります。html形式で動かせるゲーム。

今回は「粉砕と抽出」。
コーヒーミルとハンドドリップのシミュレーターはどうかな。

1杯分の豆を選んで、種類はブラジル・モカ・ブルーマウンテンの3種。

粒度を調整して、手動ミルでガリガリ粉砕。
粉はフィルターへ入れて、お湯の温度を決めて、マウスのドラッグで少しずつ注ぐ。 豆・粒度・温度・注ぐ速度で、最終的な味の感想が変わる……。
そんなゲームを素敵に作れないかな。

(AI) 「粉砕と抽出」、とても素敵なテーマですね。
豆がガリガリ砕ける感覚や、お湯を注いだときのふわっと膨らむ様子……。
自分の手加減ひとつで味が変わる奥深さは、まさに実験ゲームにぴったりです。

(^_^)/ お湯を注ぐときの「コポコポ」という音や、 コーヒーが少しずつ黒くなっていく変化も入れたい。 香りが漂ってきそうな雰囲気をどんどん高めましょう。

(AI) 「コポコポ」という音と、色の変化ですね。 それが入ると、ただのシミュレーターではなく、 “本当に淹れているような没入感”のあるゲームになります。

(*^.^) 豆の種類ごとのおすすめ(粒度・温度・蒸らし時間)を枠外にヒントとして出せるかな。 蒸らし時間はあえて表示せず、体内時計で行うゲーム性を出したい。 豆の特徴も一緒に紹介しましょう。

(AI) 「時間を表示せず、感覚で20秒を測る」という仕様、すごく良いです。 プレイヤーが「いまだ!」と注ぎ始める姿が目に浮かびます。

☕ 本日のコーヒー雑学

蒸らしている時に粉がふっくら膨らむのは、 お湯に触れて豆の中の炭酸ガスが一気に放出されるからです。

深煎りの豆は細胞がスカスカでガスを多く含むため、
蒸らすとダイナミックに膨らみます。
逆に古い豆はガスが抜けてしまい、ほとんど膨らみません。

(*^^) 実際に淹れてるから膨らみもわかるよ。
抽出後の評価のあとに、以前作った「どこかな温泉」みたいに 飲んだ感想を情景として書けたらいいな。

(AI) あの“湯上がり日記”のような情緒あるテキスト、
このコーヒーゲームにも絶対合います。
一杯のコーヒーを飲んだ情景が浮かぶような締めくくりにしましょう。

☕ マスターのコーヒー雑学(その2)

「モカ」という名前は豆の品種ではなく、 昔イエメンにあった モカ港 から出荷された豆の総称です。

港は今は砂に埋もれてしまいましたが、 その名前だけが“フルーティーな豆”の代名詞として残っています。 歴史のロマンを感じます。

■ 実際の動作

まずは、AIと相談しながら作ってもらったゲームの初期状態です。
シンプルな感じですが、おいしいコーヒーを作るのに意外と苦労しました。
(画像:AIが最初に作った基本のベース画面)

今回のゲームでは、
「マスターの豆ノート」 を参考にしながら至高の一杯を目指します。

(画像:豆ノートの画面)

手動ミルでガリガリ粉砕します。

(画像:粒度の調整)

蒸らし時間を合わせて、ゆっくり抽出していきます。

(画像:蒸らしと抽出)

中心をとらえて、
適切な速度でお湯を注ぐことができれば、香り高い一杯に仕上がります。

(画像:できあがり日記)

レシピ通りに淹れるのはなかなか難しく、
少しでもズレると味が変わってしまうところがリアルです。

(画像:抽出失敗)


■ コードのポイント

今回の記事では、AI と相談しながら作った 「コーヒーハンドドリップシミュレーター」 の HTML コードを公開します。

ブラウザだけで動く、とてもシンプルなゲームです。
難しい部分はほとんどないので、気軽に試してみてくださいね。

【遊ぶまでの手順】

1. PC の「メモ帳」(※Windows の場合)を開きます。
2. 下のコードをコピーして貼り付けます。
3. 「coffee.html」など、好きな名前で保存します。
4. 保存したファイルをブラウザで開くだけで遊べます。

■ 基本操作

① 今日の豆をえらぶ

ブラジル、モカ、ブルーマウンテン。 今日のあなたの気分にぴったりの豆をチョイスしてくださいね。

② ミルでガリガリ挽く

豆の個性に合わせるもよし、自分の好みを追求するもよし。
「細挽き〜粗挽き」を調整したら、
ボタンを押して香りを想像しながら豆を挽きましょう。

③ お湯の温度を決める

熱々にするか、少し落ち着かせるか。 これも美味しさを引き出す大切なポイントです。

④ いざ、ドリップ!(※ここが腕の見せどころ)

枠の中をドラッグすると、コポコポとお湯が注がれます。
最初はほんの少しだけ注いで、一度マウスを離してみてください。
ここから、美味しいコーヒーの要である 「蒸らし」 のスタートです。

画面に秒数は出ません。
自分の感覚と体内時計を信じて、じっくり待ってみてください。
「ここだ!」というタイミングで再びお湯を注ぎ切れば、
あなただけの一杯が完成です。

⑤ テイスティング日記を読む

淹れ終わると、今日のコーヒーの出来栄えが 「カフェノート」 に記録されます。
さてさて、どんな味に仕上がったかな?

▼ここからコード▼(クリックで開く)
<!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 {
font-family: 'Hiragino Maru Gothic ProN', 'Meiryo', sans-serif;
background-color: #fdfaf6;
color: #4a3f35;
text-align: center;
margin: 0;
padding: 20px;
}
#main-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
gap: 20px;
max-width: 900px;
margin: 0 auto;
}
#game-container {
background-color: #fff;
width: 100%;
max-width: 500px;
padding: 30px;
border-radius: 20px;
box-shadow: 0 10px 25px rgba(111, 78, 55, 0.1);
border: 1px solid #eaddcf;
box-sizing: border-box;
}
#hint-container {
background-color: #fffaf0;
width: 100%;
max-width: 300px;
padding: 25px;
border-radius: 10px;
box-shadow: 2px 2px 10px rgba(0,0,0,0.05);
border-left: 5px solid #8b5a2b;
text-align: left;
box-sizing: border-box;
}
#hint-container h3 {
color: #6f4e37;
margin-top: 0;
border-bottom: 1px dashed #d4c4b7;
padding-bottom: 10px;
font-size: 18px;
}
.hint-item {
margin-bottom: 15px;
font-size: 14px;
line-height: 1.6;
}
.hint-item span { font-weight: bold; color: #8b5a2b; }
h1 {
font-size: 26px;
color: #6f4e37;
border-bottom: 2px dashed #d4c4b7;
padding-bottom: 15px;
margin-top: 0;
}
h2 { color: #8b5a2b; font-size: 20px; margin-top: 25px; }
.phase { display: none; margin-top: 20px; animation: fadeIn 0.5s; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.active { display: block; }
button {
background-color: #8b5a2b;
color: white;
border: none;
padding: 12px 24px;
margin: 8px;
border-radius: 30px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
box-shadow: 0 4px 0 #6f4e37;
}
button:hover { background-color: #6f4e37; transform: translateY(2px); box-shadow: 0 2px 0 #6f4e37; }
button:active { transform: translateY(4px); box-shadow: 0 0px 0 #6f4e37; }
input[type=range] { width: 80%; margin: 15px 0; cursor: pointer; }
.bean-icon { font-size: 48px; margin-bottom: 10px; }
#grind-dripper {
width: 100px; height: 80px; background-color: #eaddcf;
border-radius: 0 0 50px 50px; margin: 20px auto; position: relative; border: 3px solid #b89f89;
}
#grind-powder {
position: absolute; bottom: 5px; left: 5px; right: 5px;
background-color: #6f4e37; border-radius: 0 0 45px 45px; transition: height 0.3s; height: 0px;
}
#drip-area {
width: 100%; height: 180px; background-color: #eaddcf; border: 3px dashed #b89f89;
border-radius: 15px; margin: 20px 0; cursor: crosshair; position: relative;
overflow: hidden; user-select: none; display: flex; flex-direction: column;
align-items: center; justify-content: center;
}
#drip-instructions {
z-index: 10; background: rgba(255,255,255,0.85); padding: 10px 15px;
border-radius: 10px; pointer-events: none; font-weight: bold; color: #4a2511;
text-align: center; line-height: 1.4;
}
.water-drop {
position: absolute; width: 6px; height: 10px; background-color: rgba(220, 181, 148, 0.7);
border-radius: 50%; animation: dropDown 1s linear forwards;
}
@keyframes dropDown { to { transform: translateY(200px); opacity: 0; } }
#cup-section { margin-top: 20px; }
#cup {
width: 120px; height: 100px; background-color: #fff; border: 4px solid #d4c4b7;
border-radius: 0 0 60px 60px; margin: 0 auto; position: relative; overflow: hidden;
}
#cup-coffee {
position: absolute; bottom: 0; left: 0; right: 0; background-color: #fff;
height: 0px; transition: height 0.1s, background-color 0.1s;
}
#cup-handle {
width: 40px; height: 60px; border: 4px solid #d4c4b7; border-radius: 50%;
position: absolute; top: 10px; right: -30px;
}
#cup-progress-bg {
width: 80%; height: 15px; background-color: #eee; border-radius: 10px;
margin: 15px auto 0; overflow: hidden; border: 1px solid #d4c4b7;
}
#cup-progress { width: 0%; height: 100%; background-color: #4a2511; transition: width 0.1s; }
#result-text {
font-size: 15px; line-height: 1.8; text-align: left; background: #fdfaf6;
padding: 20px; border-radius: 10px; border: 1px solid #eaddcf; box-shadow: inset 0 2px 5px rgba(0,0,0,0.05);
}
.diary-entry {
margin-top: 25px;
padding: 25px 20px 20px 20px;
background-image:
linear-gradient(#fdfaf6 1px, transparent 1px),
linear-gradient(90deg, #fdfaf6 1px, transparent 1px),
linear-gradient(#e0d5c1 1px, transparent 1px);
background-size: 100% 1.8em, 100% 1.8em, 100% 1.8em;
background-color: #faf7f2;
border-radius: 5px; color: #4a3f35; font-size: 16px; line-height: 1.8em;
box-shadow: 2px 3px 6px rgba(0,0,0,0.08); position: relative;
}
.diary-entry::before {
content: ""; position: absolute; top: -10px; left: 50%; transform: translateX(-50%) rotate(-2deg);
width: 80px; height: 25px; background-color: rgba(220, 180, 150, 0.4);
}
.diary-date { font-weight: bold; color: #d35400; margin-bottom: 5px; text-align: left; }
</style>
</head>
<body>
<div id="main-wrapper">
<div id="game-container">
<h1>至高の一杯</h1>
<div id="phase-1" class="phase active">
<h2>1. コーヒー豆の選択</h2>
<p>今日淹れる豆を選んでください。</p>
<div style="display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;">
<button onclick="selectBean('ブラジル', '🇧🇷')"><div class="bean-icon">🇧🇷</div>ブラジル<br>(バランス)</button>
<button onclick="selectBean('モカ', '☕')"><div class="bean-icon"></div>モカ<br>(フルーティー)</button>
<button onclick="selectBean('ブルーマウンテン', '🇯🇲')"><div class="bean-icon">🇯🇲</div>ブルーマウンテン<br>(上品)</button>
</div>
</div>
<div id="phase-2" class="phase">
<h2>2. ミルで粉砕</h2>
<p>粒度を調整してください。</p>
<label>細挽き ← <input type="range" id="grind-size" min="1" max="5" value="3"> → 粗挽き</label>
<div id="grind-dripper"><div id="grind-powder"></div></div>
<button id="grind-btn" onclick="grindBeans()">ガリガリ挽く(あと5回)</button>
</div>
<div id="phase-3" class="phase">
<h2>3. ハンドドリップ抽出</h2>
<p>お湯の温度を決めてください。</p>
<label>80℃ <input type="range" id="water-temp" min="80" max="100" value="90"> 100℃</label>
<p>設定温度: <span id="temp-display">90</span></p>
<div id="drip-area">
<div id="drip-instructions">ドラッグでお湯を少し注ぎ<br>「蒸らし」を開始 💧</div>
</div>
<div id="cup-section">
<div style="position: relative; width: 120px; margin: 0 auto;">
<div id="cup"><div id="cup-coffee"></div></div>
<div id="cup-handle"></div>
</div>
<div id="cup-progress-bg"><div id="cup-progress"></div></div>
<p>抽出量: <span id="extract-percent">0</span>%</p>
</div>
</div>
<div id="phase-4" class="phase">
<h2>できあがり!</h2>
<div id="result-text"></div>
<br>
<button onclick="location.reload()">もう一杯淹れる</button>
</div>
</div>
<div id="hint-container">
<h3>📝 マスターの豆ノート</h3>
<div class="hint-item">
<span>🇧🇷 ブラジル</span><br>
ナッツのような香ばしさと適度な苦味が特徴。<br>
・粒度:<b>中挽き(3)</b><br>・温度:<b>90℃</b><br>・蒸らし:<b>約20〜30秒</b>
</div>
<div class="hint-item">
<span>☕ モカ</span><br>
果実のようなフルーティーな酸味が魅力。<br>
・粒度:<b>中細挽き(2)</b><br>・温度:<b>85℃</b><br>・蒸らし:<b>約15〜25秒</b>
</div>
<div class="hint-item">
<span>🇯🇲 ブルーマウンテン</span><br>
非常に上品で滑らかな口当たり。<br>
・粒度:<b>中粗挽き(4)</b><br>・温度:<b>92℃</b><br>・蒸らし:<b>約25〜35秒</b>
</div>
</div>
</div>
<script>
let state = {
bean: "", beanIcon: "", grind: 3, temp: 90,
dripStartTime: 0, dripEndTime: 0, grindCount: 5, maxGrindCount: 5, extraction: 0,
hasBloomed: false, isBlooming: false, bloomStartTime: 0, bloomTime: 0
};
let audioCtx;
let mainGain;
// 音響システム初期化
function initAudio() {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
mainGain = audioCtx.createGain();
mainGain.gain.setValueAtTime(0.5, audioCtx.currentTime);
mainGain.connect(audioCtx.destination);
}
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
}
// --- 効果音:粉砕音(ガリガリ) ---
function playGrindSound() {
const duration = 0.3;
const noise = audioCtx.createBufferSource();
const buffer = audioCtx.createBuffer(1, audioCtx.sampleRate * duration, audioCtx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < data.length; i++) data[i] = Math.random() * 2 - 1;
noise.buffer = buffer;
const filter = audioCtx.createBiquadFilter();
filter.type = 'bandpass';
filter.frequency.setValueAtTime(400, audioCtx.currentTime);
filter.Q.setValueAtTime(2, audioCtx.currentTime);
const g = audioCtx.createGain();
g.gain.setValueAtTime(0.3, audioCtx.currentTime);
g.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);
noise.connect(filter);
filter.connect(g);
g.connect(mainGain);
noise.start();
}
// --- 効果音:抽出音(コポコポ) ---
let pourGain;
let pourNoise;
function startPourSound() {
pourNoise = audioCtx.createOscillator();
pourNoise.type = 'sine';
const lfo = audioCtx.createOscillator();
lfo.frequency.setValueAtTime(10, audioCtx.currentTime);
const lfoGain = audioCtx.createGain();
lfoGain.gain.setValueAtTime(100, audioCtx.currentTime);
pourGain = audioCtx.createGain();
pourGain.gain.setValueAtTime(0, audioCtx.currentTime);
pourGain.gain.linearRampToValueAtTime(0.1, audioCtx.currentTime + 0.2);
lfo.connect(lfoGain);
lfoGain.connect(pourNoise.frequency);
pourNoise.connect(pourGain);
pourGain.connect(mainGain);
lfo.start();
pourNoise.start();
}
function stopPourSound() {
if (pourGain) {
pourGain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.2);
setTimeout(() => { if(pourNoise) pourNoise.stop(); }, 200);
}
}
// --- フェーズ進行 ---
function selectBean(beanName, icon) {
initAudio();
state.bean = beanName; state.beanIcon = icon;
document.getElementById('phase-1').classList.remove('active');
document.getElementById('phase-2').classList.add('active');
}
function grindBeans() {
playGrindSound();
state.grindCount--;
const maxPowderHeight = 64;
document.getElementById('grind-powder').style.height = (((state.maxGrindCount - state.grindCount) / state.maxGrindCount) * maxPowderHeight) + "px";
if (state.grindCount === 0) {
state.grind = parseInt(document.getElementById('grind-size').value);
document.getElementById('phase-2').classList.remove('active');
document.getElementById('phase-3').classList.add('active');
}
}
// ★ここで温度表示をリアルタイム更新する処理を復活!
document.getElementById('water-temp').addEventListener('input', function(e) {
document.getElementById('temp-display').innerText = e.target.value;
});
// ドリップ操作
const dripArea = document.getElementById('drip-area');
let dropInterval;
dripArea.addEventListener('mousedown', () => {
if (state.extraction >= 100) return;
if (state.isBlooming) {
state.isBlooming = false; state.hasBloomed = true;
state.bloomTime = (Date.now() - state.bloomStartTime) / 1000;
}
if (state.extraction === 0) state.dripStartTime = Date.now();
startPourSound();
dropInterval = setInterval(() => {
const drop = document.createElement('div');
drop.classList.add('water-drop');
drop.style.left = Math.random() * (dripArea.offsetWidth - 10) + 5 + 'px';
dripArea.appendChild(drop);
setTimeout(() => drop.remove(), 1000);
}, 100);
state.isPouring = true;
});
window.addEventListener('mouseup', () => {
if (state.isPouring) {
state.isPouring = false;
stopPourSound();
clearInterval(dropInterval);
if (!state.hasBloomed && state.extraction > 0 && state.extraction < 100) {
state.isBlooming = true; state.bloomStartTime = Date.now();
document.getElementById('drip-instructions').innerHTML = `蒸らし中...<br>(香りが立ち上るのを感じて)`;
document.getElementById('drip-instructions').style.display = 'block';
}
}
});
dripArea.addEventListener('mousemove', () => {
if (state.isPouring && state.extraction < 100) {
state.extraction += 0.35;
updateVisuals();
if (state.extraction >= 100) finish();
}
});
function updateVisuals() {
document.getElementById('cup-progress').style.width = state.extraction + "%";
document.getElementById('extract-percent').innerText = Math.floor(state.extraction);
document.getElementById('cup-coffee').style.height = (state.extraction * 0.8) + "px";
const r = Math.floor(234 + (74 - 234) * (state.extraction / 100));
const g = Math.floor(221 + (37 - 221) * (state.extraction / 100));
const b = Math.floor(207 + (17 - 207) * (state.extraction / 100));
document.getElementById('cup-coffee').style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
}
function finish() {
state.dripEndTime = Date.now();
state.temp = parseInt(document.getElementById('water-temp').value);
stopPourSound();
document.getElementById('phase-3').classList.remove('active');
document.getElementById('phase-4').classList.add('active');
showResult();
}
function showResult() {
let ideal = { temp: 90, grind: 3, bloomMin: 20, bloomMax: 30 };
if (state.bean === 'モカ') ideal = { temp: 85, grind: 2, bloomMin: 15, bloomMax: 25 };
else if (state.bean === 'ブルーマウンテン') ideal = { temp: 92, grind: 4, bloomMin: 25, bloomMax: 35 };
let review = `<b>【テクニカル評価】</b><br>`;
let score = 0;
// 蒸らし判定
if (state.bloomTime === 0) review += "❌ 蒸らしなし。<br>";
else if (state.bloomTime < ideal.bloomMin) review += `⚠️ 蒸らし不足(約${state.bloomTime.toFixed(1)}秒)。<br>`;
else if (state.bloomTime > ideal.bloomMax) review += `⚠️ 蒸らしすぎ(約${state.bloomTime.toFixed(1)}秒)。<br>`;
else { review += `✨ <b>完璧な蒸らし!</b>(${state.bloomTime.toFixed(1)}秒)<br>`; score++; }
// 温度判定
if (state.temp === ideal.temp) { review += `✨ <b>温度設定が完璧!</b><br>`; score++; }
else if (state.temp > ideal.temp) review += `⚠️ お湯が熱すぎます。<br>`;
else review += `⚠️ お湯がぬるすぎます。<br>`;
// 粒度判定
if (state.grind === ideal.grind) { review += `✨ <b>粒度がベストマッチ!</b><br>`; score++; }
else if (state.grind < ideal.grind) review += `⚠️ 推奨より細挽きです。<br>`;
else review += `⚠️ 推奨より粗挽きです。<br>`;
// 日記テキスト
let diaryText = "";
if (score === 3) {
if(state.bean === 'ブラジル') diaryText = "わぁっ、今日の一杯は最高!ナッツみたいに香ばしい香りがフワ〜ッと広がって、一口飲むと「これこれ!」ってなる王道の美味しさ。あぁ、自分で丁寧に淹れたコーヒーってなんでこんなに美味しいんだろう♪よし、今日も一日頑張るぞ!";
if(state.bean === 'モカ') diaryText = "大成功!お湯を注いだ瞬間から、フルーツみたいに甘くて華やかな香りが広がる〜!一口飲むと、爽やかな酸味がパッと口に広がって、気分までパッと明るくなるなぁ。じっくり温度を下げて淹れた甲斐があった!明日の朝も絶対にこれ淹れようっと♪";
if(state.bean === 'ブルーマウンテン') diaryText = "キター!これぞ黄金バランス!スッと滑らかに喉を通って、あとからフワ〜っと上品な香りが追いかけてくる。まるでお店で飲むみたいな贅沢な味!じっくり蒸らしたから、豆のポテンシャルを120%引き出せたかも。誰かに自慢したくなる極上の一杯!";
} else if (score >= 1) {
diaryText = `ん〜、いい香り!淹れたてのアツアツをふーふーしながら飲むこの時間がたまらないんだよね。今日は${state.bean}の個性がちょっと元気に顔を出してるけど、それもまた愛嬌。美味しいコーヒーを飲むとエネルギーが湧いてくるなぁ。`;
} else {
diaryText = `あれれ、今日はちょっぴり雑味が出ちゃったかな?でも、お湯を注いでコーヒーのドームがぷく〜っと膨らむのを見てる時間はすごくワクワクした!次はもうちょっと落ち着いてリベンジするぞー!`;
}
const dateStr = new Date().toLocaleDateString() + " ☕";
// 評価と日記を合体
document.getElementById('result-text').innerHTML = review + `<div class="diary-entry"><div class="diary-date">${dateStr}</div>${diaryText}</div>`;
}
</script>
</body>
</html>


■ 今日の学び

「おいしいコーヒー」の作り方のイメージにつながるゲームができました。
U、(*= 。=)⁼3

ハンドドリップのコーヒーは、感覚的な部分がとても多くて、 同じ豆でも毎回ちがう表情を見せてくれます。 その“一期一会”の味わいこそが、コーヒーの魅力だと思います。

今回のゲーム作りでは、AI からたくさんの豆知識をもらいながら、
自分でも淹れ方を改めて見直す良いきっかけになりました。

ゲーム制作そのものが、まるで小さなコーヒー講座のようで、
とても素敵な学びになったと思います。ヽ(*^_^*)ノ

■ 次回は、まさかの主役の「アカメカッパ」
 
#31「カッパ綱引き」に登場したあの強敵、
アカメカッパがまさかの主役に返り咲きます。

今回は、どこか懐かしい“電子ゲーム風”の実験。 シンプルなのにクセになる、
昔の携帯ゲーム機を思い出すような仕上がりです。

今日も読んでくださってありがとうございます。
コーヒーの香りが届きますように。

次回もお楽しみに。(^v^)ノシ

次の実験はこちら(畑荒らしの天罰回避): 「嵐のキュウリ畑」



 今日も最後まで読んでくださって、ありがとうございます。
みーの実験室は、みなさんの応援で元気に動いています。(*^v^*)

~このブログについて~

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

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


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

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

続きを読む