乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

JavaScript

今回はバイブコーディングを
うまく行かせるためのコツについてです。

解説動画はこちら




バイブコーディングのコツ


昨今ではもう当たり前になってきている
バイブコーディング

これをうまく活かせるための
コツについてお伝えします。


ポイントは3つだけ

1.マークダウン形式で指示する

2.ロールを与える

3.できるだけ具体的に指示する

これだけ守れたら十分です

それ以外の説明や細かい所は
動画の方を見ていただければと思います。



ゲーム作成プロンプト

この内容に、追加で仕様を加えるなどで
改変することができると思います。
# 依頼:HTML Canvasを使用した「掘削アクションパズル」の作成

以下の仕様に基づき、シングルファイルのHTML(HTML/CSS/JS一体型)でゲームを作成してください。

## 1. ゲーム概要
- タイトル:簡易版ドリラー
- プレイヤーは下方向に向かってブロックを掘り進み、スコアと深さを競う。
- 「酸素(AIR)」の概念があり、時間経過で減少する。

## 2. コアメカニクス
- **移動と掘削**: 
    - 矢印キーで移動。
    - 隣接する(上下左右)ブロックを、移動キー(左、下、右)で破壊。
    - 1ブロック下に進むごとに深さを +1する
    - 破壊できたらその方向に進む
- **ブロックの挙動**:
    - ブロックの種類は4種類
    - 青色の土ブロック : 1アクションで破壊可能、破壊するのに酸素ゲージを1消費する
    - 茶色の土ブロック : 2アクションで破壊可能、破壊するのに酸素ゲージを2消費する
    - 灰色の岩ブロック : 3アクションで破壊可能、破壊するのに酸素ゲージを5消費する
    - 銀色のメタルブロック : 破壊不能、移動アクション毎に酸素ゲージを2消費する
- **リソース管理**:
    - 酸素ゲージは最大100。毎秒1ずつ減少。
    - 特定のブロック(エアーカプセル)を取得すると酸素が15回復。
    - 特定のブロックの破壊でも酸素ゲージを消費する
    - 酸素ブロックはおよそ、30メートルに1つの割合で出現する
- **ゲーム管理**:
    - 画面読み込みと同時にゲーム開始
    - 酸素ゲージ0でゲームオーバー
    - スペースキー押下で再ゲームスタート

## 3. 画面構成
- 画面の上部と下部の2部構成
- 画面上部はスコアなどの表示ゾーン
- Canvasサイズ400x100
- 画面上部に左から「DEPTH(深さ)スコア」「AIR(残り酸素)ゲージ」を表示。
- DEPTHスコアの表示は画面左上に固定し、数値4桁で0埋めする
- AIRゲージは画面上部の中央に長めに固定
- AIRゲージ全体は白枠組みで、残り酸素を黄色で表現し右から左に向かって減るようにする
- AIRゲージの右側に残り酸素を数値で表示(MAX100で3桁0埋めする)
- 画面下部はブロックゾーン
- Canvasサイズ: 400x600(縦長)
- ブロックサイズ: 40x40のグリッド
- 掘り進めるごとに、うまく調整してスクロールするようにする
- 深さ10m毎にブロックキャンバスの左外側にその深さを数値で表示させる

## 4. ビジュアル・操作性
- ブロックの色は4色(青、茶、灰、銀)、それぞれ、四角で表現し、枠は白くする
- エアーカプセルは桃色の簡易的な丸型図形とする
- キャラクターは黒色の簡易的な下向きの三角形でOK。
- 操作:
    - Left/Right:移動
    - Down:下のブロックを掘る

## 5. 実装のステップ
1. Canvasのセットアップとゲームループ(requestAnimationFrame)の作成。
2. ブロック配置データの生成(配列管理)。
3. プレイヤーの移動と掘削処理。
4. ブロックの消滅ロジックの実装。
5. 酸素減少とゲームオーバー判定の実装。

まずは、これらを網羅した動くコードを出力してください。


これをLLMに直接放り投げれば
HTMLでJSを用いたゲームを作ってもらえると思います。

是非コピペしてみてください

それでは。




 

今回もJSでクソゲーを作ってみました


解説動画はこちら







クソゲー作ってみた

その名も
「ずっこんテトリス」
です

普通のテトリスを改変して
少し面白くなるようにしてみました
こちらからプレイできます。

ずっこんテトリス

上下左右キーの操作のみの
シンプル設計で

長いテトリス棒を追加しました
sample


こやつは「ずっこんテトリス棒」ですね

コードはこんな感じになっています。
const game = document.getElementById("game");
const rareChanceInput = document.getElementById("rareChance");
const chanceValueDisplay = document.getElementById("chanceValue");
const ROWS = 20;
const COLS = 10;

// グリッドを初期化
const grid = Array.from({ length: ROWS }, () => Array(COLS).fill(0));

// 通常のテトリミノ
const tetrominoes = [
  [[1, 1, 1, 1]], // I
  [
    [1, 1],
    [1, 1],
  ], // O
  [
    [0, 1, 0],
    [1, 1, 1],
  ], // T
  [
    [1, 1, 0],
    [0, 1, 1],
  ], // S
  [
    [0, 1, 1],
    [1, 1, 0],
  ], // Z
  [
    [1, 1, 1],
    [1, 0, 0],
  ], // L
  [
    [1, 1, 1],
    [0, 0, 1],
  ], // J
];

// レアな「ロング棒」長さを8に変更
const rareTetromino = [
  [[1, 1, 1, 1, 1, 1, 1, 1]], // 長さ8の棒
];

// テトリミノの状態
let currentTetromino = getRandomTetromino();
let currentRow = 0;
let currentCol = Math.floor((COLS - currentTetromino[0].length) / 2);

// グリッドを描画
function drawGrid() {
  game.innerHTML = "";
  for (let row = 0; row < ROWS; row++) {
    for (let col = 0; col < COLS; col++) {
      const cell = document.createElement("div");
      cell.classList.add("cell");
      if (grid[row][col] === 1) {
        cell.classList.add("filled");
      }
      game.appendChild(cell);
    }
  }
}

// テトリミノを描画
function drawTetromino() {
  currentTetromino.forEach((row, r) => {
    row.forEach((value, c) => {
      if (value && currentRow + r >= 0) {
        grid[currentRow + r][currentCol + c] = 1;
      }
    });
  });
}

// テトリミノを削除
function clearTetromino() {
  currentTetromino.forEach((row, r) => {
    row.forEach((value, c) => {
      if (value && currentRow + r >= 0) {
        grid[currentRow + r][currentCol + c] = 0;
      }
    });
  });
}

// 衝突判定
function isValidMove(newRow, newCol, newTetromino) {
  return newTetromino.every((row, r) =>
    row.every((value, c) => {
      const x = newCol + c;
      const y = newRow + r;
      return (
        !value ||
        (y >= 0 && y < ROWS && x >= 0 && x < COLS && grid[y][x] === 0)
      );
    })
  );
}

// ラインを削除
function clearLines() {
  for (let row = ROWS - 1; row >= 0; row--) {
    if (grid[row].every((cell) => cell === 1)) {
      grid.splice(row, 1);
      grid.unshift(Array(COLS).fill(0));
      row++;
    }
  }
}

// ランダムなテトリミノを取得(レア形状の低確率出現を含む)
function getRandomTetromino() {
  const rareChance = parseFloat(rareChanceInput.value); // スライダーの値を取得
  if (Math.random() < rareChance) { // ロング棒の出現確率
    return rareTetromino[0];
  } else {
    return tetrominoes[Math.floor(Math.random() * tetrominoes.length)];
  }
}

// テトリミノを回転
function rotateTetromino() {
  const newTetromino = currentTetromino[0].map((_, colIndex) =>
    currentTetromino.map((row) => row[colIndex]).reverse()
  );

  if (isValidMove(currentRow, currentCol, newTetromino)) {
    currentTetromino = newTetromino;
  }
}

// ゲームのループ
function gameLoop() {
  clearTetromino();
  if (isValidMove(currentRow + 1, currentCol, currentTetromino)) {
    currentRow++;
  } else {
    drawTetromino();
    clearLines();

    // 次のテトリミノを生成
    currentTetromino = getRandomTetromino();
    currentRow = 0;
    currentCol = Math.floor((COLS - currentTetromino[0].length) / 2);

    // ゲームオーバー判定
    if (!isValidMove(currentRow, currentCol, currentTetromino)) {
      alert("Game Over");
      grid.forEach((row) => row.fill(0));
      currentTetromino = getRandomTetromino();
      currentRow = 0;
      currentCol = Math.floor((COLS - currentTetromino[0].length) / 2);
    }
  }
  drawTetromino();
  drawGrid();
}

// キー操作
document.addEventListener("keydown", (e) => {
  clearTetromino();
  if (e.key === "ArrowLeft" && isValidMove(currentRow, currentCol - 1, currentTetromino)) {
    currentCol--;
  } else if (e.key === "ArrowRight" && isValidMove(currentRow, currentCol + 1, currentTetromino)) {
    currentCol++;
  } else if (e.key === "ArrowDown") {
    if (isValidMove(currentRow + 1, currentCol, currentTetromino)) {
      currentRow++;
    }
  } else if (e.key === "ArrowUp") {
    rotateTetromino();
  }
  drawTetromino();
  drawGrid();
});

// スライダーの値を表示
rareChanceInput.addEventListener("input", () => {
  chanceValueDisplay.textContent = parseFloat(rareChanceInput.value).toFixed(2);
});

// ゲーム開始
setInterval(gameLoop, 500);
drawGrid();


ここでレアなテトリス棒として定義し
出現確率を画面上のスライダーの値で設定しています。

ここを上げると、出現確率も上がります。

どの確率が一番面白くなるかは分かりませんので
色々変えて試していただければと思います。

コードも改変すると
面白くなるかもしれないので
色々遊んでみてください

それでは






 

今回は簡単なゲームを
Javascriptで作ってみました

解説動画はこちら




今回は「ナンスピ」と呼ばれるゲームを再現してみました。

4972825233115-3-1400x1400のコピー


東急ハンズとかで売られている
トイグッズになりますが

1から25までの数字をぽちぽち押していって
タイムを競うものです

製品のHPはこちら

ナンスピ

試し書きには
20秒以下 : げべげべ
20秒以内 : 平均的
16秒以内 : 良い
12秒以内 : すごく良い
6.25秒 : パイロットの平均

とありました。

買うと高いので
Javascriptのコードにしてみました


コードはこちら
(Codepen)

ソースコード

HTML,CSS
Javascriptを一緒くたにしています。

ソースコードをコピーして
HTMLファイル保存してブラウザ実行するか
Codepenでそのまま楽しめます。

スクリーンショット 2025-01-18 16.15.58


単純に「ゲーム開始」ボタンで
ゲームスタート

1から25までの数字をクリックしてください

スクリーンショット 2025-01-18 16.16.09


25までクリックし終えるとタイムがポップアップします。
スクリーンショット 2025-01-18 16.15.34
過去の記録もされるので
過去の自分を超えられるように頑張ってください

ちなみに
自分は平均並み以下なので
デバックできていません


6.25秒以内にクリアできた方
ぜひコメントしてくださいね!!!

それ以外でも
自分のクリアタイムを
コメントしていただけると励みになります!!


今回はJavascriptを使った
簡単なゲームのご紹介でした

ぜひ遊んでみてください

それでは。





先日Hunter x Hunterの架空のボードゲームである
軍儀が発売されたのですが・・・
買えなかったので代わりに
軍儀っぽいナニカを作ってみました。


解説動画はこちら



さて軍儀なんですが
漫画を読んでない人にとっては
何じゃそれってものだと思いますので
軽めに説明しておくと

東ゴルトー発祥のボードゲームで
非常に将棋に似ています。

9x9のマスにコマを置き
「師(スイ)」を取ったら勝ちです。

相手のコマは取ることも出来て
自分のコマとして利用することも出来て
これらの駒を盤上に打つことは
新(あらた)と呼ばれている

また将棋とは違うルールとして
駒を3枚まで重ねる(ツケる)ことが可能
 
コマの動きは将棋とは違うようなので
公開されているコマの動きが分かるものを
JavaScriptで再現してみることとしました。

なお対戦は出来ず、コマの動きを
確かめるのみの実装です。

初期盤面はこんな感じにしました。


スクリーンショット 2022-03-26 17.21.12

9x9盤面に初期配置で適当に配置しています。

最初は簡単なコマから



スクリーンショット 2022-03-26 17.18.05

将棋だと歩のようなコマですが
前後に1マス進めるのが異なっています。

続いて槍

スクリーンショット 2022-03-26 17.17.33

槍は前に2マス、斜め前と後ろに1マス進めます。
将棋の槍と違って面白い動きです。

続いて忍
スクリーンショット 2022-03-26 17.18.34


忍びは斜めに2マスという
トリッキーな動きです。
将棋の桂馬とも違って、少し考えるコマですね。

続いて小

スクリーンショット 2022-03-26 17.16.58

これは将棋の金と同じ動きです。
使いやすそうですね。

続いて中

スクリーンショット 2022-03-26 17.19.45

中は将棋の角の成り(馬)と同じ動きです。
初めからバシバシ動けるのは強いですね。

続いて大
スクリーンショット 2022-03-26 17.19.58

大は将棋の飛車の成り(龍王)と同じ動きです。
最初から突っ込めるので最強のコマかもしれません。

最後に師
スクリーンショット 2022-03-26 17.19.20

これは将棋の王将と同じなので
馴染みがありますね。

このほかにもまだまだコマの種類があるようですが
公開されてないみたいなので実装出来てないです。

他のルールとして
ツケを行った場合は3コマまで重ねられ
1コマ重ねるごとに、移動出来るマスが
1マス増えるというルールです。

まだ実装出来ていませんが
今後軍儀のルールが確定した際には
実装を進めてみようかと思っています。

そうすればWEB上で対戦とかで遊べそうですね。

今回は
Hunter x Hunterの架空のボードゲームである
軍儀っぽいナニカをJSで作ってみました。

早く再販されますように
それでは。


先日セガさんが
ぷよぷよのプログラミング講座を
公開していましたので
早速ぷよぷよ作ってみました。

解説動画はこちら




さて
まず、講座はこちらです。
ぷよぷよプログラミング

monacaと言うツールでのプログラミング講座なので
アカウントの作成が必要です。

メアドを登録するだけなので簡単だと思います。
プランはFreeプランを選びましょう。

さて、まず講座にアクセスすると
初級
中級
上級

3コースあります。

初級は比較的書くコードが少なめ
中級は書くコードが増え
上級は1から全部作る
と言う難易度になっています。

基本的なソースコードは
公開されているので
それを写経する形で講座は進んでいきます。

monacaを開くとこんな感じの画面になります。
スクリーンショット 2020-06-27 16.06.29

左側にはファイル群
右側にはソースが表示されます。

「実行」から「プレビュータブを表示」
でテスト実行ができます。

スクリーンショット 2020-06-27 16.07.03

こんな感じのデバック画面が出て来て
操作もできます。

プロジェクトの基本構成は
土台となるindex.html
ゲームの操作を司るplayer.js
画面上の操作を司るstage.js
コンフィグ設定ファイルのconfig.js

あとはimg配下にぷよの画像があります。

講座の内容としては
player.jsを書き換えて
少しづつ操作方法を
増やしていく内容になっていますね。


初級では書き加える部分がかなり少なく
デバッグも簡単なので
早ければ1時間ほどで終わります。

でも中級になってくると
書く場所と量も増えて来て
デバッグも大変になります。

上級は1から全部なので、何日かかるか
分からないですねーーー。

monacaはアプリを作るサービスのようなので
実機にこのプロジェクトをビルドして
動かすこともできるっぽいですね。

ただ、スマホだとコントローラー無いので
相当厳しそうではあります。

monacaでは言語はJavascriptを用いているので
基本的にはブラウザーで開発するのと
あまり変わりはありません。

比較的デバッグも簡単ですね。

難点は
自分があまりぷよぷよ上手く無いので
デバッグが大変だと言うことくらいでしょうか。

ちゃんと連鎖で消える所まで行った時は
少し感動してしまいました。


昔ゲームプログラミングを勉強していた時は
セガの方が出している700Pほどの超分厚い本を見ながら
プログラミングの方法をを学んでいました。

パズルゲームは
プログラミングの教材としてはピカイチです。

特にテトリスとかぷよぷよは
最高の題材では無いでしょうか?

難易度としてはぷよぷよの方が
難しいかなと思いますが

こう言った教材が無料で公開されていること自体
セガさんに感謝したいところではあります。

ソースコードなどはゲーム業界を目指す人は
相当参考になるんじゃ無いでしょうか?

ゲーム業界を目指さない人も
Javascriptの制御部分は
かなり参考になると思います。

やって損は無い講座ですね。

おヒマな方は是非やってみてください。
それでは。





このページのトップヘ