# 2D マインクラフト風ゲーム ? 設計仕様書
## 概要
HTML5 Canvas (単一 `.html` ファイル) で動く 2D サンドボックスゲーム。
Minecraft の採掘・クラフト・昼夜サイクルをトップビュー 2D で再現する。
外部ライブラリ・サーバー不要。ブラウザで直接開いて即プレイ可能。
---
## 画面・Canvas 仕様
| 項目 | 値 |
|---|---|
| Canvas 論理サイズ | 900 × 560 px |
| CSS 表示サイズ | 1125 × 700 px(×1.25 拡大) |
| ゲームビュー | 900 × 460 px(上部) |
| パネルエリア | 900 × 100 px(下部 HUD) |
| タイルサイズ | 32 px |
| マップサイズ | 160 × 100 タイル(= 5120 × 3200 px) |
| カメラ | プレイヤー追従(クランプあり) |
---
## タイルシステム
### 2 レイヤー構造
| レイヤー | 配列 | 用途 | タイル種別 |
|---|---|---|---|
| map1 | `Uint8Array` | 地形(常に通過可能) | AIR / WATER / SAND / GRASS / DIRT |
| map2 | `Uint8Array` | オブジェクト・壁 | 上記以外の全タイル |
### タイル ID 一覧
| ID | 名前 | 定数 | 特性 |
|---|---|---|---|
| 0 | 空気 | AIR | 透過 |
| 1 | 水 | WATER | 水泳判定・速度低下 |
| 2 | 砂 | SAND | mt=0.6 |
| 3 | 草 | GRASS | mt=0.8, drop:dirt |
| 4 | 土 | DIRT | mt=0.9, drop:dirt |
| 5 | 石 | STONE | mt=3.0, rt=1(木ツルハシ必要) |
| 6 | 石炭鉱石 | COAL | mt=4.0, rt=1 |
| 7 | 鉄鉱石 | IRON | mt=5.0, rt=2(石ツルハシ必要) |
| 8 | 金鉱石 | GOLD | mt=7.0, rt=3(鉄ツルハシ必要), 深部のみ |
| 9 | 木 | WOOD | mt=4.0, 独自描画(樹冠付き) |
| 10 | 葉 | LEAVES | mt=0.4, 8%でリンゴドロップ, 移動低下 |
| 11 | 板材 | PLANKS | mt=2.0, 年輪描画 |
| 12 | 砂利石 | COBBLE | mt=2.5 |
| 13 | 作業台 | TABLE | mt=2.0 |
| 14 | たいまつ | TORCH | mt=0.05(即採取), 光源(r=88) |
| 15 | ドア(閉) | DOOR_C | プレイヤーのみ通過可(pp=true) |
| 16 | ドア(開) | DOOR_O | 通過可 |
| 17 | ベッド | BED | mt=0.1, 夜に睡眠 |
| 18 | 宝箱 | CHEST | mt=0.8, ルートポップアップ |
| 19 | 焚き火 | CAMPFIRE | mt=0.2, 光源(r=120), 生肉を焼ける |
| 20 | 丸太 | LOG | mt=4.0, 横向き丸太描画 |
| 21 | かまど | FURNACE | mt=2.5, 精錬UI開放 |
### タイルプロパティ
```js
TDEF[id] = {
n: string, // 日本語名
sol: boolean, // 固体(衝突あり)
pp: boolean, // プレイヤーのみ通過可(ドア)
swim: boolean, // 水泳判定
slow: boolean, // 速度低下(葉)
light: boolean, // 光源
mt: number, // 採掘時間(秒)
rt: number, // 必要ツルハシレベル (0?3)
drop: string, // ドロップアイテムID
dn: number, // ドロップ数
dc: number, // ドロップ確率(省略時=1.0)
col: string, // 代表色(パーティクル・描画用)
}
```
---
## ワールド生成
生成は `generateWorld()` で一度だけ実行。乱数は LCG (線形合同法) を使用(再現性あり)。
### 生成ステップ
1. **ベース地形** ? ノイズ関数(4 オクターブ sin/cos 合成)で WATER / SAND / GRASS / DIRT+STONE を決定
2. **海岸線** ? 外周 14 タイルを強制 WATER、その内側 4 タイルを SAND
3. **川 × 4 本** ? ランダムウォークで WATER を伸ばす(長さ 450 タイル)
4. **池 × 10 個** ? 楕円形の WATER エリア(rx=2?5, ry=2?4)
5. **川岸砂化** ? WATER 隣接の GRASS/DIRT を SAND に変換
6. **鉱石配置** ? STONE タイルをランダムにCOAL(4%) / IRON(3%) へ置換。GOLD は深部のみ(0.5%)
7. **木・森生成**
- `genTrees()`: マップ全体にまばらな木(3%確率・6タイル間隔)
- `genForest()` × 3 回: 半径7タイルの円形密林(2タイル間隔・約40%確率、約18本/クラスター)
8. **構造物**
- 廃坑 (`genAbandonedMine`) × 1
- 廃村 (`genRuinedVillage`) × 2
9. **ミニマップ初期化・プレイヤースポーン・羊スポーン**
### 木の配置ルール (`placeTree`)
- map1 が GRASS であること
- map2 が AIR または LEAVES であること(密林内で隣接木の葉をWOODで上書き可)
- 成功時: map2 = WOOD、周囲 3×3 と上段の AIR タイルに LEAVES を展開
### 廃坑 (`genAbandonedMine`)
- STONE/COAL が密集したエリア(スコア ? 28)を探索
- 11×7 の部屋を掘削(床=DIRT, 壁=COBBLE)
- 中央に宝箱(洞窟チェストとして `caveChests` Setに登録)
- 左右にたいまつ × 2
- ランダムにPLANKS / COBBLE がれき配置
### 廃村 (`genRuinedVillage`)
- GRASS が広がるエリアに 2?3 棟の崩れた家を生成
- 壁は PLANKS or COBBLE(70% が欠損)
- 家の中にランダムで作業台・宝箱
---
## プレイヤー
### 基本パラメータ
| パラメータ | 値 |
|---|---|
| 移動速度 | 110 px/s |
| 水中速度 | ×0.35 |
| 葉上速度 | ×0.72 |
| HP | 20 / 20 |
| 空腹度 | 20 / 20 |
| 空気(水中) | 10 / 10 |
| ヒットボックス | 20×28 px(左上オフセット: 6, 4) |
### 操作
| 操作 | 機能 |
|---|---|
| WASD / 矢印キー | 移動 |
| マウス左ホールド(ビュー内) | 採掘 / 攻撃 / 羊への操作 |
| マウス右クリック(ビュー内) | ブロック設置 |
| F キー | インタラクト(ドア・ベッド・焚き火・宝箱・かまど・食事) |
| E キー | インベントリ開閉 |
| R キー | クラフトUI開閉 |
| 1?0 キー / スクロール | ホットバー選択 |
| Ctrl+S | 手動セーブ |
### スプライトアニメーション
- 96×128 png(3列×4行): 列=歩行フレーム(0=左足, 1=待機, 2=右足), 行=向き(0=下, 1=左, 2=右, 3=上)
- 歩行時: 0.14 s ごとにフレーム切り替え
### HP 変動ルール
| 条件 | 効果 |
|---|---|
| ゾンビに触れる(距離 < 32 px) | -6 HP(1.5 秒クールダウン) |
| 水中で air = 0 | -3 HP/s |
| 空腹度 = 0 | -1 HP / 5 秒 |
| 夜・屋内 | +1 HP / 5 秒 |
| 空腹度 ? 16 かつ HP 不満 | +1 HP / 4 秒 |
| 就寝 | +5 HP(一回) |
| HP = 0 | 3 秒後にスポーン地点でリスポーン |
---
## インベントリ・アイテム
- インベントリスロット: 36(9列×4行)
- ホットバー: 前面の 10 スロット
### アイテム定義 (`IDEF`)
| ID | 名前 | スタック | 特性 |
|---|---|---|---|
| sand | 砂 | 64 | 設置可 (SAND) |
| dirt | 土 | 64 | 設置可 (DIRT) |
| cobble | 砂利石 | 64 | 設置可 (COBBLE) |
| wood | 木材 | 64 | 設置可 (LOG) |
| plank | 板材 | 64 | 設置可 (PLANKS) |
| coal | 石炭 | 64 | ? |
| iron | 鉄鉱石 | 64 | かまどで鉄インゴットへ |
| gold | 金鉱石 | 64 | かまどで金インゴットへ |
| stick | 棒 | 64 | ? |
| torch | たいまつ | 64 | 設置可 (TORCH) |
| door | ドア | 16 | 設置可 (DOOR_C) |
| bed | ベッド | 4 | 設置可 (BED) |
| table | 作業台 | 4 | 設置可 (TABLE) |
| wool | 羊毛 | 64 | ? |
| wood_pick | 木のツルハシ | 1 | tl=1 |
| stone_pick | 石のツルハシ | 1 | tl=2 |
| iron_pick | 鉄のツルハシ | 1 | tl=3 |
| wood_sword | 木の剣 | 1 | dmg=5, acd=0.5 |
| stone_sword | 石の剣 | 1 | dmg=9, acd=0.45 |
| iron_sword | 鉄の剣 | 1 | dmg=15, acd=0.38 |
| wood_axe | 木のオノ | 1 | al=1 |
| stone_axe | 石のオノ | 1 | al=2 |
| iron_axe | 鉄のオノ | 1 | al=3 |
| apple | リンゴ | 16 | food=4 |
| raw_meat | 生肉 | 16 | food=2 |
| cooked_meat | 焼き肉 | 16 | food=8 |
| campfire | 焚き火 | 4 | 設置可 (CAMPFIRE) |
| furnace | かまど | 4 | 設置可 (FURNACE) |
| iron_ingot | 鉄インゴット | 64 | ? |
| gold_ingot | 金インゴット | 64 | ? |
---
## 採掘システム
### 採掘速度計算
```
speedMult = isWood && al>0 ? [2, 3.5, 6][al-1]
: [1, 1.5, 3, 5][toolLevel]
mineProg += dt * speedMult / def.mt
```
- `mineProg ? 1` で採掘完了 → ドロップ生成
- ツルハシレベル不足時は採掘不可(警告トースト表示)
- 採掘中は 0.45 s ごとに採掘音(石系は低音、木・土系は高音)
- 採掘中タイルに進捗バー(黄色)とハイライト枠を表示
### ツルハシレベル効果
| ツルハシ | tl | 速度倍率 | 採掘可能 |
|---|---|---|---|
| 素手 | 0 | ×1 | rt=0 のみ |
| 木のツルハシ | 1 | ×1.5 | rt?1 |
| 石のツルハシ | 2 | ×3 | rt?2 |
| 鉄のツルハシ | 3 | ×5 | rt?3 |
### オノレベル効果(木・丸太のみ)
| オノ | al | 速度倍率 |
|---|---|---|
| 木のオノ | 1 | ×2 |
| 石のオノ | 2 | ×3.5 |
| 鉄のオノ | 3 | ×6 |
> 素手での木採掘速度は mt=4.0(ツルハシ×1 相当と同速)
---
## クラフトシステム
### クラフトレシピ
| 成果物 | 素材 |
|---|---|
| 板材 ×4 | 木材 ×1 |
| 棒 ×4 | 板材 ×2 |
| たいまつ ×4 | 棒 ×1 + 石炭 ×1 |
| 作業台 ×1 | 板材 ×4 |
| ドア ×1 | 板材 ×6 |
| 焚き火 ×1 | 砂利石 ×3 + 棒 ×2 + 石炭 ×1 |
| 木のツルハシ ×1 | 板材 ×3 + 棒 ×2 |
| 石のツルハシ ×1 | 砂利石 ×3 + 棒 ×2 |
| 鉄のツルハシ ×1 | 鉄インゴット ×3 + 棒 ×2 |
| 木の剣 ×1 | 板材 ×2 + 棒 ×1 |
| 石の剣 ×1 | 砂利石 ×2 + 棒 ×1 |
| 鉄の剣 ×1 | 鉄インゴット ×2 + 棒 ×1 |
| ベッド ×1 | 羊毛 ×3 + 板材 ×3 |
| 焼き肉 ×1 | 生肉 ×1 + 石炭 ×1 |
| かまど ×1 | 砂利石 ×8 |
| 木のオノ ×1 | 板材 ×3 + 棒 ×2 |
| 石のオノ ×1 | 砂利石 ×3 + 棒 ×2 |
| 鉄のオノ ×1 | 鉄インゴット ×3 + 棒 ×2 |
### クラフト UI
- R キーで開閉
- クラフト可能なレシピが上位に並ぶ(ソート済み)
- ホバー時にツールチップ表示
- 素材不足は薄暗く表示
---
## 精錬システム(かまど)
かまどに隣接 (距離 < 52 px) して F キーでUIを開く。
### 精錬レシピ
| 素材 | 成果物 | 燃料(石炭) | 時間 |
|---|---|---|---|
| 鉄鉱石 | 鉄インゴット | ×1 | 2.5 秒 |
| 金鉱石 | 金インゴット | ×1 | 3.5 秒 |
---
## 調理システム(焚き火)
焚き火に隣接して F キーを押す。
ホットバーに「生肉」を持っていると「焼き肉」1個に変換。
---
## 戦闘システム
### 攻撃
| 操作 | 動作 |
|---|---|
| 剣を持って左クリック | 扇形スイング(半径 46 px, 角度 ±80°)でヒット判定 |
| その他のアイテムで左クリック | 近接パンチ(距離 < 64 px, カーソル近くの敵を優先) |
### ダメージ計算
```
attackPower = weapon.dmg (武器装備時)
= toolLevel × 2 (ツルハシ等)
= 1 (素手)
```
### 攻撃クールダウン
| 武器 | クールダウン |
|---|---|
| 木の剣 | 0.50 s |
| 石の剣 | 0.45 s |
| 鉄の剣 | 0.38 s |
| ツルハシ等 | 0.65 s |
| 素手 | 1.00 s |
---
## エンティティ
### ゾンビ
| パラメータ | 値 |
|---|---|
| HP | 20 |
| 移動速度 | 55 px/s |
| 攻撃ダメージ | -6 HP |
| 攻撃間隔 | 1.5 s |
| 攻撃範囲 | 距離 < 32 px |
| ドロップ | 生肉 ×1(40% で ×2) |
- 夜(dayTime ? 300)に最大 6 体まで、8 秒ごとにスポーン
- スポーン条件: GRASS タイル かつ 画面外
- 朝になると全滅(`enemies = []`)
### 羊
| パラメータ | 値 |
|---|---|
| HP | 5 |
| 移動速度 | 14 px/s |
| 羊毛再生時間 | 60 秒 |
| 最大数 | 4 匹 |
| 補充タイミング | 1 日の始まり(dayTime < 2)で不足分スポーン |
**インタラクション**:
- 素手でクリック&ホールド → 1 秒で刈り取り(羊毛 2?3 個)
- ツルハシ・剣でクリック → 撃破(生肉 ×1 + 羊毛 ×1)
**描画**:
- 足元に楕円影(横半径 11 px, 縦半径 3.5 px, 不透明度 28%)をスプライト中心の +16 px 下に表示
---
## 昼夜サイクル
| 時刻 | 内容 |
|---|---|
| dayTime 0?300 | 昼(600 秒サイクルの前半) |
| dayTime 300 | 夜の始まり(ゾンビ出現警告) |
| dayTime 300?600 | 夜(画面暗転オーバーレイ、ゾンビスポーン) |
| dayTime ? 600 | 翌朝(dayTime -= 600、ゾンビ消滅) |
- たいまつ・焚き火が `torches` リストに登録され、夜間ライトマスクで光源描画
---
## 睡眠
- ベッドに隣接して F キー(夜のみ有効)
- 0.8 秒後: dayTime=0、ゾンビ消滅、HP+5、空腹+4
- 1.6 秒後: 起床アニメーション終了
---
## 宝箱ルート
宝箱に隣接 or 採掘で開封。
### 表面チェスト(廃村)
| アイテム | 数量 |
|---|---|
| 鉄鉱石 | 1?2 個 |
| 石炭 | 2?4 個 |
| 板材 | 3?7 個 |
| 砂利石 | 4?9 個 |
3?4 種をランダムでドロップ(重複なし)
### 洞窟チェスト(廃坑)
表面チェストの **2 倍** の量をドロップ。
---
## 屋内判定(家)
- ドアを設置後 F キーで開閉するたびに `recalcIndoor()` 実行
- ドア内側から BFS フラッド、300 タイル以内かつ完全に囲まれていれば屋内
- 屋内では夜間 HP 自然回復が発動
---
## セーブ・ロード
- **保存先**: `localStorage['mc2d_save']` (JSON + Base64)
- **保存内容**: map1/map2 配列、インベントリ、HP・空腹・時刻、プレイヤー座標、たいまつリスト
- **オートセーブ**: 120 秒ごと(無音)
- **手動セーブ**: Ctrl+S(トースト表示)
- **セーブバージョン**: v=2
---
## ミニマップ
- 左下に 160×100 px の `OffscreenCanvas` を表示
- プレイヤー位置に白い点を表示
- タイル変更時に `updateMini(tx,ty)` でリアルタイム更新
---
## 音響システム(Web Audio API)
| 関数 | タイミング | 内容 |
|---|---|---|
| `playMine(hard)` | 採掘中 0.45 s ごと | ノイズバースト(石系=低音, 木土系=高音) |
| `playPlace()` | ブロック設置時 | 短い正弦波トーン |
| `playHit()` | 攻撃ヒット時 | ノコギリ波降下 |
| `playPickup()` | アイテム取得時 | 短い上昇音 |
| `playZombieAtk()` | ゾンビ攻撃時 | 低音唸り |
| `playNight()` | 夜になった瞬間 | 3 音コード |
---
## パーティクルシステム
- 採掘完了・設置・ダメージ時に短命パーティクルを生成
- 重力あり(+200 px/s?)、空気抵抗あり(×0.88/フレーム)
- ライフタイム 0.35?0.65 秒
---
## HUD(パネルエリア)
```
[ホットバー 10 スロット][HP バー][空腹バー][ツールチップ]
```
- HP バー: 緑→黄→赤(HP が半分以下で黄、25%以下で赤)
- 空腹バー: 橙→赤
- 空腹度 ? 4 で「空腹警告」表示
- 現在ツールのダメージ・ツールレベルをパネルに表示
---
## 定数まとめ
| 定数 | 値 | 説明 |
|---|---|---|
| TILE | 32 | タイルサイズ (px) |
| MAP_W / MAP_H | 160 / 100 | マップサイズ (タイル) |
| INV_SIZE | 36 | インベントリスロット数 |
| HOTBAR | 10 | ホットバースロット数 |
| SHORE_R | 14 | 海岸線幅 (タイル) |
| MAX_HOUSE | 300 | 屋内判定最大タイル数 |
| GAS_DMG_P | 33.3 / s | (将来拡張用) |
---
## 乱数システム
LCG(線形合同法)ベースのシード付き乱数:
```js
_rs = (_rs * 1664525 + 1013904223) >>> 0
rng(max) = _rs % max // 整数
rngf() = rng(1000000) / 1000000 // 0?1 浮動小数
```
ノイズ関数 `noise(x,y)` は 4 オクターブの sin/cos 合成。
---
## 将来の拡張候補
- バイオームシステム(砂漠・雪原・沼地)
- 武器・防具強化(エンチャント)
- 農業・植林システム
- ネザー(地下ダンジョン)
- マルチクラフトレシピ(シェイプ配置)
- モバイルタッチ対応バーチャルパッド