FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

トラキア776 移動範囲チェックルーチン


トラキア式移動消費配列取得プログラム解説


------------------------------------------------------------------------------------
・資料

*トラキア776 移動消費配列取得ルーチン トラキア776 移動消費配列取得ルーチン

*各クラス クラス基本データ設定       $30000 各クラス基本設定

*各クラス地形コストデータ           $310BC~ クラス別 地形移動コスト設定

------------------------------------------------------------------------------------
今回は解りやすくするために


・マップの大きさはX=#20、Y=#20とする

・マップ全体の移動消費コストを1とする

・移動チェック座標起点はX=9、Y=9とする

・移動ユニットの移動力は5とする

座標チェック説明1

マップ外周部の青い部分はカーソル移動不可能の部分である

----------------------------------------------------------------------------------

・下準備として移動消費配列バッファ(7E:A937~7E:AF36)には全領域にあらかじめFFの値を入力しておく。

(7E:A937~7E:AF36 ;マップ上 移動消費配列 $600バイト分)

----------------------------------------------------------------------------------

・現在座標X、Yを2バイトの値で表す方法、

現在座標 = 現在座標Y *( マップ座標X大きさ+1 )+ 現在座標X

説明図
--------------------------------------------------------------------------------
・また、2バイトの値で表した現在座標をX、Yに戻す方法。

現在座標 ÷ ( マップ座標X大きさ+1 )

商=現在X座標
余り=現在Y座標

---------------------------------------------------------------
現在座標が( マップ座標X大きさ+1 )で割りきれない場合は

現在X座標=現在座標
現在Y座標=0

と成る。

----------------------------------------------------------------------------------

*使用メモリ

7E:000B = 座標チェック 1巡判別フラグ

7E:000F = 移動ユニット移動力(+1)

7E:0013 = マップ上のユニットの存在を無視する/無視しないフラグ ; 00=無視する FF=無視しない

7E:0015 = 座標チェックデータ 一時書き込みインデックス (2バイト)

7E:0017 = 座標チェックデータ 一時読み込みインデックス (2バイト)

7E:0019 = マップ上ユニット存在チェック  RAMアドレスを格納 ; チェック基準座標の上 (2バイト)
7E:001B = マップ上ユニット存在チェック  RAMアドレスを格納 ; チェック基準座標の下 (2バイト)
7E:001D = マップ上ユニット存在チェック  RAMアドレスを格納 ; チェック基準座標の左 (2バイト)
7E:001F = マップ上ユニット存在チェック  RAMアドレスを格納 ; チェック基準座標の右 (2バイト)

7E:0021 = マップチップ地形ID配置 RAMアドレスを格納 ; チェック基準座標の上 (2バイト)
7E:0023 = マップチップ地形ID配置 RAMアドレスを格納 ; チェック基準座標の下 (2バイト)
7E:0025 = マップチップ地形ID配置 RAMアドレスを格納 ; チェック基準座標の左 (2バイト)
7E:0027 = マップチップ地形ID配置 RAMアドレスを格納 ; チェック基準座標の右 (2バイト)

7E:0029 = マップ上移動消費配列 RAMアドレスを格納 ; チェック基準座標の上 (2バイト)
7E:002B = マップ上移動消費配列 RAMアドレスを格納 ; チェック基準座標の下 (2バイト)
7E:002D = マップ上移動消費配列 RAMアドレスを格納 ; チェック基準座標の左 (2バイト)
7E:0032 = マップ上移動消費配列 RAMアドレスを格納 ; チェック基準座標の右 (2バイト)

7E;0035 = 座標チェック方向 プログラムアドレスヘッダ (2バイト)

7E:1038 ~ 7E:12B7まで ; 座標チェックデータ 一時格納メモリA ;4バイトずつ ;$280バイト

7E:12B8 ~ 7E:1537まで ; 座標チェックデータ 一時格納メモリB ;4バイトずつ ;$280バイト

7E:520C ~ 7E:5238   ; 移動消費配列算出時 各地形移動コスト

7E:6FCB ~         ; マップ上ユニット存在チェックバッファ

7E:7BCB ~        ; マップチップ地形ID配置 RAMアドレス

7E:A937 ~ 7E:AF36   ; マップ上 移動消費配列

--------------------------------------------------------------------------------------------

・座標チェックデータは1セットあたり

1、チェック先座標の座標値1 (チェック先座標の座標値は2バイト管理)
2、チェック先座標の座標値2
3、チェック先座標の方向         ;00=上下左右 ;02=上 ;04=右 ;06=下 ;08=左
4、チェック先座標の移動消費配列値

となっている。

--------------------------------------------------------------------------------------------
・座標チェック箇所は移動力が1増えるごとに4つずつ増えていく。

$280÷4=$A0 ;最大#160個分の座標チェックデータが格納可能。

$A0÷4=$28 ;#40
--------------------------------------------------------------------------------------------
チェック開始時の最初の処理

000Bに00を格納
0015
0017

---------------------------------------------------------------------------------------------

各座標をチェックする際に、「座標チェックデータとして登録しない条件」 として以下の4つの条件がある。

すなわち

(1)チェック先座標上に敵対ユニットが存在する。

(2)チェック先座標が移動不可能な地形である。

(3)チェック先座標の移動消費配列値が [ チェック元座標の移動消費配列 + チェック先座標の地形移動コスト ] よりも小さい。

(4)チェック先座標の移動消費配列が移動ユニットの移動力よりも大きい。



(3)に関しては少し分かりにくいかもしれないが、これは後ほど解説する。  ※移動消費配列の最適値を取得 参照

--------------------------------------------------------------------------------------------------

・今回は簡易版解説なので敵対ユニットの存在チェック、移動不可地形のチェックはしない。



=====================================================================================
=====================================================================================

・初回は上下左右チェックルーチン


まずチェック座標起点情報を座標チェックデータ一時格納メモリに入力する

データの入力先は7E;1038~にセット


現在座標 X=9、Y=9
現在座標XYを2バイトで表すと ; マップX広さ($14) * 現在X座標($9) + 現在Y座標($9)=$00BD


7E;1038=00BD ; 現在座標を格納
7E;103A=0000 ; 移動消費コストを格納 ;起点なので移動消費配列はゼロ

7E;103E=FFFF ; 一巡読み込み終了フラグをセット

-----------------------------------------------------

・座標チェックデータ一時格納メモリへの入力先アドレスを変更


座標チェックデータ 一時書き込みアドレスを7E:12B8~にセットする ; 7E;0015 = $0280

座標チェックデータ 一時読み込みアドレスを7E:1038~にセットする ; 7E;0017 = $0000

=====================================================================================
=====================================================================================

移動座標起点周囲のチェック開始

まず現在位置00BDを中心に

          1 現在基準座標の上座標
          2 現在基準座標の下座標
          3 現在基準座標の左座標
          4 現在基準座標の右座標

の順にチェックしていく。


図1

座標チェック説明2B


座標チェックデータ一時格納メモリ

7E;12B8=00A9 ; チェック座標      (1)
7E;12BA=01   ; 移動消費配列
7E;12BB=02   ; チェック方向 上

7E;12BC=00D1 ; チェック座標      (2)
7E;12BE=01   ; 移動消費配列
7E;12BF=06   ; チェック方向 下

7E;12C0=00BC ; チェック座標      (3)
7E;12C2=01   ; 移動消費配列
7E;12C3=08   ; チェック方向 左

7E;12C4=00BE ; チェック座標      (4)
7E;12C6=01   ; 移動消費配列
7E;12C7=04   ; チェック方向 右

-----------------------------------------------------------------------
・チェック方向の値は 

  上 = 02 
  下 = 06 
  左 = 08 
  右 = 04 

である。

-----------------------------------------------------------------------

・移動消費配列図

       01
    01 00 01
       01

-----------------------------------------------------------------------

座標00BDのチェック終了

7E;12CAにFFFFを入力する ; 一巡チェック終了フラグ


座標チェックデータ 一時書き込みアドレスを7E:1038~にセットする ; 7E;0015 = $0000

座標チェックデータ 一時読み込みアドレスを7E:12B8~にセットする ; 7E;0017 = $0280

=====================================================================================
=====================================================================================

・上座標のチェック         (1)

00A9を中心にして上、左、右とチェックしていく

図2

座標チェック説明3B


チェック先座標が移動可能である場合、

・チェック先座標
・チェック先座標の方向
・チェック先座標の移動消費配列

を座標データチェック一時格納領域に入力し、また、7E:A937~の移動消費配列格納領域に移動消費配列を入力する。

そしてチェック先座標データ読み込みインデックスを+4する。

座標チェックデータ一時格納メモリの格納先メモリアドレスを7E;1038~にセット

チェック先座標のデータを格納していく


7E;1038=0095 ; チェック先座標
7E;103A=02   ; 移動消費配列
7E;103B=02   ; チェック方向 上

7E;103C=00A8 ; チェック先座標
7E;103E=02   ; 移動消費配列
7E;103F=08    ; チェック方向 左

7E;1040=00AA ; チェック先座標
7E;1042=02   ; 移動消費配列
7E;1043=04   ; チェック方向 右

--------------------------------------------------------------------------------------------------

・下座標のチェック         (2)

00D1を中心に下、左、右とチェックしていく

図3

座標チェック説明4B


7E;1044=00E5 ; チェック先座標
7E;1046=02   ; 移動消費配列
7E;1047=06   ; チェック方向 下

7E;1048=00D0 ; チェック先座標
7E;104A=02   ; 移動消費配列
7E;104B=08   ; チェック方向 左

7E;104C=00D2 ; チェック先座標
7E;104E=02   ; 移動消費配列
7E;104F=04   ; チェック方向 右

--------------------------------------------------------------------------------------------------

・左座標のチェック         (3)

00BCを中心に上、下、左とチェックしていく

図4

座標チェック説明5B


-----------------------------------------------------------------------

※移動消費配列の最適値を取得


・00A8、00D0は既に調べたにもかかわらず再びチェックするのは座標A(00BD)から座標B(00A8)へ移動する際の
 最適経路を導くためである。



・解説図
座標チェック説明 同座標チェック説明


薄緑色は平地、移動コストは1とする
深緑色は林、移動コストは2とする

-----------------------------------------------------------------

座標00BDから座標00A8に最短で移動する場合

  (1) 00BD→00A9→00A8 の順に進む場合
  (2) 00BD→00BC→00A8 の順に進む場合

  が考えられるが、図の場合(1)の順路で進んだほうが移動コストは少なくて済む。



(1)の順路の場合
座標チェック説明 同座標チェックA


(1)の順路の場合の移動消費配列

  02 01 
     00 
-----------------------------------------------

(2)の順路の場合
座標チェック説明 同座標チェックB


(2)の順路の場合の移動消費配列

  03 
  02 00 

--------------------------------------------

(1)の順路で進んだ場合、00A8の移動消費配列は2であるが、
(2)の順路で進んだ場合、00A8の移動消費配列は3になる。

この場合、00A8の移動消費配列は、より小さい値である2が採用される。

-------------------------------------------------------------------------------

以上のように、同じ座標をチェックしているのは移動コスト配列の最小値を求めるためである。


座標情報チェック時、
「 その時チェックするチェック先座標の移動コスト配列 」 と 「 既に入力されているチェック先座標の移動コスト配列 」
とを比較して

その時取得したチェック先座標の移動コスト配列 < 既に取得した同チェック先座標の移動コスト配列

の場合、チェック先座標の座標情報が更新される。  (わかりにくい?)

--------------------------------------------------------------------------

よって、今回調べた00A8、00D0の座標情報は採用しない。

今回入力する座標情報は

7E;1050=00BB ; チェック先座標
7E;1052=02   ; 移動消費配列
7E;1053=08   ; チェック方向 左

のみである。

-------------------------------------------------------------------------------------------------

・右座標のチェック         (4)

00BEを中心に上、下、右とチェックしていく

図5

座標チェック説明6B


7E;1054=00BF ; チェック先座標
7E;1056=02   ; 移動消費配列
7E;1057=04   ; チェック方向 右

(この時調べた00AA、00D2の座標情報は採用しない。 理由は前述。)

------------------------------------------------------------

一巡チェック終了

今回チェックした移動可能な座標データ一覧

7E;1038=0095 ; チェック先座標   (1)
7E;103A=02   ; 移動消費配列
7E;103B=02   ; チェック方向 上

7E;103C=00A8 ; チェック先座標   (2)
7E;103E=02   ; 移動消費配列
7E;103F=08    ; チェック方向 左

7E;1040=00AA ; チェック先座標   (3)
7E;1042=02   ; 移動消費配列
7E;1043=04   ; チェック方向 右

7E;1044=00E5 ; チェック先座標   (4)
7E;1046=02   ; 移動消費配列
7E;1047=06   ; チェック方向 下

7E;1048=00D0 ; チェック先座標   (5)
7E;104A=02   ; 移動消費配列
7E;104B=08   ; チェック方向 左

7E;104C=00D2 ; チェック先座標   (6)
7E;104E=02   ; 移動消費配列
7E;104F=04   ; チェック方向 右

7E;1050=00BB ; チェック先座標   (7)
7E;1052=02   ; 移動消費配列
7E;1053=08   ; チェック方向 左

7E;1054=00BF ; チェック先座標   (8)
7E;1056=02   ; 移動消費配列
7E;1057=04   ; チェック方向 右

7E;105A=FFFF   ;一巡チェック終了コード

------------------------------------------------------------------------------

・移動消費配列図


         02
      02 01 02
   02 01 00 01 02
      02 01 02
         02

------------------------------------------------------------------------------

・次は、これらのデータをもとに以上の座標を基点としてそれぞれの座標の周りをチェックしていく。


座標チェックデータ 一時書き込みアドレスを7E:12B8~にセットする ; 7E;0015 = $0280

座標チェックデータ 一時読み込みアドレスを7E:1038~にセットする ; 7E;0017 = $0000

=====================================================================================
=====================================================================================


・座標0095のチェック   (1)

7E;12B8=0081 ; チェック先座標
7E;12BA=03   ; 移動消費配列
7E;12BB=02   ; チェック方向 上

7E;12BC=0094 ; チェック先座標
7E;12BE=03   ; 移動消費配列
7E;12BF=08   ; チェック方向 左

7E;12C0=0096 ; チェック先座標
7E;12C2=03   ; 移動消費配列
7E;12C3=04   ; チェック方向 右


座標チェック説明A


----------------------------------------------------------------

・座標00A8のチェック   (2)

7E;12C4=00A7 ; チェック先座標
7E;12C6=03   ; 移動消費配列
7E;12C7=08   ; チェック方向 左

0094、00BCの座標情報は既にチェックされたものが優先される。


座標チェック説明B

----------------------------------------------------------------

・座標00AAのチェック   (3)

7E;12C8=00AB ; チェック先座標
7E;12CA=03   ; 移動消費配列
7E;12CB=04   ; チェック方向 右

0096、00BEの座標情報は既にチェックされたものが優先される。


座標チェック説明C

----------------------------------------------------------------

・座標00E5のチェック   (4)

7E;12CC=00F9 ; チェック先座標
7E;12CE=03   ; 移動消費配列
7E;12CF=06   ; チェック方向 下

7E;12D0=00E4 ; チェック先座標
7E;12D2=03   ; 移動消費配列
7E;12D3=08   ; チェック方向 左

7E;12D4=00E6 ; チェック先座標
7E;12D6=03   ; 移動消費配列
7E;12D7=04   ; チェック方向 右


座標チェック説明D

----------------------------------------------------------------

・座標00D0のチェック   (5)

7E;12D8=00CF ; チェック先座標
7E;12DA=03   ; 移動消費配列
7E;12DB=08   ; チェック方向 左

00BC、00E4の座標情報は既にチェックされたものが優先される。


座標チェック説明E

----------------------------------------------------------------

・座標00D2のチェック   (6)

7E;12DC=00D3 ; チェック先座標
7E;12DE=03   ; 移動消費配列
7E;12DF=04   ; チェック方向 右

00BE、00E6の座標情報は既にチェックされたものが優先される。


座標チェック説明E2

----------------------------------------------------------------

・座標00BBのチェック   (7)

7E;12E0=00BA ; チェック先座標
7E;12E2=03   ; 移動消費配列
7E;12E3=08   ; チェック方向 左

00A7、00CFの座標情報は既にチェックされたものが優先される。


座標チェック説明F


----------------------------------------------------------------

・座標00BFのチェック   (8)

7E;12E4=00C0 ; チェック先座標
7E;12E6=03   ; 移動消費配列
7E;12E7=04   ; チェック方向 右

00AB、00D3の座標情報は既にチェックされたものが優先される。


座標チェック説明J

----------------------------------------------------------------

・座標一巡チェック終了

7E;12EA=FFFF ; チェック終了フラグ格納


座標チェック説明K


----------------------------------------------------

今回チェック、格納した座標情報


7E;12B8=0081 ; チェック先座標   (1)
7E;12BA=03   ; 移動消費配列
7E;12BB=02   ; チェック方向 上

7E;12BC=0094 ; チェック先座標   (2)
7E;12BE=03   ; 移動消費配列
7E;12BF=08   ; チェック方向 左

7E;12C0=0096 ; チェック先座標   (3)
7E;12C2=03   ; 移動消費配列
7E;12C3=04   ; チェック方向 右

7E;12C4=00A7 ; チェック先座標   (4)
7E;12C6=03   ; 移動消費配列
7E;12C7=08   ; チェック方向 左

7E;12C8=00AB ; チェック先座標   (5)
7E;12CA=03   ; 移動消費配列
7E;12CB=04   ; チェック方向 右

7E;12CC=00F9 ; チェック先座標   (6)
7E;12CE=03   ; 移動消費配列
7E;12CF=06   ; チェック方向 下

7E;12D0=00E4 ; チェック先座標   (7)
7E;12D2=03   ; 移動消費配列
7E;12D3=08   ; チェック方向 左

7E;12D4=00E6 ; チェック先座標   (8)
7E;12D6=03   ; 移動消費配列
7E;12D7=04   ; チェック方向 右

7E;12D8=00FC ; チェック先座標   (9)
7E;12DA=03   ; 移動消費配列
7E;12DB=08   ; チェック方向 左

7E;12DC=00D3 ; チェック先座標   (10)
7E;12DE=03   ; 移動消費配列
7E;12DF=04   ; チェック方向 右

7E;12E0=00BA ; チェック先座標   (11)
7E;12E2=03   ; 移動消費配列
7E;12E3=08   ; チェック方向 左

7E;12E4=00C0 ; チェック先座標   (12)
7E;12E6=03   ; 移動消費配列
7E;12E7=04   ; チェック方向 右

7E;12EA=FFFF ; チェック終了フラグ格納

----------------------------------------------------------

・移動消費配列図

          03
       03 02 03
    03 02 01 02 03
 03 02 01 00 01 02 03
    03 02 01 02 03
       03 02 03
          03

----------------------------------------------------------

座標チェックデータ 一時書き込みアドレスを7E:1038~にセットする ; 7E;0015 = $0000

座標チェックデータ 一時読み込みアドレスを7E:12B8~にセットする ; 7E;0015 = $0280

=====================================================================================
=====================================================================================

・以降、煩雑(?)なので座標チェックの手順は省略する


座標チェック説明8

----------------------------------------------------------

・移動消費配列図

             04
          04 03 04
       04 03 02 03 04
    04 03 02 01 02 03 04
 04 03 02 01 00 01 02 03 04
    04 03 02 01 02 03 04
       04 03 02 03 04
          04 03 04
             04

------------------------------------------------------

座標チェックデータ 一時書き込みアドレスを7E12B8:~にセットする ; 7E;0015 = $0280

座標チェックデータ 一時読み込みアドレスを7E:1038~にセットする ; 7E;0017 = $0000

=====================================================================================
=====================================================================================



座標チェック説明9

----------------------------------------------------------

・移動消費配列図

                05
             05 04 05
          05 04 03 04 05
       05 04 03 02 03 04 05
    05 04 03 02 01 02 03 04 05
 05 04 03 02 01 00 01 02 03 04 05
    05 04 03 02 01 02 03 04 05
       05 04 03 02 03 04 05
          05 04 03 04 05
             05 04 05
                05

------------------------------------------------------

座標チェックデータ 一時書き込みアドレスを7E:1038~にセットする ; 7E;0015 = $0000

座標チェックデータ 一時読み込みアドレスを7E:12B8~にセットする ; 7E;0015 = $0280

=====================================================================================
=====================================================================================



座標チェック説明10

------------------------------------------------------

・移動消費配列図

                  06
               06 05 06
            06 05 04 05 06
         06 05 04 03 04 05 06
      06 05 04 03 02 03 04 05 06
   06 05 04 03 02 01 02 03 04 05 06
06 05 04 03 02 01 00 01 02 03 04 05 06
   06 05 04 03 02 01 02 03 04 05 06
      06 05 04 03 02 03 04 05 06
         06 05 04 03 04 05 06
            06 05 04 05 06
               06 05 06
                  06

------------------------------------------------------


外縁の赤い部分の座標の移動消費配列は移動ユニットの移動力以上の値なので移動不可である。

よって、今回チェックした座標は全て登録されず、
座標チェックデータ一時格納メモリの書き込みアドレスである7E:1038にはFFFFが格納される。


読み込みアドレスの最初のデータがFFFFであれば移動消費配列取得プログラムは終了する(説明不足。要加筆)


=================================================================================
=================================================================================

・後記


 トラキア776の移動消費配列の解説を記事にしてみましたが、
多分この説明だけではよくわからないと思います。
 ですのでSLGのプログラムに詳しい方、または興味のある方、そうでない方も
疑問点、指摘点が多数あると思いますので是非コメントをください。順次校正していきます。


 今回の記事はなかなか難しい内容なので毎日(2週間ぐらい下書き状態で編集して
いました・・・)加筆、修正チェックを繰り返していると段々とノイローゼ状態になって
きたので一度公開してみました(笑)。

 市販のSLGのプログラム本を読んでも、またネット情報でもこの手のプログラムは
あまり詳しく解説されていないようなので今回の記事がSLG制作に興味を持っている
人たちの役に立てば、と願っています。

 次回は実際にトラキアのゲーム画面を用いて解説していく予定です。

---------------------------------------------------------------------

・雑談

1ヶ月強ぶりの更新になりました。長いあいだコメントの返信ができず、大変失礼しました。

<機械音痴

ヴェスタリア、プレイできましたか?(笑)

 自分の日記によれば、9月19日からヴェスタリアをプレイし始めてたんですが
予想通りドハマリしてしまい10月9日にクリアするまでほとんどヴェスタリア漬け
状態でブログの更新が全くできませでした。
 おかげでちょっと前まで調べていたトラキアのCPU思考ルーチンなどの
解析データ等は頭の中でほぼデリート状態・・・

 ヴェスタリアをクリアしたあと(今から2週間ほど前)解析資料を再チェックし始めたときは
どのデータがPC内のどこにあるのかも失念していた有様でした・・・ゲーム怖い・・・
(睡眠中の夢の中でもゲームしているなんて、何年ぶり?(笑))

 今回の一件で、学生時代に勉学の邪魔になるのでそれまで所持していた漫画やゲームを全部
処分したときのことを思い出しました(泣) 

 ヴェスタリア2部、制作公開されて欲しいような、ないような(笑


今回はこんな感じですね。 ではまた次回に。


スポンサーサイト

カウンタ

プロフィール

Anonymous

Author:Anonymous
ファミコンゲーム解析、同人ゲーム制作

免責 
本ブログの管理者は第三者がこの
ブログでDLしたツールを使用する
ことによって発生した如何なる
事件・損害に対して全く責任を
負いません

最新記事
月別アーカイブ
カテゴリ
検索フォーム
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。