0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Jasmine TeaAdvent Calendar 2023

Day 10

JasmineTea の手続き (`PROCEDURE`) を使ってみる

Last updated at Posted at 2023-12-09

これは Jasmine Tea アドベントカレンダー 2023 の 10 日目の記事です。

こんにちは、Jasmine Tea の開発に参加している石川です。この記事では Jasmine Tea の「手続き (PROCEDURE)」について説明します。

手続き(PROCEDURE) は複数の命令をひとまとまりにするための仕組みです。

プログラミングをしていると、プログラムが複雑になったり、似たプログラムが繰り返されてしまうことがあります。もし、複雑なプログラムをひとまとまりの命令のように書ければ、より分かりやすくする事ができます。同様に、繰り返されているプログラムもひとまとまりの命令のように書ければ、簡潔にすることができます。手続きをうまく使うことで、それらを実現できます。

PROCEDURE 命令と CALL 命令

次のプログラムは、クリックされたときや十字キーが押されたときにキャラクターを動かすというものです。

  • クリック時: その場所から右にキャラクターを動かす
  • 十字キー押下時: 中心からキーの方向にキャラクターを動かす

(動作確認はこちら)

sprite_number = 0

do
  tap x, y
  if x <> -1 and y <> -1 then
    sprite sprite_number, 0, sprite_number * 4 + 3
    show sprite_number, (x, y)
    direction sprite_number, 3
    distance sprite_number, 600
    speed sprite_number, 20
    move sprite_number
    sprite_number = (sprite_number + 1) % 13
  end if
  
  key$ = inkey$()
  if key$ = "ArrowLeft" then
    sprite sprite_number, 0, sprite_number * 4 + 2
    show sprite_number, (320, 200)
    direction sprite_number, 7
    distance sprite_number, 600
    speed sprite_number, 20
    move sprite_number
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowUp" then
    sprite sprite_number, 0, sprite_number * 4 + 1
    show sprite_number, (320, 200)
    direction sprite_number, 1
    distance sprite_number, 600
    speed sprite_number, 20
    move sprite_number
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowRight" then
    sprite sprite_number, 0, sprite_number * 4 + 3
    show sprite_number, (320, 200)
    direction sprite_number, 3
    distance sprite_number, 600
    speed sprite_number, 20
    move sprite_number
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowDown" then
    sprite sprite_number, 0, sprite_number * 4 + 0
    show sprite_number, (320, 200)
    direction sprite_number, 5
    distance sprite_number, 600
    speed sprite_number, 20
    move sprite_number
    sprite_number = (sprite_number + 1) % 13
  end if
loop

この sprite から move までの命令は「キャラクターを動かす」ことを意味しています。これを procedure を使ってひとまとまりにしてみましょう。まずは、tap でキャラクタを動かす部分を procedureend procedure でまとめ、それを call 命令で使うようにしてみましょう。(プログラムの全体はこちら)

procedure move_sprite
  sprite sprite_number, 0, sprite_number * 4 + 3
  show sprite_number, (x, y)
  direction sprite_number, 3
  distance sprite_number, 600
  speed sprite_number, 20
  move sprite_number
end procedure

sprite_number = 0

do
  tap x, y
  if x <> -1 and y <> -1 then
    call move_sprite
    sprite_number = (sprite_number + 1) % 13
  end if
  ...

実は、このプログラムはうまく動きません。procedure の中では、sprite_number, x, y という変数に値が代入されていないため、それらの変数を使うことができないからです。

screenshot procedure failed

procedure の外の値を使うためには、「引数」として手続きに渡してあげればよいです。引数は procedure move_sprite number, x, y のように定義します。(プログラムの全体はこちら)

procedure move_sprite number, x, y
  sprite number, 0, number * 4 + 3
  show number, (x, y)
  direction number, 3
  distance number, 600
  speed number, 20
  move number
end procedure

sprite_number = 0

do
  tap x, y
  if x <> -1 and y <> -1 then
    call move_sprite sprite_number, x, y
    sprite_number = (sprite_number + 1) % 13
  end if

このようにすることで、call 時点での sprite_numberxy の値を、move_sprite の中で numberxy として使うことができます。

手続きを他の場所でも使う

画面をクリックしたときのキャラクターの動かし方と、十字キーを押したときの画面の動かし方は少し違いますが、ほとんど同じです。違う部分は以下の 2 点です。

  • sprite sprite_number, 0, sprite_number * 4 + sdsd の部分
  • direction sprite_number, dd の部分

これら違う部分を引数として与えてあげれば、以下のプログラムのように、クリック用の手続きを十字キーに対しても流用できます。(動作確認はこちら)

procedure move_sprite number, x, y, sd, d
  sprite number, 0, number * 4 + sd
  show number, (x, y)
  direction number, d
  distance number, 600
  speed number, 20
  move number
end procedure

sprite_number = 0

do
  tap x, y
  if x <> -1 and y <> -1 then
    call move_sprite sprite_number, x, y, 3, 3
    sprite_number = (sprite_number + 1) % 13
  end if
  
  key$ = inkey$()
  if key$ = "ArrowLeft" then
    call move_sprite sprite_number, 320, 200, 2, 7
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowUp" then
    call move_sprite sprite_number, 320, 200, 1, 1
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowRight" then
    call move_sprite sprite_number, 320, 200, 3, 3
    sprite_number = (sprite_number + 1) % 13
  else if key$ = "ArrowDown" then
    call move_sprite sprite_number, 320, 200, 0, 5
    sprite_number = (sprite_number + 1) % 13
  end if
loop

手続き(PROCEDURE)を使うことで、プログラムを簡潔にすることができました。

次回は

Jasmine Tea には「手続き」と似た仕組みとして、「関数(FUNCTION)」があります。次回はそれを使ってみます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?