huyi1985
@huyi1985

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

なぜ『スーパーマリオブラザーズ』(FC)では、マリオがブロックを叩く前に隠し1UPフラグがクリアされたのか?

『スーパーマリオブラザーズ』(FC)の逆アセンブルコード(こちら)を解析していたところ、隠し1UPキノコに関する興味深い仕様を見つけました。

それは、1UPの二重取得を防ぐフラグが、マリオが実際に隠しブロックを叩く前にクリアされた という点です。

該当コード:

; https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L4172

Hidden1UpBlock:
      lda Hidden1UpFlag  ;if flag not set, do not render object
      beq ExitDecBlock
      lda #$00           ;if set, init for the next one
      sta Hidden1UpFlag
      jmp BrickWithItem  ;jump to code shared with unbreakable bricks

例えば、1-1 の隠し1UPの場合、この処理は マリオが以下の画像の位置に到達した時点で実行されます。しかし、この時点では 1UP のブロックはまだ画面外にあります。

そのため、もし初心者プレイヤーがこの地点でクリボーにやられてしまうと、次回のプレイでは 1UPを取得するチャンスが完全に失われる ことになります。

この仕様は、Webアプリに例えると「ボタンを押した瞬間にクーポンを取得」ではなく、「ページを開いた瞬間にクーポンを取得済みとみなす」ような挙動に似ています。

もし運悪くクーポンを押さないままページをリロードしてしまうと、クーポンは未取得のまま失われてしまう、という状況です。

考えられる理由の一つは、ファミコンのハードウェア制約を回避するための最適化です。
もし**「マリオがブロックを叩いた瞬間」**にフラグをクリアする仕様だった場合、以下のような追加処理が必要になると思います。

  • マリオがジャンプするたびに、隠し1UPブロックとの衝突を判定する
  • プレイヤーが1UPを取得できるかどうかをチェックする
  • さらに、マリオの位置 => 取得可否のフラグを検索するテーブルを作成・参照する処理も発生する(O(N) の空間計算量を犠牲にして O(1) の時間計算量を得るため)

この仕様について、詳しい方のご意見を伺いたいです!
これは単なる最適化なのでしょうか? それともゲームバランスやデザイン上の意図があったのでしょうか?

3

2Answer

フラグクリア位置の、境界試験をやりやすいポイントに設定されているのではないかと思いました

上の画像の位置でクリボーに当たる
 =>次回プレイで1UPキノコは取れない

上の画像の1ブロック手前でクリボーに当たる
 =>次回プレイで1UPキノコは取れる

1Like

Your answer might help someone💌