ChatGPTを活用したゲーム制作の方法|具体的な事例を解説

ChatGPTは、その優れた対話能力と多岐にわたる応用範囲から、ゲーム制作の分野でも注目を集めています。
本記事では、プログラミング未経験者でも簡単に始められるChatGPTを使ったゲーム制作の成功事例と具体的な手法を詳しく解説します。
コンテンツ [表示]
シューティングゲームを制作するにあたって必要なツールや環境について、具体例と目的をあげて答えてくれました。
さらに、開発する際のポイントも答えてくれています。
ChatGPTがJavaScriptを用いて、シューティングゲームを制作するには、テキストエディタとウェブブラウザが必要だと教えてくれました。
筆者は、ウェブブラウザはGoogle Chromeを使用しているので、新たに環境を整える必要なさそうです。
もしGoogle Chromeを導入していない場合、下記のリンクからインストールすることができます。
筆者は、コードの編集と保存を行うために必要なテキストエディタを導入していないので、Visual Studio Codeの導入方法について尋ねてみます。
作業環境を導入する方法について、公式リンクへのアクセス方法を添えて回答してくれました。
Visual Studio Codeのダウンロードは、以下のリンクから可能です。
ChatGPTの手順通り、Visual Studio Codeの導入を進めます。
以下の画像のように表示されれば、Visual Studio Codeの導入が完了です。
次に、Visual Studio Codeで「Live Server」という拡張機能をインストールします。
拡張機能のインストール方法は、Visual Studio Codeの左サイドバーにある「拡張機能」アイコン(四つの四角形のアイコン)をクリックします。
拡張機能ビューの検索バーに「Live Server」と入力します。
検索結果に「Live Server - Ritwick Dey」が表示されるので、それを選択します。
「インストール」ボタンをクリックして、拡張機能をインストールします。
ChatGPTの指示に従って実際にゲームを制作する
作業環境の導入が終わったら、ChatGPTにシューティングゲームの作り方を教えてもらいます。
ChatGPTの指示に従って、プロジェクトフォルダを作成します。
筆者は、デスクトップに配置しました。
プロジェクトフォルダの名前は、「my-html-project」とします。
プロジェクトフォルダ内に「index.html」、「style.css」、「script.js」ファイルをそれぞれ作成します。
作成方法は、まずVisual Studio Codeを起動し、サイドバーのエクスプローラーから、作成したプロジェクトフォルダを開きます。
次に、新しい無題のテキストファイルをクリックして、3つのテキストファイルを作成します。
3つのテキストファイルの名前を「index.html」、「style.css」、「script.js」とそれぞれリネームします。
このままでは、敵が緑の四角で描画されている状態なので、ChatGPTの画像生成機能を使って、インベーダーのグラフィックを作成します。
この画像を、「enemy.png」という名前で、作成したプロジェクトファイル、「my-html-project」のフォルダに保存します。
以下の画像のような階層になっていれば、作業環境の準備が完了です。
最後に、ChatGPTが出力したコードを、それぞれのファイルに記述します。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shooting Game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<button id="restartButton" style="display:none;">Restart</button>
<script src="script.js"></script>
</body>
</html>
style.css
body {
margin: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #000;
}
canvas {
border: 1px solid #fff;
}
#restartButton {
margin-top: 20px;
padding: 10px 20px;
font-size: 20px;
cursor: pointer;
}
script.js
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const restartButton = document.getElementById('restartButton');
const player = {
x: canvas.width / 2 - 25,
y: canvas.height - 60,
width: 50,
height: 50,
speed: 5,
dx: 0,
lives: 3
};
let bullets = [];
let enemies = [];
let enemyBullets = [];
let score = 0;
let gameOver = false;
let paused = false;
let enemyInterval;
const enemyImage = new Image();
enemyImage.src = 'enemy.png';
function drawPlayer() {
ctx.fillStyle = 'blue';
ctx.fillRect(player.x, player.y, player.width, player.height);
}
function drawBullets() {
bullets.forEach(bullet => {
ctx.fillStyle = 'red';
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
});
}
function drawEnemies() {
enemies.forEach(enemy => {
if (enemyImage.complete) {
ctx.drawImage(enemyImage, enemy.x, enemy.y, enemy.width, enemy.height);
} else {
ctx.fillStyle = 'green';
ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
}
});
}
function drawEnemyBullets() {
enemyBullets.forEach(bullet => {
ctx.fillStyle = 'yellow';
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
});
}
function drawScoreAndLives() {
ctx.fillStyle = 'white';
ctx.font = '20px sans-serif';
ctx.fillText('Score: ' + score, 10, 20);
ctx.fillText('Lives: ' + player.lives, canvas.width - 100, 20);
}
function movePlayer() {
player.x += player.dx;
if (player.x < 0) {
player.x = 0;
}
if (player.x + player.width > canvas.width) {
player.x = canvas.width - player.width;
}
}
function moveBullets() {
bullets.forEach((bullet, index) => {
bullet.y -= bullet.speed;
if (bullet.y < 0) {
bullets.splice(index, 1);
}
});
}
function moveEnemies() {
enemies.forEach((enemy, index) => {
enemy.y += enemy.speed;
if (enemy.y > canvas.height) {
enemies.splice(index, 1);
}
if (Math.random() < 0.01) {
createEnemyBullet(enemy.x + enemy.width / 2, enemy.y + enemy.height);
}
});
}
function moveEnemyBullets() {
enemyBullets.forEach((bullet, index) => {
bullet.y += bullet.speed;
if (bullet.y > canvas.height) {
enemyBullets.splice(index, 1);
}
});
}
function detectCollisions() {
bullets.forEach((bullet, bulletIndex) => {
enemies.forEach((enemy, enemyIndex) => {
if (
bullet.x < enemy.x + enemy.width &&
bullet.x + bullet.width > enemy.x &&
bullet.y < enemy.y + enemy.height &&
bullet.y + bullet.height > enemy.y
) {
bullets.splice(bulletIndex, 1);
enemies.splice(enemyIndex, 1);
score += 10;
}
});
});
enemyBullets.forEach((bullet, bulletIndex) => {
if (
bullet.x < player.x + player.width &&
bullet.x + bullet.width > player.x &&
bullet.y < player.y + player.height &&
bullet.y + bullet.height > player.y
) {
enemyBullets.splice(bulletIndex, 1);
player.lives -= 1;
if (player.lives <= 0) {
gameOver = true;
clearInterval(enemyInterval);
restartButton.style.display = 'block';
}
}
});
enemies.forEach((enemy, enemyIndex) => {
if (
enemy.x < player.x + player.width &&
enemy.x + enemy.width > player.x &&
enemy.y < player.y + player.height &&
enemy.y + enemy.height > player.y
) {
enemies.splice(enemyIndex, 1);
player.lives -= 1;
if (player.lives <= 0) {
gameOver = true;
clearInterval(enemyInterval);
restartButton.style.display = 'block';
}
}
});
}
function update() {
if (!paused && !gameOver) {
movePlayer();
moveBullets();
moveEnemies();
moveEnemyBullets();
detectCollisions();
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
drawBullets();
drawEnemies();
drawEnemyBullets();
drawScoreAndLives();
if (paused) {
ctx.fillStyle = 'white';
ctx.font = '48px sans-serif';
ctx.fillText('Paused', canvas.width / 2 - 100, canvas.height / 2);
}
if (gameOver) {
ctx.fillStyle = 'white';
ctx.font = '48px sans-serif';
ctx.fillText('Game Over', canvas.width / 2 - 150, canvas.height / 2);
}
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
function keyDown(e) {
if (e.key === 'ArrowRight' || e.key === 'Right') {
player.dx = player.speed;
} else if (e.key === 'ArrowLeft' || e.key === 'Left') {
player.dx = -player.speed;
} else if (e.key === ' ') {
createBullet();
} else if (e.key === 'p' || e.key === 'P') {
togglePause();
}
}
function keyUp(e) {
if (
e.key === 'ArrowRight' ||
e.key === 'Right' ||
e.key === 'ArrowLeft' ||
e.key === 'Left'
) {
player.dx = 0;
}
}
function togglePause() {
paused = !paused;
if (paused) {
clearInterval(enemyInterval);
} else {
startEnemyInterval();
}
}
function createBullet() {
bullets.push({
x: player.x + player.width / 2 - 2.5,
y: player.y,
width: 5,
height: 10,
speed: 7
});
}
function createEnemy() {
const x = Math.random() * (canvas.width - 20);
enemies.push({
x: x,
y: 0,
width: 50,
height: 50,
speed: 3
});
}
function createEnemyBullet(x, y) {
enemyBullets.push({
x: x - 2.5,
y: y,
width: 5,
height: 10,
speed: 5
});
}
function startEnemyInterval() {
enemyInterval = setInterval(createEnemy, 1000);
}
function restartGame() {
gameOver = false;
paused = false;
player.x = canvas.width / 2 - 25;
player.y = canvas.height - 60;
player.lives = 3;
score = 0;
bullets = [];
enemies = [];
enemyBullets = [];
restartButton.style.display = 'none';
startEnemyInterval();
}
document.addEventListener('keydown', keyDown);
document.addEventListener('keyup', keyUp);
restartButton.addEventListener('click', restartGame);
startEnemyInterval();
loop();
記述し終えたら、Visual Studio Codeで「index.html」ファイルを右クリックし、「Open with Live Server」を選択します。
または、Visual Studio Codeの右下にある「Go Live」ボタンをクリックします。
ウェブブラウザが自動的に開き、ゲームが表示されます。
以下の画面が表示されたら、ゲームの完成です。
まとめ|ChatGPTを活用したゲーム制作
本記事では、ChatGPTを活用してシューティングゲームを制作する手順を解説しました。
ChatGPTの力を借りることで、基本的な開発環境のセットアップから、実際のコーディング、そしてゲームの起動まで、プログラミングの知識がなくてもゲームが制作できました。
ChatGPTを活用すれば、ゲーム制作において、コーディングのヒントはもちろん、レベルデザインの設計、ストーリー展開のアイデアまで、幅広いサポートを得られます。
ただし、ChatGPTの回答は必ずしも正しいとは限らないため、最終的な判断と決定は自分で行うことを念頭に、ChatGPTをあくまでもゲーム制作の補助ツールとして位置づけることが大切です。
ぜひChatGPTを活用して、ゲーム制作に参考にできる部分があれば取り入れてみてください。
- 1
- 2