HSP3 ゲームのプログラミング | |
迷路・ゲーム制作 |
迷路はゲームのマップ(地図)など、利用範囲は広い。ここでは、迷路の作成と探索方法を学習して、最終的にはプレイヤーがキャラクタをゴールまで移動させるゲームを制作していく。
(1) 迷路作成(「棒倒し法」)
迷路を作成するアルゴリズムはいろいろとある。「棒倒し法」、「穴掘り法(道のばし法)」、「壁のばし法」などがある。(これらのキーワードで検索して調べてみよう。)
ここでは、「棒倒し法」で作成していくことにする。次に、作成手順を示す。
○ 棒倒し法
グラフ用紙のマス目に壁を書いていくようなイメージである。
1.外枠(壁)を描画する。
2.基準点(壁)を描画する。
1マス間隔で壁を配置する。したがって、外枠のサイズは「奇数」で設定する。3.1列目の基準点から壁をのばす。
基準点から「棒」を上下左右の一方に倒すように壁を配置する。4.2列目以降の基準点から壁をのばす。
2列目以降は「棒」を上下右の一方に倒すように配置する。
[注]左方向には棒を倒さない。
完成
○ プログラミング
マス目を使って迷路を作成していくので、二次元配列に壁と道のデータを格納することにすると考えやすい。座標は(x, y)と表すので、配列の添え字もそれに対応させて考える。
(0,0) (1,0) (2,0) (3,0) (4,0) (0,1) (1,1) (2,1) (3,1) (4,1) (0,2) (1,2) (2,2) (3,2) (4,2) (0,3) (1,3) (2,3) (3,3) (4,3)
座標(配列)を(x, y)と表すと、(x, y)を基準に上下左右の座標は計算によって表すことができる。
・(x, y)の上 … (x, y - 1)
・(x, y)の下 … (x, y + 1)
・(x, y)の左 … (x, - 1 y)
・(x, y)の右 … (x + 1, y)
(x - 1, y - 1) (x, y - 1) (x + 1, y - 1) (x - 1, y) (x, y) (x + 1, y) (x - 1, y + 1) (x, y + 1) (x + 1, y + 1)
(maze11.hsp)
迷路の外枠を描画する。迷路作成のプログラムはサブルーチンとして作成する。
1マスのサイズは8×8ドットとし、迷路全体のサイズは79×49マスとする。
ゲームでキャラクタを移動させるとき、描画と消去を繰り返す。このとき、毎回迷路を作成するのは時間のムダであるので、別のウィンドウに迷路を作成しておき、gcopy命令でコピーすることにする。
;maze11.hsp
#define bsize 8 ;ブロックサイズ(正方形)
#define bx 79 ;迷路のサイズ(マス目単位)
#define by 49
#define winx1 bx * bsize ;ウィンドウサイズ
#define winy1 by * bsize
dim maze, bx, by ;迷路データ 0:道、1:壁
randomize
buffer 1, winx1, winy1 ;迷路描画用
gosub *maze_make ;迷路作成
screen 0, winx1, winy1 ;メインウィンドウ
pos 0, 0 : gcopy 1, 0, 0, winx1, winy1 ;迷路画像コピー
stop
;迷路作成(棒倒し法) -----
*maze_make
;迷路初期化
repeat bx
xx = cnt
repeat by
maze(xx, cnt) = 0
loop
loop
;外枠作成
repeat bx ;上下枠
maze(cnt, 0) = 1
maze(cnt, by - 1) = 1
loop
repeat by ;左右枠
maze(0, cnt) = 1
maze(bx - 1, cnt) = 1
loop
;迷路描画
color 0, 0, 255
repeat bx
cnt1 = cnt
repeat by
if maze(cnt1, cnt) = 1 {
boxf cnt1 * bsize, cnt * bsize, cnt1 * bsize + bsize, cnt * bsize + bsize
}
loop
loop
return
外枠が青色で描画される。
迷路のデータは配列mazeに格納している。0が道で、1が壁である。
メインのウィンドウはID0であるから、迷路はウィンドウID1に描画して利用するときにID0にコピーするような方式にする。
外枠作成では、配列mazeに壁のデータ(1)を格納しているだけである。迷路描画で配列のデータが1(壁)のときだけ四角形を描画している。
迷路の大きさを変更する場合は、ブロックサイズと迷路サイズ(最初の3行)の値を変更するだけである。
(maze61.hsp)
基準点(壁)を描画する処理を追加する。
・壁を描画する座標はxが2, 4, 6, 8, …, 74, 76, 78、yが2, 4, 6, 8, … , 44, 46, 48である。repeat bx / 2 ;bxは79なので79/2=39.5であるが、bxは整数型なので29となる。x, yともに0から壁データを設定することになるが、何回設定しても不都合はない。
xx = cnt * 2 ;xx = 0, 2, 4, 6, 8, …, 74, 76, 78
repeat by / 2 ;上記と同じ
maze(xx, cnt * 2) = 壁データ ;cnt*2 = 0, 2, 4, 6, 8, … , 44, 46, 48
loop
loop
(maze12.hsp)
1列目の基準点から壁をのばす(棒を倒す)処理を追加する。
;maze12.hsp
<< 省略 >>
stop
;迷路作成(棒倒し法) -----
*maze_make
;迷路初期化
<< 省略 >>
;外枠作成
<< 省略 >>
;基準点作成
<< 省略 >>
;基準1列目の壁作成
xx = 2
repeat by / 2 - 1, 1
yy = cnt * 2 ;yy = 2, 4, 6, 8, … , 44, 46, 48
repeat
rr = rnd(4) ;0-3の乱数発生
if rr = 0 & maze(xx, yy - 1) = 0 { ;上
maze(xx, yy - 1) = 1
break
}
if rr = 1 & maze(xx, yy + 1) = 0 { ;下
maze(xx, yy + 1) = 1
break
}
if rr = 2 & maze(xx - 1, yy) = 0 { ;左
maze(xx - 1, yy) = 1
break
}
if rr = 3 & maze(xx + 1, yy) = 0 { ;右
maze(xx + 1, yy) = 1
break
}
loop
loop
;迷路描画
<< 省略 >>
return
基準点の座標は、前の課題のようにすれば繰り返しで作ることができる。ただし、1列目だけなのでxxは2で固定である。
棒を倒す方向は乱数で決定する。方向は上下左右の4方向なので、0〜3の乱数をrnd(4)で発生させ、if文で方向別に壁データを設定している。倒す方向に壁がある場合は方向を決定し直すようにするため、repeat命令で永久ループにしている。したがって、倒す方向に壁データを設定したとき、break命令で永久ループを抜け出す。
(maze62.hsp)
2列目以降の基準点から壁をのばす(棒を倒す)処理を追加する。
・サンプルの基準1列目の壁作成を利用して、xが4, 6, 8, …, 74, 76, 78と変わるようにループを追加する。また、左方向には壁を作らない(棒を倒さない)ので、その処理部分は削除する。
迷路・ゲーム制作 | |
2007 © Hiroshi Masuda |