皆さん、こんにちは!Google Gemini3の勢いが止まりません!推論、サイトやコードの生成、果てはNanobanana Proで画像生成も自由自在とまさに無双状態です!
「ちょっとゲームでも作れないかな?」と思って軽くプロンプトを投げたら、
まさかの 本当に動くゲーム が完成しました。
今回は、当ブログのマスコットキャラクター
“シンナモ” を主人公にしたボンバーマン風ゲーム。
正直、Gemini 3 のコード生成力をナメてました……。
これ、普通に遊べるレベルです。
Google Gemini3はこちらhttps://gemini.google.com/app?hl=ja
はじまりは「初代ゼルダみたいなの作って」の一言から
最初に試したプロンプトは、わずか数行の簡単なもの。
初代ゼルダの伝説のような、画面端に行くと画面がスライドするアクションゲームを作って。
MAPはランダムでお願いします。
これだけで、Gemini 3 は ランダムマップ生成+部屋切り替えのアクションゲーム を1ファイルで作り上げました。
完成品がこちらhttps://ai-workstudio.site/wp-content/uploads/2025/11/zelda.html

(画像はGoogle Gemini3より生成したものをキャプチャーしております)
Gemini 3 は「ゼルダ風ゲーム」という文脈をしっかり理解しているようで、短い指示でも必要な要素を自動で補完してくれるのが特徴です。

簡単なプロンプトなのにちゃんとできてるなも!?

Gemin3に進化してユーザーさんの意思をさらにくみ取れるようになったなも!目に見えない変化だけど、これってめちゃくちゃ重要なことなも!
次は「ボンバーマン風+シンナモ主人公」に挑戦
ゼルダ風ゲームが動いたことで、次に興味がわいたのがこちら。
シンナモを主人公にして、ボンバーマン風のゲームは作れないか?
というものです。

僕もボンバーマンみたいに敵を倒してみたいなも~!

あんたがボンバーマンに…?自爆なんかしないなもよね…?
そこで、以下のように「ゲームとして最低限必要な仕様」と「シンナモの見た目」を丁寧にプロンプト化して Gemini 3 に渡しました。
Shinnamo Bomber Mobile
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Shinnamo Bomber Mobile</title>
<style>
:root {
--tile-size: 40px;
--bg-color: #3a4a3b;
--wall-color: #555;
--block-color: #d38e54;
--bomb-color: #333;
--expl-color: #ffaa00;
/* シンナモのカラーパレット */
--shin-body: #baff58;
--shin-shadow: #9acd32;
--shin-eye: #1a1a1a;
--shin-highlight: #baff58;
--shin-cheek: #ff9999;
}
body {
background-color: #222;
color: white;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start; /* 上寄せに変更 */
height: 100vh;
margin: 0;
overflow: hidden;
touch-action: none; /* スマホでのスクロール無効化 */
}
h1 { margin: 10px 0 5px 0; font-size: 18px; text-align: center; }
.controls-info { font-size: 12px; color: #aaa; margin-bottom: 5px; text-align: center; }
/* ゲーム全体を包むラッパー(縮小用) */
#game-wrapper {
display: flex;
justify-content: center;
width: 100%;
margin-bottom: 10px;
}
/* ゲームボード */
#game-board {
position: relative;
background-color: var(--bg-color);
border: 4px solid #888;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
/* 初期サイズ(JSで制御しますがCSSでも定義) */
width: 600px;
height: 440px;
flex-shrink: 0;
}
/* --- スマホ用コントローラー --- */
#mobile-controls {
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: 500px;
padding: 10px 20px;
box-sizing: border-box;
margin-top: auto; /* 画面下部に配置 */
margin-bottom: 20px;
}
/* 十字キーエリア */
.d-pad {
display: grid;
grid-template-columns: 60px 60px 60px;
grid-template-rows: 60px 60px;
gap: 5px;
}
.btn {
background: rgba(255, 255, 255, 0.15);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 10px;
color: white;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
user-select: none;
touch-action: manipulation;
transition: background 0.1s;
}
.btn:active { background: rgba(255, 255, 255, 0.4); }
/* 配置調整 */
.btn-up { grid-column: 2; grid-row: 1; }
.btn-left { grid-column: 1; grid-row: 2; }
.btn-down { grid-column: 2; grid-row: 2; }
.btn-right { grid-column: 3; grid-row: 2; }
/* 爆弾ボタン */
.btn-bomb {
width: 90px;
height: 90px;
border-radius: 50%;
background: rgba(255, 80, 80, 0.3);
border-color: rgba(255, 80, 80, 0.6);
font-weight: bold;
font-size: 16px;
}
.btn-bomb:active { background: rgba(255, 80, 80, 0.6); }
/* --- 以下、ゲーム内パーツ(前回と同じ) --- */
/* タイル共通 */
.tile {
width: var(--tile-size);
height: var(--tile-size);
position: absolute;
box-sizing: border-box;
}
.wall {
background: repeating-linear-gradient(45deg, #555, #555 5px, #444 5px, #444 10px);
border: 2px solid #333;
box-shadow: inset 0 0 5px black;
}
.block {
background-color: var(--block-color);
border: 2px solid #8b4513;
box-shadow: inset 3px 3px 0 rgba(255,255,255,0.2), inset -3px -3px 0 rgba(0,0,0,0.2);
}
.bomb {
background: radial-gradient(circle at 30% 30%, #666, #000);
border-radius: 50%;
width: 30px; height: 30px;
top: 5px; left: 5px;
position: absolute;
animation: pulse 0.5s infinite alternate;
z-index: 5;
}
.bomb::before { content: ''; position: absolute; top: -5px; left: 50%; width: 4px; height: 8px; background: orange; transform: translateX(-50%); }
@keyframes pulse { from { transform: scale(1); } to { transform: scale(1.1); } }
.explosion {
background-color: var(--expl-color);
opacity: 0.8;
z-index: 4;
animation: fadeOut 0.5s forwards;
}
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }
/* --- 主人公:シンナモ --- */
#player {
width: 34px; height: 34px;
position: absolute; z-index: 10;
transition: top 0.1s linear, left 0.1s linear;
transform-origin: bottom center;
}
.shinnamo-body {
width: 100%; height: 100%;
background-color: var(--shin-body);
border-radius: 12px 12px 16px 16px;
position: relative;
box-shadow: inset -3px -3px 5px rgba(0,0,0,0.1);
animation: breathe 2s infinite ease-in-out;
}
.shinnamo-hat {
position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
background: white; color: #333; font-size: 10px; font-weight: bold;
padding: 1px 4px; border-radius: 4px; box-shadow: 0 2px 2px rgba(0,0,0,0.2); z-index: 12;
}
.shinnamo-hat::after { content: ''; position: absolute; bottom: -2px; left: -2px; right: -2px; height: 2px; background: #ddd; border-radius: 2px; }
.shinnamo-face { position: absolute; top: 10px; left: 0; width: 100%; height: 20px; display: flex; justify-content: center; gap: 8px; }
.eye { width: 6px; height: 8px; background-color: var(--shin-eye); border-radius: 2px; position: relative; }
.eye::after { content: ''; position: absolute; top: 1px; left: 1px; width: 2px; height: 2px; background-color: var(--shin-highlight); }
.cheek { position: absolute; top: 8px; width: 6px; height: 4px; background-color: var(--shin-cheek); border-radius: 50%; opacity: 0.7; }
.cheek.left { left: 4px; } .cheek.right { right: 4px; }
@keyframes breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05, 0.95); } }
.walking .shinnamo-body { animation: walk 0.3s infinite alternate; }
@keyframes walk { from { transform: rotate(-5deg); } to { transform: rotate(5deg); } }
/* --- 敵キャラ --- */
.enemy {
width: 30px; height: 30px; background: #ff5555;
border-radius: 50% 50% 10% 10%; position: absolute; z-index: 8;
transition: top 0.5s linear, left 0.5s linear;
box-shadow: inset -2px -2px 5px rgba(0,0,0,0.3);
}
.enemy::before, .enemy::after { content: ''; position: absolute; top: 8px; width: 6px; height: 6px; background: white; border-radius: 50%; }
.enemy::before { left: 6px; } .enemy::after { right: 6px; }
/* オーバーレイ */
#overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
display: none; flex-direction: column; align-items: center; justify-content: center;
z-index: 100;
}
#message { font-size: 40px; font-weight: bold; margin-bottom: 20px; text-align: center; }
button { padding: 10px 20px; font-size: 18px; cursor: pointer; background: var(--shin-body); border: none; border-radius: 5px; color: #222; font-weight: bold;}
</style>
</head>
<body>
<h1>Shinnamo Bomber 💣</h1>
<div class="controls-info">PC: 矢印キー&Space | スマホ: 下のボタン</div>
<div id="game-wrapper">
<div id="game-board">
</div>
</div>
<div id="mobile-controls">
<div class="d-pad">
<div class="btn btn-up" ontouchstart="handleTouch('up', event)" onmousedown="handleTouch('up', event)">↑</div>
<div class="btn btn-left" ontouchstart="handleTouch('left', event)" onmousedown="handleTouch('left', event)">←</div>
<div class="btn btn-down" ontouchstart="handleTouch('down', event)" onmousedown="handleTouch('down', event)">↓</div>
<div class="btn btn-right" ontouchstart="handleTouch('right', event)" onmousedown="handleTouch('right', event)">→</div>
</div>
<div class="btn btn-bomb" ontouchstart="handleTouch('bomb', event)" onmousedown="handleTouch('bomb', event)">BOMB</div>
</div>
<div id="overlay">
<div id="message">GAME OVER</div>
<button onclick="initGame()">もう一回遊ぶ</button>
</div>
<script>
// --- 設定 ---
const TILE_SIZE = 40;
const ROWS = 11;
const COLS = 15;
const EMPTY = 0;
const WALL = 1;
const BLOCK = 2;
let map = [];
let player = { x: 1, y: 1, el: null };
let enemies = [];
let bombs = [];
let gameActive = false;
const boardEl = document.getElementById('game-board');
const overlayEl = document.getElementById('overlay');
const messageEl = document.getElementById('message');
const wrapperEl = document.getElementById('game-wrapper');
// ボードサイズ設定
boardEl.style.width = `${COLS * TILE_SIZE}px`;
boardEl.style.height = `${ROWS * TILE_SIZE}px`;
// --- レスポンシブ対応: 画面に合わせてゲームボードを縮小 ---
function resizeBoard() {
const screenWidth = window.innerWidth;
const boardWidth = COLS * TILE_SIZE; // 600px
// 画面幅がボードより小さい場合、縮小率を計算
// 少し余白(40px)を持たせる
let scale = Math.min(1, (screenWidth - 20) / boardWidth);
boardEl.style.transformOrigin = "top center";
boardEl.style.transform = `scale(${scale})`;
// 縮小した分、下の余白が空きすぎるので高さを調整
const scaledHeight = (ROWS * TILE_SIZE) * scale;
wrapperEl.style.height = `${scaledHeight}px`;
}
// 初回とリサイズ時に実行
window.addEventListener('resize', resizeBoard);
window.addEventListener('load', resizeBoard);
// --- シンナモのHTML生成 ---
function createShinnamoHTML() {
const div = document.createElement('div');
div.id = 'player';
div.innerHTML = `
<div class="shinnamo-hat">AI</div>
<div class="shinnamo-body">
<div class="shinnamo-face">
<div class="cheek left"></div>
<div class="eye"></div>
<div class="eye"></div>
<div class="cheek right"></div>
</div>
</div>
`;
return div;
}
// --- ゲーム初期化 ---
function initGame() {
boardEl.innerHTML = '';
overlayEl.style.display = 'none';
enemies = [];
bombs = [];
map = [];
gameActive = true;
for (let r = 0; r < ROWS; r++) {
let row = [];
for (let c = 0; c < COLS; c++) {
if (r === 0 || r === ROWS - 1 || c === 0 || c === COLS - 1 || (r % 2 === 0 && c % 2 === 0)) {
row.push(WALL);
} else if ((r < 3 && c < 3)) {
row.push(EMPTY);
} else {
row.push(Math.random() < 0.4 ? BLOCK : EMPTY);
}
}
map.push(row);
}
renderMap();
player.x = 1;
player.y = 1;
player.el = createShinnamoHTML();
updatePlayerPos();
boardEl.appendChild(player.el);
for(let i=0; i<3; i++) spawnEnemy();
if (!window.gameLoopId) {
gameLoop();
}
}
function renderMap() {
const existingTiles = document.querySelectorAll('.tile:not(.enemy):not(.bomb):not(#player)');
existingTiles.forEach(e => e.remove());
for (let r = 0; r < ROWS; r++) {
for (let c = 0; c < COLS; c++) {
if (map[r][c] === WALL) createTile(c, r, 'wall');
else if (map[r][c] === BLOCK) createTile(c, r, 'block');
}
}
}
function createTile(x, y, className) {
const div = document.createElement('div');
div.classList.add('tile', className);
div.style.left = x * TILE_SIZE + 'px';
div.style.top = y * TILE_SIZE + 'px';
div.dataset.x = x;
div.dataset.y = y;
boardEl.appendChild(div);
}
function spawnEnemy() {
let ex, ey;
do {
ex = Math.floor(Math.random() * COLS);
ey = Math.floor(Math.random() * ROWS);
} while (map[ey][ex] !== EMPTY || (Math.abs(ex - player.x) < 3 && Math.abs(ey - player.y) < 3));
const el = document.createElement('div');
el.classList.add('enemy', 'tile');
boardEl.appendChild(el);
enemies.push({
x: ex, y: ey, el: el,
direction: getRandomDirection(),
moveTimer: 0
});
}
function updatePlayerPos() {
const offset = (TILE_SIZE - 34) / 2;
player.el.style.left = (player.x * TILE_SIZE + offset) + 'px';
player.el.style.top = (player.y * TILE_SIZE + offset) + 'px';
}
// --- 入力処理(共通化) ---
function attemptMove(dx, dy) {
if (!gameActive) return;
const nx = player.x + dx;
const ny = player.y + dy;
const hasBomb = bombs.some(b => b.x === nx && b.y === ny);
if (map[ny][nx] === EMPTY && !hasBomb) {
player.x = nx;
player.y = ny;
updatePlayerPos();
player.el.classList.add('walking');
setTimeout(() => player.el.classList.remove('walking'), 300);
}
}
// キーボード操作
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowUp') attemptMove(0, -1);
else if (e.key === 'ArrowDown') attemptMove(0, 1);
else if (e.key === 'ArrowLeft') attemptMove(-1, 0);
else if (e.key === 'ArrowRight') attemptMove(1, 0);
else if (e.key === ' ' || e.code === 'Space') placeBomb();
});
// タッチ操作 (HTMLのonclick/ontouchstartから呼ばれる)
function handleTouch(action, event) {
if(event) event.preventDefault(); // ダブルタップズームなどを防止
if (!gameActive) return;
if (action === 'up') attemptMove(0, -1);
if (action === 'down') attemptMove(0, 1);
if (action === 'left') attemptMove(-1, 0);
if (action === 'right') attemptMove(1, 0);
if (action === 'bomb') placeBomb();
}
// --- 爆弾ロジック ---
function placeBomb() {
if (!gameActive) return;
if (bombs.some(b => b.x === player.x && b.y === player.y)) return;
const bomb = { x: player.x, y: player.y, timer: 180 };
const el = document.createElement('div');
el.classList.add('tile', 'bomb');
el.style.left = (player.x * TILE_SIZE + 5) + 'px';
el.style.top = (player.y * TILE_SIZE + 5) + 'px';
boardEl.appendChild(el);
bomb.el = el;
bombs.push(bomb);
}
function explodeBomb(bomb) {
bomb.el.remove();
bombs = bombs.filter(b => b !== bomb);
createExplosion(bomb.x, bomb.y);
const dirs = [{dx:0, dy:-1}, {dx:0, dy:1}, {dx:-1, dy:0}, {dx:1, dy:0}];
const power = 2;
dirs.forEach(dir => {
for (let i = 1; i <= power; i++) {
const tx = bomb.x + (dir.dx * i);
const ty = bomb.y + (dir.dy * i);
if (tx < 0 || tx >= COLS || ty < 0 || ty >= ROWS) break;
if (map[ty][tx] === WALL) break;
createExplosion(tx, ty);
if (map[ty][tx] === BLOCK) {
map[ty][tx] = EMPTY;
const blockEl = document.querySelector(`.block[data-x="${tx}"][data-y="${ty}"]`);
if (blockEl) blockEl.remove();
break;
}
const chainedBomb = bombs.find(b => b.x === tx && b.y === ty);
if (chainedBomb) chainedBomb.timer = 0;
}
});
}
function createExplosion(x, y) {
const el = document.createElement('div');
el.classList.add('tile', 'explosion');
el.style.left = x * TILE_SIZE + 'px';
el.style.top = y * TILE_SIZE + 'px';
boardEl.appendChild(el);
if (player.x === x && player.y === y) gameOver(false);
enemies.forEach((en, index) => {
if (en.x === x && en.y === y) {
en.el.remove();
enemies.splice(index, 1);
}
});
setTimeout(() => el.remove(), 500);
}
// --- 敵のAI ---
function updateEnemies() {
enemies.forEach(en => {
const offset = (TILE_SIZE - 30) / 2;
en.moveTimer++;
if (en.moveTimer > 30) {
en.moveTimer = 0;
tryMoveEnemy(en);
}
en.el.style.left = (en.x * TILE_SIZE + offset) + 'px';
en.el.style.top = (en.y * TILE_SIZE + offset) + 'px';
if (en.x === player.x && en.y === player.y) gameOver(false);
});
}
function tryMoveEnemy(en) {
let nx = en.x + en.direction.dx;
let ny = en.y + en.direction.dy;
const hasBomb = bombs.some(b => b.x === nx && b.y === ny);
if (nx < 0 || nx >= COLS || ny < 0 || ny >= ROWS || map[ny][nx] !== EMPTY || hasBomb) {
en.direction = getRandomDirection();
} else {
en.x = nx;
en.y = ny;
}
}
function getRandomDirection() {
const dirs = [{dx:0, dy:-1}, {dx:0, dy:1}, {dx:-1, dy:0}, {dx:1, dy:0}];
return dirs[Math.floor(Math.random() * dirs.length)];
}
// --- ゲームループ ---
function gameLoop() {
window.gameLoopId = requestAnimationFrame(gameLoop);
if (!gameActive) return;
bombs.forEach(b => {
b.timer--;
if (b.timer <= 0) explodeBomb(b);
});
updateEnemies();
if (enemies.length === 0) gameOver(true);
}
function gameOver(isClear) {
gameActive = false;
if (isClear) {
messageEl.textContent = "STAGE CLEAR! 🎉";
messageEl.style.color = "#baff58";
} else {
messageEl.textContent = "GAME OVER 💀";
messageEl.style.color = "#ff5555";
}
overlayEl.style.display = 'flex';
}
resizeBoard();
initGame();
</script>
</body>
</html>
今回のポイントは以下の部分です。
- マップは16×12のタイルで構成
- 壊せるブロック/壊せない壁
- 爆弾の設置・爆風処理
- 敵AI
- ゲームオーバーとクリア判定
- 主人公シンナモの見た目をCSSで再現
Gemini 3 はこの仕様にもきちんと対応し、必要なコードをすべて1つの HTML にまとめて返してくれました。
完成した「Shinnamo Bomber」がこちら
完成品がこちらhttps://ai-workstudio.site/wp-content/uploads/2025/11/game2.html

(画像はGoogle Gemini3より生成したものをキャプチャーしております)

凄いなも!僕が動いてるなも~!

ホントにできてるなも!?プロンプト渡しただけなもよ!?
実際に動かすと、これが驚くほどちゃんと動きます。
良かったところ
- シンナモの見た目の再現度が高い
- ブロックと壁の質感がしっかり分かれている
- 爆弾が正しく起動し、爆風も3方向に伸びる
- 敵のランダム移動も機能
- 当たり判定もしっかり動く
- ゲームオーバー・勝利表示も完備
正直、AIで作ったと言わなければ分からないのでは…というレベルです。

皆も遊ぶ時は自爆しないように気をつけてなも!

黒焦げになってるなも…
Gemini 3でゲーム生成を成功させるためのポイント
今回の検証を通して、「成功しやすいプロンプトの書き方」が明確になってきました。
ゲーム生成に強い書き方
- ジャンルはひとつに絞る(例:ボンバーマン風)
- 必須仕様だけ箇条書きで明確にする
- 「外部リソース禁止」と必ず書く
- HTML/CSS/JS を必ず 1 ファイルの形で出力させる
- 主人公の見た目は画像ではなく CSSで再現させる
- スマホ操作をつけたい場合は明確に指示する
特に キャラのビジュアル再現をCSSに任せる方法 は非常に安定します。
AI×ゲーム制作、ここまで来てるのか…と驚いた
今回の「Shinnamo Bomber」生成は、
AIのゲーム制作能力がすでに 一般ユーザーでも扱えるレベルまで来ている ことを証明してくれました。
- プロンプトだけでステージ生成
- 敵と爆弾の挙動
- 当たり判定
- キャラクター表現
- ブラウザ上で即プレイ可能
これらがすべて自動で整った状態で出てくるのは、はっきり言って革命級です。
まとめ:Gemini 3は“ゲーム生成”でも強かった
今回の検証でわかったのは、
Gemini 3はプロンプトだけで本当に遊べるゲームを作れるということ。
しかも、主人公をオリジナルキャラにすることも簡単。
HTML/CSS/JS の1ファイル構成なので、WordPress にそのままアップして遊べる点も魅力です。
AIによるゲーム生成は、これからもっと一般化する予感がします。
合わせて読みたい

ここまで記事を読んでくれてありがとうなも…焦げが取れてよかったなも…

ボクが取ってあげたんだから、感謝してよね!
また、下記記事ではNanobanana Proの画像生成能力を大調査!今回黒焦げになったシンナモが、今度はゼリー作りに挑戦!?
一体どんなものが出来たのか…是非記事をチェックしてなも~!



