サンプルプログラム
迷路ゲーム
説明
迷路の中にある他のキャラクターに捕まらずに、すべてのドットを食べてください!
キーボードのカーソルキー、または行きたい方向に画面をタップすることで、男の子のキャラクターを動かすことができます。
Studioで試す
以下のリンクから Jasmine Tea でこのサンプルプログラムを Studio 画面で開いて実際に試すことができます。プログラムを実行したいときは、エディターの右下にある青色の「実行」ボタンを押してください。
プログラム
// 迷路の大きさ
MAZE_WIDTH=19
MAZE_HEIGHT=11
// メインループ
do
cls 3
// 迷路を描いて配列を得る
maze@=draw_maze@(MAZE_WIDTH,MAZE_HEIGHT)
// ドット総数
all_dots=calc_dot_count(MAZE_WIDTH,MAZE_HEIGHT,maze@)
// 主人公の表示
mx=1
my=1
call show_hero mx,my
// 敵の表示
ex@=[MAZE_WIDTH-2,MAZE_WIDTH-2]
ey@=[MAZE_HEIGHT-2,1]
es@=[random(1,12),random(1,12)]
call show_enemy ex@,ey@,es@,0
call show_enemy ex@,ey@,es@,1
// 敵2の方向
ed=-1
do
// 主人公の移動
mpos@=move_hero@(mx,my,MAZE_WIDTH,maze@)
mx=mpos@[0]
my=mpos@[1]
// 敵1の移動
epos@=move_enemy1@(mx,my,ex@[0],ey@[0],es@[0],MAZE_WIDTH,maze@)
ex@[0]=epos@[0]
ey@[0]=epos@[1]
es@[0]=epos@[2]
// 敵2の移動
epos@=move_enemy2@(ex@[1],ey@[1],es@[1],ed,MAZE_WIDTH,maze@)
ex@[1]=epos@[0]
ey@[1]=epos@[1]
es@[1]=epos@[2]
ed=epos@[3]
// クラッシュ判定
call is_crash es@
// ドット食べたか判定
if is_ate_dot(mx,my,MAZE_WIDTH,maze@) then
maze@[my*MAZE_WIDTH+mx]=2
box (mx*32+16,my*32+8)-(mx*32+31+16,my*31+32+8),0,0
all_dots=all_dots-1
end if
// 残りのドット数の表示
call print_remaining_dot_count all_dots
// クリア判定
if all_dots=0 then
call print_game_clear
exit do
end if
loop
loop
// ゲームクリア表示
procedure print_game_clear
locate 17,10
print "ゲームクリア"
pause 5000
end procedure
// 残りのドット数の表示
procedure print_remaining_dot_count all_dots
locate 1,23
print "のこりのドット:";all_dots;" ";
end procedure
// ドット判定
function is_ate_dot(x,y,width,maze@)
return maze@[y*width+x]=0
end function
// 当たり判定
procedure is_crash es@
if crash(0,es@[0]) or crash(0,es@[1]) then
locate 15,10
print "ゲームオーバー"
end
end if
end procedure
// 敵2の移動
function move_enemy2@(ex,ey,es,ed,width,maze@)
if not moving(es) then
if ed=-1 then
if can_move(ex,ey,width,5,maze@) then
epos@=move_enemy2_sprite@(ex,ey,5,es,ed)
else
if can_move(ex,ey,width,7,maze@) then
epos@=move_enemy2_sprite@(ex,ey,7,es,ed)
end if
end if
else
if ed=1 or ed=5 then
if random(0,1)=0 then
nd1=3
nd2=7
else
nd1=7
nd2=3
end if
if can_move(ex,ey,width,nd1,maze@) then
epos@=move_enemy2_sprite@(ex,ey,nd1,es,ed)
else
if can_move(ex,ey,width,nd2,maze@) then
epos@=move_enemy2_sprite@(ex,ey,nd2,es,ed)
else
if ed=1 then
if can_move(ex,ey,width,1,maze@) then
epos@=move_enemy2_sprite@(ex,ey,1,es,ed)
else
epos@=move_enemy2_sprite@(ex,ey,5,es,ed)
end if
else
if can_move(ex,ey,width,5,maze@) then
epos@=move_enemy2_sprite@(ex,ey,5,es,ed)
else
epos@=move_enemy2_sprite@(ex,ey,1,es,ed)
end if
end if
end if
end if
else
if random(0,1)=0 then
nd1=1
nd2=5
else
nd1=5
nd2=1
end if
if can_move(ex,ey,width,nd1,maze@) then
epos@=move_enemy2_sprite@(ex,ey,nd1,es,ed)
else
if can_move(ex,ey,width,nd2,maze@) then
epos@=move_enemy2_sprite@(ex,ey,nd2,es,ed)
else
if ed=3 then
if can_move(ex,ey,width,3,maze@) then
epos@=move_enemy2_sprite@(ex,ey,3,es,ed)
else
epos@=move_enemy2_sprite@(ex,ey,7,es,ed)
end if
else
if can_move(ex,ey,width,7,maze@) then
epos@=move_enemy2_sprite@(ex,ey,7,es,ed)
else
epos@=move_enemy2_sprite@(ex,ey,3,es,ed)
end if
end if
end if
end if
end if
end if
ex=epos@[0]
ey=epos@[1]
ed=epos@[2]
end if
return [ex,ey,es,ed]
end function
// 敵2のスプライトの移動
function move_enemy2_sprite@(ex,ey,d,es,ed)
direction es,d
if d=5 then
ey=ey+1
end if
if d=7 then
ex=ex-1
end if
if d=3 then
ex=ex+1
end if
if d=1 then
ey=ey-1
end if
ed=d
move es
return [ex,ey,ed]
end function
// 敵1の移動
function move_enemy1@(mx,my,ex,ey,es,width,maze@)
if not moving(es) then
tdir=decide_enemy1_direction(mx,my,ex,ey,width,maze@)
direction es,tdir
if tdir=1 then
ey=ey-1
end if
if tdir=3 then
ex=ex+1
end if
if tdir=5 then
ey=ey+1
end if
if tdir=7 then
ex=ex-1
end if
move es
end if
return [ex,ey,es]
end function
// 敵機1の移動方向の決定
function decide_enemy1_direction(mx,my,ex,ey,width,maze@)
tdist=100
if can_move(ex,ey,width,1,maze@) then
dist=calc_hero_enemy_distance(mx,my,ex,ey-1)
if dist<tdist then
tdist=dist
tdir=1
end if
end if
if can_move(ex,ey,width,3,maze@) then
dist=calc_hero_enemy_distance(mx,my,ex+1,ey)
if dist<tdist then
tdist=dist
tdir=3
end if
end if
if can_move(ex,ey,width,5,maze@) then
dist=calc_hero_enemy_distance(mx,my,ex,ey+1)
if dist<tdist then
tdist=dist
tdir=5
end if
end if
if can_move(ex,ey,width,7,maze@) then
dist=calc_hero_enemy_distance(mx,my,ex-1,ey)
if dist<tdist then
tdist=dist
tdir=7
end if
end if
return tdir
end function
// 自機と敵の距離を計算
function calc_hero_enemy_distance(mx,my,ex,ey)
return sqr(pow(abs(mx-ex),2)+pow(abs(my-ey),2))
end function
// 主人公の移動
function move_hero@(mx,my,width,maze@)
if not moving(0) then
d=decide_hero_direction()
if can_move(mx,my,width,d,maze@) then
mpos@=move_hero_sprite@(d,mx,my)
mx=mpos@[0]
my=mpos@[1]
end if
end if
return [mx,my]
end function
// 主人公のスプライトを移動
function move_hero_sprite@(d,mx,my)
if d=5 then
my=my+1
end if
if d=1 then
my=my-1
end if
if d=3 then
mx=mx+1
end if
if d=7 then
mx=mx-1
end if
direction 0,d
move 0
return [mx,my]
end function
// 主人公の移動方向を決定
function decide_hero_direction()
d=0
k$=inkey$()
tap tx,ty
if k$<>"" then
if k$="ArrowDown" then
d=5
else if k$="ArrowUp" then
d=1
else if k$="ArrowRight" then
d=3
else if k$="ArrowLeft" then
d=7
end if
else
if tx<>-1 then
if xpos(0)<tx and tx<xpos(0)+31 then
if ty<(ypos(0)+16) then
d=1
else if (ypos(0)+16)<ty then
d=5
end if
else
if ypos(0)<ty and ty<ypos(0)+31 then
if tx<(xpos(0)+16) then
d=7
else if (xpos(0)+16)<tx then
d=3
end if
end if
end if
end if
end if
return d
end function
// 指定位置から指定方向に移動できるか
function can_move(x,y,width,d,maze@)
if d=5 then
return maze@[(y+1)*width+x]<>1
else if d=1 then
return maze@[(y-1)*width+x]<>1
else if d=3 then
return maze@[y*width+(x+1)]<>1
else if d=7 then
return maze@[y*width+(x-1)]<>1
else
return 0
end if
end function
// 敵の表示
procedure show_enemy ex@,ey@,es@,no
distance es@[no],32
speed es@[no],13
show es@[no],(16+ex@[no]*32,8+ey@[no]*32-1)
end procedure
// 主人公の表示
procedure show_hero x,y
distance 0,32
speed 0,18
show 0,(16+x*32,8+y*32-1)
end procedure
// ドット数の計算
function calc_dot_count(width,height,maze@)
dot_count=0
for y=0 to height-1
for x=0 to width-1
if maze@[y*width+x]<>1 then
if maze@[(y-1)*width+x]=0 or maze@[(y+1)*width+x]=0 or maze@[y*width+(x+1)]=0 or maze@[y*width+(x-1)]=0 then
dot_count=dot_count+1
end if
end if
next
next
return dot_count
end function
// 迷路の描画
function draw_maze@(width,height)
maze@=[]
for y=0 to height-1
for x=0 to width-1
maze@[y*width+x]=0
if y=0 or y=height-1 or x=0 or x=width-1 then
maze@[y*width+x]=1
end if
if x%2=0 and y%2=0 then
maze@[y*width+x]=1
if x<>0 and x<>width-1 and y<>0 and y<>height-1 then
r=random(0,3)
if r=0 then
maze@[(y-1)*width+x]=1
else if r=1 then
maze@[y*width+(x+1)]=1
else if r=2 then
maze@[(y+1)*width+x]=1
else if r=3 then
maze@[y*width+(x-1)]=1
end if
end if
end if
next
next
wall=random(440,481)
render 0
for y=0 to height-1
for x=0 to width-1
if maze@[y*width+x]=1 then
put (x*32+16,y*32+8),wall
put (x*32+16+16,y*32+8),wall
put (x*32+16,y*32+16+8),wall
put (x*32+16+16,y*32+16+8),wall
else
if maze@[(y-1)*width+x]=0 or maze@[(y+1)*width+x]=0 or maze@[y*width+(x+1)]=0 or maze@[y*width+(x-1)]=0 then
put (x*32+16+8,y*32+8+8),random(367,370)
end if
end if
next
next
render 1
return maze@
end function
解説
ゲームのメインループは、6行目から56行目です。メインループでは、以下の処理を順番に行っています。各処理は、プロシージャまたは関数として作成されています。
迷路の情報は、maze@ 配列が持っています。maze@ 配列の各要素は、以下のいずれかの値が代入されています。
2つの敵は、それぞれ移動の処理に特徴があります。