自作でちょっとしたものを作ろうと思うと、
関数とか、モジュール的なものを使いたくなるのですが
モジュールの中では、変数は流用されているのかなと思ってテストしてみました。
-----
goto *Main
#module myMod
; 値の初期設定
#defcfunc local setValue int nValue
a = nValue
return a
; 足し算
#defcfunc local addValue int nValue
a = a + nValue
return a
#global
*Main
ret = setValue@myMod(10)
mes "return:" + ret
ret = addValue@myMod(5)
mes "return:" + ret
mes "a:" + a
stop
-----
この結果は、
return:10
return:15
a:0
となりました。
つまり、どこで定義した変数も、クラス内のメンバ変数のような扱いということのようです。
生き続けて、他の関数からも見える。(addValue())
もちろん、外からは見えない。(最後のa)
ずいぶんお久しぶりです。
特に何があったというわけではありませんが
なんとなく遠ざかっておりました。
やりたいときがベストタイミングってことで
ふとやってみました。
自分で作った関数定義です。
-----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
; 足し算関数
#defcfunc myAdd int a, int b
return a+b
; 引き算関数
#defcfunc mySub int a, int b
return a-b
; メイン関数
*MainProgram
ansAdd = myAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = mySub( 40, 30 )
mes "40-30=" + ansSub
stop
----
前回、少しびびっていましたが、たいしたことはない感じ。
あえて言えば、プロトタイプ宣言したい感じ。
あと気をつけなくちゃいけないことが、変数のすべてがグローバル変数的な扱いになる。
つまり、myAdd()内で定義した変数を、mySub()で参照・変更が可能ということ。
これは危ないねってことで、モジュール化して固めるらしいです。
あ、あと、ラベルの重複防止も兼ねて。
それがこんな感じ。
-----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
#module
; 足し算関数
#defcfunc myAdd int a, int b
return a+b
#global
#module
; 引き算関数
#defcfunc mySub int a, int b
return a-b
#global
; メイン関数
*MainProgram
ansAdd = myAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = mySub( 40, 30 )
mes "40-30=" + ansSub
stop
----
変更点
・#module
~
#global
で囲みました。
こうすると、関数名以外は同じ変数名・ラベルを使ってもいい。
さらに関数名もかぶるよ!という場合は、モジュールに名前も付けられます。
----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
#module myModAdd
; 足し算関数
#defcfunc local myCalc int a, int b
return a+b
#global
#module myModSub
; 引き算関数
#defcfunc local myCalc int a, int b
return a-b
#global
; メイン関数
*MainProgram
ansAdd = myCalc@myModAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = myCalc@myModSub( 40, 30 )
mes "40-30=" + ansSub
stop
----
変更点
・#moduleの後ろに名前をつけました。
・関数名を2つ同じにしました。
・関数名の前にlocalをつけました。
localは・・・よくわからないから今のところはお決まりの呪文だと覚えておくことにします。
特に何があったというわけではありませんが
なんとなく遠ざかっておりました。

やりたいときがベストタイミングってことで
ふとやってみました。
自分で作った関数定義です。
-----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
; 足し算関数
#defcfunc myAdd int a, int b
return a+b
; 引き算関数
#defcfunc mySub int a, int b
return a-b
; メイン関数
*MainProgram
ansAdd = myAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = mySub( 40, 30 )
mes "40-30=" + ansSub
stop
----
前回、少しびびっていましたが、たいしたことはない感じ。
あえて言えば、プロトタイプ宣言したい感じ。
あと気をつけなくちゃいけないことが、変数のすべてがグローバル変数的な扱いになる。
つまり、myAdd()内で定義した変数を、mySub()で参照・変更が可能ということ。
これは危ないねってことで、モジュール化して固めるらしいです。
あ、あと、ラベルの重複防止も兼ねて。
それがこんな感じ。
-----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
#module
; 足し算関数
#defcfunc myAdd int a, int b
return a+b
#global
#module
; 引き算関数
#defcfunc mySub int a, int b
return a-b
#global
; メイン関数
*MainProgram
ansAdd = myAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = mySub( 40, 30 )
mes "40-30=" + ansSub
stop
----
変更点
・#module
~
#global
で囲みました。
こうすると、関数名以外は同じ変数名・ラベルを使ってもいい。
さらに関数名もかぶるよ!という場合は、モジュールに名前も付けられます。
----
; 自作関数(正式にはユーザ定義関数)
goto *MainProgram
#module myModAdd
; 足し算関数
#defcfunc local myCalc int a, int b
return a+b
#global
#module myModSub
; 引き算関数
#defcfunc local myCalc int a, int b
return a-b
#global
; メイン関数
*MainProgram
ansAdd = myCalc@myModAdd( 10, 20 )
mes "10+20=" + ansAdd
ansSub = myCalc@myModSub( 40, 30 )
mes "40-30=" + ansSub
stop
----
変更点
・#moduleの後ろに名前をつけました。
・関数名を2つ同じにしました。
・関数名の前にlocalをつけました。
localは・・・よくわからないから今のところはお決まりの呪文だと覚えておくことにします。

ちょっと触っていなかったので復習も兼ねて、
簡単そうなプログラムを作ってみました。
「カーソルが乗ると、色が変る」
でもこれじゃさすがに簡単そうだったので
「カーソルが乗ると、じわっと色が変る」
にしてみました。
もちろん、離れるときもじわっと戻ります。
------
; タイルのマス目上にマウスカーソルがあると、そのタイルがじわっと光る
screen 0, 400, 300
nTileSize = 50
; タイルの色
; 暗い色
dim naBlack, 3
naBlack = 0, 0, 50
; 明るい色
dim naWhite, 3
naWhite = 255, 255, 0
; じわっと光るステップ数(ステータスの値に使用する)
nShineStep = 100
; 全タイルに、光状態のステータスを持たせる[ 0 ~ nShineStep ]
nTileNum_x = int( ginfo_sx / nTileSize )
nTileNum_y = int( ginfo_sy / nTileSize )
dim naShineStatus, nTileNum_x, nTileNum_y
for i, 0, nTileNum_x, 1
for j, 0, nTileNum_y, 1
naShineStatus(i,j) = 0
next
next
; 関数の使い方がよくわからないため使用するグローバル変数
; DrawOneTile()で使用
; タイルのx方向index
gnX = 0
; タイルのy方向index
gnY = 0
; 光らせる度合い(最大nShineStep)
gnShine = 0
; メイン処理
*DrawMain
redraw 0
; タイルを描く
gosub *DrawTile
redraw 1
await 5
goto *DrawMain
stop
; タイルを描く
*DrawTile
nTileNum_x = int( ginfo_sx / nTileSize )
nTileNum_y = int( ginfo_sy / nTileSize )
; マウスがあるタイルを調べる
mouse_i = int( mousex / nTileSize )
mouse_j = int( mousey / nTileSize )
for i, 0, nTileNum_x, 1
for j, 0, nTileNum_y, 1
; マウスがある場合は光らせる
if( (i=mouse_i) and (j=mouse_j) ){
if( naShineStatus(i,j) < nShineStep ){ // 最大に光っていないタイルのみ
naShineStatus(i,j) = naShineStatus(i,j) + 3 // 光るのは暗くするより早く
// ※最後、少しmaxを超えるけど気にしない
}
}else{
; マウスがない場合は暗くさせる
if( naShineStatus(i,j) > 0 ){ // もともと明るいタイルのみ
naShineStatus(i,j) = naShineStatus(i,j) - 1
}
}
; 描画
gnX = i
gnY = j
gnShine = naShineStatus(i,j)
gosub *DrawOneTile
next
next
return
; 指示があったタイルを1つだけ描く
; ※ 関数の使い方がよくわからないので、ひとまずグローバル変数で。。(恥
; よくわからない点メモ
; ・moduleを定義しないといけないのか?
; ・変数は基本的にローカル変数なのか?
; ・グローバル変数も使いたいときはどう記述するか?
; 引数
; gnX:タイルのx方向index
; gnY:タイルのy方向index
; gnShine:光らせる度合い(最大nShineStep)
*DrawOneTile
; 色の計算
if( gnShine<=0 ){
nR = naBlack(0)
nG = naBlack(1)
nB = naBlack(2)
}else:if( gnShine>=nShineStep ){
nR = naWhite(0)
nG = naWhite(1)
nB = naWhite(2)
}else{
nR = naBlack(0) + int( (gnShine*(naWhite(0) - naBlack(0)))/nShineStep )
nG = naBlack(1) + int( (gnShine*(naWhite(1) - naBlack(1)))/nShineStep )
nB = naBlack(2) + int( (gnShine*(naWhite(2) - naBlack(2)))/nShineStep )
}
; 背景
color nR, nG, nB
boxf i*nTileSize, j*nTileSize, (i+1)*nTileSize, (j+1)*nTileSize
; 上のふち
color 0, 0, 0
line gnX*nTileSize, gnY*nTileSize, (gnX+1)*nTileSize, gnY*nTileSize
; 左のふち
line gnX*nTileSize, gnY*nTileSize, gnX*nTileSize, (gnY+1)*nTileSize
return
----------
アルゴリズムの問題なので、
HSP的に、特に難しい技術は使っていません。
長いけど、読めばわかるという感じ。
すべてのタイルごとにステータスを持って、
マウスカーソルの位置を見て、それを変えて、
それを元に色を決定する
というロジックです。
以前やったかもしれないけども、
内部関数の使い方がわからなかったので使いませんでした
じゃ、それは次の課題かなぁ。
簡単そうなプログラムを作ってみました。

「カーソルが乗ると、色が変る」
でもこれじゃさすがに簡単そうだったので
「カーソルが乗ると、じわっと色が変る」
にしてみました。
もちろん、離れるときもじわっと戻ります。
------
; タイルのマス目上にマウスカーソルがあると、そのタイルがじわっと光る
screen 0, 400, 300
nTileSize = 50
; タイルの色
; 暗い色
dim naBlack, 3
naBlack = 0, 0, 50
; 明るい色
dim naWhite, 3
naWhite = 255, 255, 0
; じわっと光るステップ数(ステータスの値に使用する)
nShineStep = 100
; 全タイルに、光状態のステータスを持たせる[ 0 ~ nShineStep ]
nTileNum_x = int( ginfo_sx / nTileSize )
nTileNum_y = int( ginfo_sy / nTileSize )
dim naShineStatus, nTileNum_x, nTileNum_y
for i, 0, nTileNum_x, 1
for j, 0, nTileNum_y, 1
naShineStatus(i,j) = 0
next
next
; 関数の使い方がよくわからないため使用するグローバル変数
; DrawOneTile()で使用
; タイルのx方向index
gnX = 0
; タイルのy方向index
gnY = 0
; 光らせる度合い(最大nShineStep)
gnShine = 0
; メイン処理
*DrawMain
redraw 0
; タイルを描く
gosub *DrawTile
redraw 1
await 5
goto *DrawMain
stop
; タイルを描く
*DrawTile
nTileNum_x = int( ginfo_sx / nTileSize )
nTileNum_y = int( ginfo_sy / nTileSize )
; マウスがあるタイルを調べる
mouse_i = int( mousex / nTileSize )
mouse_j = int( mousey / nTileSize )
for i, 0, nTileNum_x, 1
for j, 0, nTileNum_y, 1
; マウスがある場合は光らせる
if( (i=mouse_i) and (j=mouse_j) ){
if( naShineStatus(i,j) < nShineStep ){ // 最大に光っていないタイルのみ
naShineStatus(i,j) = naShineStatus(i,j) + 3 // 光るのは暗くするより早く
// ※最後、少しmaxを超えるけど気にしない
}
}else{
; マウスがない場合は暗くさせる
if( naShineStatus(i,j) > 0 ){ // もともと明るいタイルのみ
naShineStatus(i,j) = naShineStatus(i,j) - 1
}
}
; 描画
gnX = i
gnY = j
gnShine = naShineStatus(i,j)
gosub *DrawOneTile
next
next
return
; 指示があったタイルを1つだけ描く
; ※ 関数の使い方がよくわからないので、ひとまずグローバル変数で。。(恥
; よくわからない点メモ
; ・moduleを定義しないといけないのか?
; ・変数は基本的にローカル変数なのか?
; ・グローバル変数も使いたいときはどう記述するか?
; 引数
; gnX:タイルのx方向index
; gnY:タイルのy方向index
; gnShine:光らせる度合い(最大nShineStep)
*DrawOneTile
; 色の計算
if( gnShine<=0 ){
nR = naBlack(0)
nG = naBlack(1)
nB = naBlack(2)
}else:if( gnShine>=nShineStep ){
nR = naWhite(0)
nG = naWhite(1)
nB = naWhite(2)
}else{
nR = naBlack(0) + int( (gnShine*(naWhite(0) - naBlack(0)))/nShineStep )
nG = naBlack(1) + int( (gnShine*(naWhite(1) - naBlack(1)))/nShineStep )
nB = naBlack(2) + int( (gnShine*(naWhite(2) - naBlack(2)))/nShineStep )
}
; 背景
color nR, nG, nB
boxf i*nTileSize, j*nTileSize, (i+1)*nTileSize, (j+1)*nTileSize
; 上のふち
color 0, 0, 0
line gnX*nTileSize, gnY*nTileSize, (gnX+1)*nTileSize, gnY*nTileSize
; 左のふち
line gnX*nTileSize, gnY*nTileSize, gnX*nTileSize, (gnY+1)*nTileSize
return
----------
アルゴリズムの問題なので、
HSP的に、特に難しい技術は使っていません。
長いけど、読めばわかるという感じ。
すべてのタイルごとにステータスを持って、
マウスカーソルの位置を見て、それを変えて、
それを元に色を決定する
というロジックです。
以前やったかもしれないけども、
内部関数の使い方がわからなかったので使いませんでした

じゃ、それは次の課題かなぁ。