# 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 合成。 --- ## 将来の拡張候補 - バイオームシステム(砂漠・雪原・沼地) - 武器・防具強化(エンチャント) - 農業・植林システム - ネザー(地下ダンジョン) - マルチクラフトレシピ(シェイプ配置) - モバイルタッチ対応バーチャルパッド