
ゲーム開発、1分で終了!プログラミング未経験者でもChatGPTを使えばわずか3ステップでゲームを作れた方法がヤバすぎた
こんにちは、レジェンドです。
プログラムがまったくわからない人でも、1分でゲームを作れる?
そんな嘘みたいな話が、実際に起こりました。
Xでo3-mini-highを使ってゲームを作られてる方を拝見したので、「僕も作ってみたいな~」と簡単なゲームを作ってみようとチャレンジしてみました。
でも、プログラミング経験ゼロの僕にできるのか…?
こたえはYES
作ったゲームは↓↓↓
※ゲームが動くのは10秒当たりから
o3-mini-highでゲームを作った方が複数おられたので僕も動物落ち物パズルを作ってみた。制作時間は数分。作り方はChatGPTo3-mini-highに動物の落ち物パズルゲームを作りたいといことと、動物と、パズルゲームのルールの指示をしただけ。凄いですね!!! pic.twitter.com/46O8qhpW8J
— レジェンド/Shosuke@日本初note×音楽フェスを開催した人 (@llllegend0620) February 1, 2025
動物の落ち物パズルゲームで、動物の顔のアイコンが上から落ちてきて、縦か横に4つ並ぶと消えるというシンプルなゲームです。
このゲームを、プログラミングを1秒も勉強したことがない人間が作っちゃいました。凄くないですか????笑
しかも、
ゲーム開発はわずか3ステップ、しかも時間は1分(笑)
作り方は以下です。
ステップ1.ChatGPTを開いて「o3-mini-high」を選択する
まずは、ChatGPTを開いて「o3-mini-high」を選択します。

※4oでも作れます
ステップ2 作りたいゲームの内容を指示する
ブロック崩しとかシューティングゲームとか適当に伝えればいOKです。
僕の場合、
ブラウザで遊ぶための落ち物パズルゲームのコードを生成してください。
縦、横4つ並ぶと消えるルールです。
動物はパンダ、犬、トラ、ウサギでお願いします。
ポーズ機能を付けてください。
と、指示しました。
そうすると、以下のコードを生成してくれました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>動物の落ち物パズルゲーム(ルール変更・ポーズ機能付き)</title>
<style>
body {
background: #222;
color: #fff;
font-family: sans-serif;
text-align: center;
margin: 0;
padding: 0;
}
#gameCanvas {
background: #f0f0f0;
display: block;
margin: 20px auto;
border: 2px solid #333;
}
#gameOver {
font-size: 2em;
color: #ff4444;
}
</style>
</head>
<body>
<h1>動物の落ち物パズルゲーム</h1>
<canvas id="gameCanvas" width="300" height="600"></canvas>
<div id="gameOver"></div>
<script>
// --- 定数とグローバル変数 ---
const COLS = 6; // 横マス数
const ROWS = 12; // 縦マス数
const CELL_SIZE = 50; // セルのピクセルサイズ
const DROP_INTERVAL = 500; // 落下間隔(ミリ秒)
// 使用する動物(Unicodeエスケープ)
const animalTypes = [
"\uD83D\uDC36", // 🐶
"\uD83D\uDC31", // 🐱
"\uD83D\uDC3C", // 🐼
"\uD83D\uDC30" // 🐰
];
// ゲーム盤(ROWS x COLS の2次元配列、空セルは null)
let grid = [];
for (let y = 0; y < ROWS; y++) {
grid[y] = [];
for (let x = 0; x < COLS; x++) {
grid[y][x] = null;
}
}
// 現在操作中の落下ブロック(2体のブロック:メインブロックと付随ブロック)
let fallingPiece = null;
// ゲームオーバーフラグ
let gameOver = false;
// ポーズ状態フラグ
let paused = false;
// Canvas の準備
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
ctx.font = "40px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
// --- 落下ブロックの生成 ---
function spawnPiece() {
// 落下開始位置(中央上部)
let startX = Math.floor(COLS / 2);
let startY = 0;
// 落下する2体の動物をランダムに選択
fallingPiece = {
x: startX, // メインブロックの x 座標
y: startY, // メインブロックの y 座標
block1: Math.floor(Math.random() * animalTypes.length), // メインブロックの種類
block2: Math.floor(Math.random() * animalTypes.length), // 付随ブロックの種類
// 付随ブロックの位置は、初期状態ではメインブロックの下(相対位置)
offsetX: 0,
offsetY: 1
};
// 新規ブロックを配置する位置が既に埋まっている場合はゲームオーバー
if (!isValidPosition(fallingPiece, fallingPiece.x, fallingPiece.y, fallingPiece.offsetX, fallingPiece.offsetY)) {
gameOver = true;
document.getElementById('gameOver').textContent = "GAME OVER";
}
}
// --- 衝突判定 ---
// 指定の座標と相対位置にブロックが配置できるかチェック
function isValidPosition(piece, x, y, offX, offY) {
// メインブロックのチェック
if (!isCellEmpty(x, y)) return false;
// 付随ブロックのチェック
let x2 = x + offX, y2 = y + offY;
if (!isCellEmpty(x2, y2)) return false;
return true;
}
// 指定セルが盤内で空かどうかをチェック(盤外の場合は false)
function isCellEmpty(x, y) {
if (x < 0 || x >= COLS || y < 0 || y >= ROWS) return false;
if (grid[y][x] !== null) return false;
return true;
}
// --- 操作処理 ---
// キーハンドリング(左右移動・回転・加速落下・ポーズ)
document.addEventListener('keydown', function(e) {
// ポーズ切替(Pキー)
if (e.key === 'p' || e.key === 'P') {
paused = !paused;
if (paused) {
document.getElementById('gameOver').textContent = "PAUSED";
draw(); // ポーズ中のオーバーレイを描画
} else {
document.getElementById('gameOver').textContent = "";
}
return;
}
// ゲームオーバーまたはポーズ中なら操作無効
if (gameOver || paused) return;
if (!fallingPiece) return;
// 現在の位置と回転情報
let newX = fallingPiece.x;
let newY = fallingPiece.y;
let newOffX = fallingPiece.offsetX;
let newOffY = fallingPiece.offsetY;
switch(e.key) {
case "ArrowLeft":
newX = fallingPiece.x - 1;
break;
case "ArrowRight":
newX = fallingPiece.x + 1;
break;
case "ArrowDown":
// 下キーで一段早く落とす
newY = fallingPiece.y + 1;
break;
case "ArrowUp":
// 回転(時計回り): (offX, offY) → (offY, -offX)
newOffX = fallingPiece.offsetY;
newOffY = -fallingPiece.offsetX;
break;
case " ":
// スペースキーで即落下
while (canMove(fallingPiece, 0, 1, fallingPiece.offsetX, fallingPiece.offsetY)) {
fallingPiece.y++;
}
lockPiece();
spawnPiece();
draw();
return;
default:
return; // その他のキーは無視
}
// 衝突チェック
if (isValidPosition(fallingPiece, newX, newY, newOffX, newOffY)) {
fallingPiece.x = newX;
fallingPiece.y = newY;
fallingPiece.offsetX = newOffX;
fallingPiece.offsetY = newOffY;
draw();
}
e.preventDefault(); // ページスクロール防止
});
// 落下移動可能かをチェック
function canMove(piece, dx, dy, offX, offY) {
let newX = piece.x + dx;
let newY = piece.y + dy;
return isValidPosition(piece, newX, newY, offX, offY);
}
// --- ゲーム更新 ---
// 定期的に呼び出し、ブロックを下に落とす
function update() {
if (gameOver) return;
if (paused) return;
if (fallingPiece && canMove(fallingPiece, 0, 1, fallingPiece.offsetX, fallingPiece.offsetY)) {
fallingPiece.y++;
} else {
// これ以上下に落とせなければ盤に固定
lockPiece();
// 縦または横に4つ以上並んだ動物を除去
clearMatches();
// 重力処理で上のブロックが落ちる
applyGravity();
// 新たなブロックを生成
spawnPiece();
}
draw();
}
// 落下ブロックを盤に固定
function lockPiece() {
if (!fallingPiece) return;
let x1 = fallingPiece.x;
let y1 = fallingPiece.y;
let x2 = fallingPiece.x + fallingPiece.offsetX;
let y2 = fallingPiece.y + fallingPiece.offsetY;
if (y1 >= 0 && y1 < ROWS && x1 >= 0 && x1 < COLS)
grid[y1][x1] = fallingPiece.block1;
if (y2 >= 0 && y2 < ROWS && x2 >= 0 && x2 < COLS)
grid[y2][x2] = fallingPiece.block2;
fallingPiece = null;
}
// --- マッチ(縦または横に4つ以上並んだ動物の除去) ---
function clearMatches() {
let toClear = [];
// 横方向のチェック
for (let y = 0; y < ROWS; y++) {
let x = 0;
while (x < COLS) {
if (grid[y][x] !== null) {
let type = grid[y][x];
let start = x;
while (x < COLS && grid[y][x] === type) {
x++;
}
let count = x - start;
if (count >= 4) {
for (let i = start; i < x; i++) {
toClear.push({ x: i, y: y });
}
}
} else {
x++;
}
}
}
// 縦方向のチェック
for (let x = 0; x < COLS; x++) {
let y = 0;
while (y < ROWS) {
if (grid[y][x] !== null) {
let type = grid[y][x];
let start = y;
while (y < ROWS && grid[y][x] === type) {
y++;
}
let count = y - start;
if (count >= 4) {
for (let i = start; i < y; i++) {
toClear.push({ x: x, y: i });
}
}
} else {
y++;
}
}
}
// 対象セルを消去
toClear.forEach(cell => {
grid[cell.y][cell.x] = null;
});
}
// --- 重力処理 ---
// 空いたセルに対して上のブロックを下へ落とす
function applyGravity() {
for (let x = 0; x < COLS; x++) {
for (let y = ROWS - 1; y >= 0; y--) {
if (grid[y][x] === null) {
for (let k = y - 1; k >= 0; k--) {
if (grid[k][x] !== null) {
grid[y][x] = grid[k][x];
grid[k][x] = null;
break;
}
}
}
}
}
}
// --- 描画 ---
function draw() {
// キャンバス全体をクリア
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#f0f0f0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 盤面のグリッド線を描画
ctx.strokeStyle = "#ccc";
for (let x = 0; x <= COLS; x++) {
ctx.beginPath();
ctx.moveTo(x * CELL_SIZE, 0);
ctx.lineTo(x * CELL_SIZE, ROWS * CELL_SIZE);
ctx.stroke();
}
for (let y = 0; y <= ROWS; y++) {
ctx.beginPath();
ctx.moveTo(0, y * CELL_SIZE);
ctx.lineTo(COLS * CELL_SIZE, y * CELL_SIZE);
ctx.stroke();
}
// 盤に固定されたブロックを描画
for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
if (grid[y][x] !== null) {
drawBlock(x, y, animalTypes[grid[y][x]]);
}
}
}
// 落下中のブロックを描画
if (fallingPiece) {
drawBlock(fallingPiece.x, fallingPiece.y, animalTypes[fallingPiece.block1]);
drawBlock(fallingPiece.x + fallingPiece.offsetX, fallingPiece.y + fallingPiece.offsetY, animalTypes[fallingPiece.block2]);
}
// ポーズ中の場合、半透明のオーバーレイと「PAUSED」を描画
if (paused) {
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#fff";
ctx.font = "50px sans-serif";
ctx.fillText("PAUSED", canvas.width / 2, canvas.height / 2);
}
}
// 各ブロックを描画する関数(セルの中心に文字を表示)
function drawBlock(x, y, text) {
if (x < 0 || x >= COLS || y < 0 || y >= ROWS) return;
let centerX = x * CELL_SIZE + CELL_SIZE / 2;
let centerY = y * CELL_SIZE + CELL_SIZE / 2;
ctx.fillText(text, centerX, centerY);
}
// --- メインループ ---
spawnPiece();
draw();
let gameInterval = setInterval(update, DROP_INTERVAL);
</script>
</body>
</html>
このコードがなんと1分でできちゃうんです(笑)
ステップ3.テキストをHTMLとして保存&実行
このコードをコピペして、テキストエディタに貼り付けます。
テキストエディタは、
・秀丸
・Notepad++
・Visual Studio Code
・Atom
・Sublime Text
などあるので、お好みのテキストエディタを使ってください。
僕は、秀丸を使いました。

貼り付けたら、ファイル形式を「HTML」を指定して保存。
そして、保存したhtmlファイルをクリックするとブラウザゲームが動きます!!!

このようにたった3ステップでプログラムを1秒も勉強したことがない人間でも動物落ち物パズルゲームを1分で作れてしまいました♪
もし良かったら、みなさんもオリジナルゲーム制作にチャレンジされてみてください♪
「作ったゲームのスクリーンショット」をシェアしてもらえたら嬉しいです✨
追記
節分にちなんで、鬼を豆で倒すシューティングゲームを制作してみました。
今回はオリジナル鬼イラストを作ってみました。

このイラストが実装されたシューティングゲームが↓↓↓
(ゲームが動くのは10秒あたりから)
o3-mini-highで鬼の豆でやっつける節分シューティングゲームが完成。鬼のイラストをオリジナルで作ってシューティングゲームに実装。色々バグが見つかって修正するのに時間が掛かったけどゲーム作り楽しい♪
— レジェンド/Shosuke@日本初note×音楽フェスを開催した人 (@llllegend0620) February 2, 2025
(ゲームが動くのは10秒あたりから) https://t.co/eocOpit5fg pic.twitter.com/RU10PMeCCJ
自分で作ったイラストもゲームに反映できるなら、色々と幅が広がりますね♪