hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
経路決定 - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

[hsp3]

経路決定

  • 移動判定で移動できる地点が分かったら、次はその地点へ移動するための経路を調べます。経路を調べるためには、出発地点と目的地点の座標、および移動判定で調べた移動力の分布が必要になります。[eller]
  • ...

スクリプト

  • モジュールとサンプルコードのセットです。コメント多めにしたらやたらと長くなってしまいましたが(^^;、モジュール部分は至ってシンプルです。
  • 移動判定部分は移動判定で使ったものをそのまま使っています。

【操作方法】

  • 画面上をクリックすると、クリックした地点への経路を検索し表示します(移動可能な地点のみ)。
    fileSRPGWalk.hsp
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    -
    |
    -
    |
    |
    -
    |
    -
    |
    |
    |
    |
    |
    |
    -
    |
    !
    -
    |
    !
    !
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    -
    |
    -
    |
    |
    !
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    -
    |
    |
    |
    !
     
     
     
     
    -
    |
    |
    |
    |
    |
    |
    |
    -
    -
    |
    -
    |
    !
    !
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
    #module SRPGWalk
    /*
    	srpginit
    		モジュールにマップの情報を渡す/モジュールの初期化
    	mapserch
    		出発地点と移動力から移動可能な地点を計算
    	getwalk
    		目的地から移動順路を計算
    */
     
    /*	srpginit p1, p2, p3
    		p1(var) : 文字列型マップデータ格納変数
    		p2,p3(int) : マップサイズ(X,Y)
     
    	モジュール初期化命令。マップデータには"112131...122"のような文字列を指定します。
    	この文字が「その地点を通過するために必要な移動力」を示しています(草原なら1、森なら2など)。
    	マップデータはp2*p3以上の長さを持っている必要があります。*/
    #deffunc srpginit str s1, int p2, int p3
        map = s1 : mapsizeX = p2 : mapsizeY = p3
        dim subx, 4 : subx = 0, 1, 0, -1
        dim suby, 4 : suby = -1, 0, 1, 0
    return
     
    /*	serch p1, p2
    		p1(int) : 残り移動量
    		p2(int) : 向き
     
    	モジュール内で使用する命令。(x,y)から見てp2の方向の地点(x+subx(p2),y+suby(p2))に
    	移動できるかどうかを計算します。ちなみに方向は
    		0 : 上	1 : 右	2 : 下	3 : 左
    	を示します。*/
    #deffunc serch@SRPGWalk int p1, int p2, local dir
        dir = p2 : many++
        serchX = x+subx(dir)
        serchY = y+suby(dir)    ; 調査対象地点(serchX, serchY)
        if (serchX<0)|(serchY<0)|(serchX>=mapsizeX)|(serchY>=mapsizeY) {
                                ; 移動不可能(対象座標がマップ外)
        } else {
            i = p1-peek(map, serchY*mapsizeX+serchX)+'0'
    ;		i = p1-int(strmid(map, serchY*mapsizeX+serchX, 1)) と同義
            if i>0 {            ; 移動量は充分
                j = peek(result, serchY*mapsizeX+serchX)
                if j<i {
                                ; 移動可能
                    x = serchX : y = serchY
                    logmes strf("[%03d]地点("+serchX+","+serchY+")は移動可能です", many)
                    poke result, serchY*mapsizeX+serchX, i
                    serch i, 0
                    x -= subx(dir) : y -= suby(dir)
                } else {
                    logmes strf("[%03d]地点("+serchX+","+serchY+")は既に調査完了しています", many)
                }
            } else {
                logmes strf("[%03d]地点("+serchX+","+serchY+")は移動不可能です", many)
            }
        }
        if dir<3 : serch p1, dir+1
    return
     
    /*	mapserch p1, p2, p3, p4
    		p1(var) : 探索データ格納変数
    		p2,p3(int) : 出発地点(X,Y)
    		p4(int) : 移動力
     
    	地点(p2,p3)から移動力p4でどこまで移動できるかを計算します。
    	先にsrpginit命令が実行されている必要があります。
    	計算した結果は変数p1に格納されます。
    	p1の内容は0や1、2など「その地点での残り移動力」を示しています。
    	値が0ならば移動不可能,1以上なら移動可能です。*/
    #deffunc mapserch var v1, int p2, int p3, int p4
        sdim result, mapsizeX*mapsizeY
        sdim v1, mapsizeX*mapsizeY
        x = p2 : y = p3
        many = 0
     
        poke result, y*mapsizeX+x, p4+1
        serch p4+1, 0
        memcpy v1, result, mapsizeX*mapsizeY
    return
     
    /*	prev(p1, p2)
    		p1,p2(int) : 調査地点(X,Y)
     
    	モジュール内で使用する関数。
    	地点(p1,p2)に移動する前にいた地点を計算するため、
    	「どの方向に進むことで地点(p1,p2)に着いたか」を返します。
    	値は0(上)〜3(左)、-1(該当なし)のいずれかになります。
    	地点(p1,p2)に移動する前にいた地点は
    		(p1-subx(prev(p1,p2)), p2-suby(prev(p1,p2)))
    	になります。*/
    #defcfunc prev@SRPGWalk int p1, int p2
        stt = -1
        i1 = peek(result, p1+p2*mapsizex)
        repeat 4    ; 全方向調査
                serchX = p1+subx(cnt) : serchY = p2+suby(cnt)    ; 調査対象座標
                if (serchX<0)|(serchY<0)|(serchX>=mapsizex)|(serchY>=mapsizey){
                    continue    ; 対象座標なし
                } else {
                    i2 = peek(result, serchY*mapsizex+serchX)
                    if i2>i1 : i1 = i2 : stt = cnt^2
                }
        loop
    return stt
     
    /*	getwalk p1, p2, p3
    		p1(var) : 足跡データ格納変数
    		p2,p3(int) : 目的地点(X,Y)
     
    	現在地から目的地点(p2,p3)に移動する最短経路を計算します。
    	先にmapserch命令が実行されている必要があります。
    	結果は変数p1に"011003"のように格納されます。0〜3の数字は上〜左を表します。
    	例えば"011003"なら上右右上上左と移動することで目的地に着くことが分かります。*/
    #deffunc getwalk var v1, int p2, int p3
        v1 = "" : x = p2 : y = p3
        if peek(result, x+y*mapsizeX)==0 : return -1    ; 移動不可能な地点を指定された
        repeat
            b = prev(x, y)    ; (x,y)地点には,どの方向に進むことで到達するか?
            if b<0 : a = cnt : break    ; どの方向でもない = 現在地点が出発地点
            v1 = str(b)+v1
            x -= subx(b) : y -= suby(b)    ; 一歩戻る
        loop
        ; aにはv1の長さが格納されている
        poke v1, a, 0    ; v1のaバイト目に文字列終了コードを書き込み
    return a
    #global
     
     
    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //		モジュールサンプル
    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    #define MAPX 11                ; マップの横方向の大きさ
    #define MAPY 11                ; マップの縦方向の大きさ
    #define MOVE 5                ; 移動力
    #define SQSIZE 32            ; タイルの一辺の長さ
        randomize
        screen 0, MAPX*SQSIZE, MAPY*SQSIZE
        sdim mapdata, MAPX*MAPY
        repeat MAPX*MAPY        ; 自動マップ作成 75%の確率で1,25%の確率で2
            if rnd(4)==0 : poke mapdata, cnt, '2' : else : poke mapdata, cnt, '1'
        loop
        dim subx, 4 : subx = 0, 1, 0, -1
        dim suby, 4 : suby = -1, 0, 1, 0
     
        srpginit mapdata, MAPX, MAPY    ; マップのデータと大きさをモジュールに渡す
        mx = (MAPX-1)/2 : my = (MAPY-1)/2    ; 初期位置はマップの中心
        mapserch s, mx, my, MOVE        ; 移動可能地点検索
        targetX = mx : targetY = my        ; 
     
    *main
        redraw 0    ;描画処理開始
        repeat MAPY : c1 = cnt
            repeat MAPX
                ; マップ描画(矩形塗りつぶし) 1は薄灰、2は濃灰
                a = 255-64*(peek(mapdata, c1*MAPX+cnt)-'0')
                color a, a, a : boxf cnt*SQSIZE, c1*SQSIZE, (cnt+1)*SQSIZE, (c1+1)*SQSIZE
     
                i = peek(s, c1*MAPX+cnt)
                if i {            ; 移動可能な地点に白い正方形の枠を描く
                    color 255, 255, 255
                    x = cnt : y = c1 : gosub *draw_sq
                    pos cnt*SQSIZE+12, c1*SQSIZE+8 : mes i-1    ; 残り移動力
                }
            loop
        loop
     
        getwalk walk, targetX, targetY : i = stat
        if i>0{
            title "移動可能 ["+targetX+","+targetY+"]"
            color 255 : x = mx : y = my
            repeat i    ; 移動経路に赤い正方形の枠を描く
                a = peek(walk,cnt)-'0'
                x += subx(a) : y += suby(a)
                gosub *draw_sq
            loop
        }else{
            if i {
                title "移動不可 ["+targetX+","+targetY+"]"
            } else {
                title "現在地 ["+targetX+","+targetY+"]"
            }
        }
     
        color 255, 255, 255 : circle mx*SQSIZE, my*SQSIZE, (mx+1)*SQSIZE, (my+1)*SQSIZE
        redraw    ; 描画処理終了
        onclick goto *set_target
    stop
    *set_target
        targetX = mousex/SQSIZE : targetY = mousey/SQSIZE
    goto *main
     
    ; 地点(x,y)に正方形の枠を描く
    *draw_sq
        line x*SQSIZE+1, y*SQSIZE+1, (x+1)*SQSIZE-2, y*SQSIZE+1
        line (x+1)*SQSIZE-2, y*SQSIZE+1, (x+1)*SQSIZE-2, (y+1)*SQSIZE-2
        line (x+1)*SQSIZE-2, (y+1)*SQSIZE-2, x*SQSIZE+1, (y+1)*SQSIZE-2
        line x*SQSIZE+1, (y+1)*SQSIZE-2, x*SQSIZE+1, y*SQSIZE+1
    return

コメント

  • 経路探索は、目的地から順番に番号を振って自分のところへもってくればいいと考えます。サンプルよければ提供しますよ。 -- トホホッティー? 2006-12-19 (火) 07:08:43
  • トホホッティーさんこんにちは。これも充分役立つとは思いますが、どんなプログラムか興味があるのでぜひ見せてください。 -- eller 2006-12-19 (火) 07:41:57
  • サンプル作りますのでどこに載せればいいですか?簡単な移動デモ作りたいとおもいます。 -- トホホッティー? 2006-12-19 (火) 14:17:33
  • すみません、僕のはCOMやオートの移動経路判定処理です。自分の移動経路なら移動可能な地点を調べてやるだけでいいと思います。 -- トホホッティー? 2006-12-19 (火) 14:25:32
    • 小ワザのページにCOM関連という見出しがありますのでそちらに追加してはどうでしょうか。レイアウトなどは他のページを参考にしてください。 -- Irisawa 2006-12-19 (火) 15:04:54
    • トホティーさん [hun]の言ってるCOMとはコンピュータのことではないでしょうか?ゲームによって「COM」だったり「CMP」だったりしますよね?(CMPは少ないか...) -- kz3 2006-12-19 (火) 16:48:51
      • あ、すみません。間違いました。略すると同じ表記になってしまうのも困りものですよね。それならアルゴリズム辺りでしょうか。 -- Irisawa 2006-12-19 (火) 16:54:40

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

添付ファイル:
fileSRPGWalk.hsp
550件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-08 (日) 02:45:13 (2436d)