2.08.組み込み関数5

以下の追加の組み込み関数が存在します(ミサイルオブジェクト,砂シミュレート用オブジェクト,その他)。

戻り値のない関数は、式の中では使えません。


mismake() ミサイルを作成します。(戻り値なし)

mismove() ミサイルを動かします。(戻り値なし)

mistext() 文字列配列に文字でミサイルを描画します。(戻り値なし)

misfreeno() ミサイルの空番号を取得します。

dismis() ミサイルを削除します。(戻り値なし)


sandmake() 砂シミュレート用オブジェクトを生成します。(戻り値なし)

sandmove() すべての砂を移動します。(戻り値なし)

sanddraw() すべての砂を描画します。(戻り値なし)

dissand() 砂シミュレート用オブジェクトを削除します。(戻り値なし)


calcfractal() フラクタルの座標(x,y)の値を計算して返します。

drawshape() 決められたパターンの図形を表示します。(戻り値なし)


intstradd() 数値の文字列を加算して文字列で返します。数値は整数のみ対応です。

intstrsub() 数値の文字列を減算して文字列で返します。数値は整数のみ対応です。

intstrmul() 数値の文字列を乗算して文字列で返します。数値は整数のみ対応です。

intstrdiv() 数値の文字列を除算して文字列で返します。数値は整数のみ対応です。


vec3set() 3次元ベクトルの要素を設定します。(戻り値なし)

vec3copy() 3次元ベクトルをコピーします。(戻り値なし)

vec3add() 3次元ベクトルを加算します。(戻り値なし)

vec3sub() 3次元ベクトルを減算します。(戻り値なし)

vec3scale() 3次元ベクトルを定数倍します。(戻り値なし)

vec3dot() 3次元ベクトルの内積を計算して結果を返します。

vec3cross() 3次元ベクトルの外積を計算します。(戻り値なし)

vec3mag() 3次元ベクトルの大きさを計算して結果を返します。

vec3normalize() 3次元ベクトルを正規化します。(戻り値なし)


quemake() キューデータを作成します。(戻り値なし)

quepush() キューデータにデータを追加します。(戻り値なし)

quepop() キューデータから最新のデータを取り出します。

queshift() キューデータから最古のデータを取り出します。

queref() キューデータのデータを参照します。

queset() キューデータにデータを設定します。(戻り値なし)

quecount() キューデータに格納しているデータの数を返します。

disque() キューデータを削除します。(戻り値なし)


2.8.1.組み込み関数5の詳細


--

mismake(gno,no,useflag,x100,y100,degree,speed100,ch,min_x,max_x,min_y,max_y,div_x,div_y)


ミサイルグループ番号がgnoでミサイル番号がnoの

ミサイル(オブジェクト)を作成します。


useflag,x100,y100,degree,speed100,chには、数値ではなく変数名を指定する必要があります。

(プログラム中ではこれらの変数により、ミサイルの状態を参照または変更できます)

useflagには、有効なミサイルについては0以外を 無効なミサイルについては0を 格納した変数を指定します。

無効なミサイルについては、移動と表示は行われません。

x100には、座標x(単位:文字)の100倍の値を格納した変数を指定します。

y100には、座標y(単位:文字)の100倍の値を格納した変数を指定します。

degreeには、進行方向とx軸正方向の直線とのなす角度(0-360の値)を格納した変数を指定します。

speed100には、速度の100倍の値を格納した変数を指定します。

(100にすると、1回の移動につき1文字分移動する速さになります)

chには、ミサイルの表示文字列を格納した変数を指定します。


min_x,max_x,min_y,max_y,div_x,div_yは、数値でも変数でもOKです。

min_xには、xの最小値を指定します(100倍はしない)。

max_xには、xの最大値を指定します(100倍はしない)。

min_yには、yの最小値を指定します(100倍はしない)。

max_yには、yの最大値を指定します(100倍はしない)。

ミサイルの座標(x,y)が、最小値~最大値の範囲を超えて移動した場合には、

そのミサイルは、自動的に無効(useflag=0)になります。

div_xには、x方向の速度の倍率の逆数を指定します。

div_yには、y方向の速度の倍率の逆数を指定します。

例えば、div_yに2を指定すると、y方向の速度が半分になります。

ただし、この場合進行方向の角度も変わってくるので、角度を変えないためには、

degreeの計算時にy方向を2倍にして計算する等の工夫が必要です。

div_xに0を指定した場合は、1(等倍)を指定したことになります。

div_yに0を指定した場合は、1(等倍)を指定したことになります。


(v17.00から引数にgnoが追加になりました。このため、過去との互換性がなくなっています)


(戻り値なし)


例.

WAIT=30

setfont("T")

txtmake(bg1,0,25,"=",40)

for(i=0;i<8;i++){

useflag[i]=1

x[i]=20*100

y[i]=13*100

degree[i]=i*45

speed[i]=100

ch[i]="o"

mismake(0,i,useflag[i],x[i],y[i],degree[i],speed[i],ch[i],0,39,1,25,1,2)

}

for(i=0;i<20;i++){

cls()

copy(bg1,0,bg2,0,26)

mistext(bg2,0,25,0,0,7)

txtdraw(bg2,0,25,0,0)

mismove(0,0,7)

sleep(WAIT)

}


上の例では、(グループ番号0に属する)

8方向に進むミサイル0~7を作成しています。

そして、mistext()とtxtdraw()でミサイルを表示し、

mismove()でミサイルを動かしています。


(mistext()とtxtdraw()を使うかわりに、

画像を用意して drawimg()等でミサイルを表示することも もちろん可能です。

その場合は 表示する際に座標を100で割る必要があります)


--

ミサイル表示の拡張機能:

mismake()でミサイルを作成する際に、

ミサイルの表示文字列chを # $ % & のいずれかの文字(半角)で開始すると、

特殊フォーマットにより複数行のミサイルを mistext()で描画できます。

特殊フォーマットは、先頭の文字で区切り文字(# $ % &のいずれか)を指定し、

以後、以下の項目を区切り文字で区切って記述します。

(1)x座標のオフセット値

(2)y座標のオフセット値

(3)上書きモード(=0:上書き, =1:半角/全角スペース以外を上書き, =2:半角/全角スペースのみ上書き)

(4)1行目の表示文字列

(5)2行目の表示文字列

:

(x)n行目の表示文字列

例えば、上のプログラム例で、

ch[i]="o"

の行を、

ch[i]="#-1#-1#1# x #xox# x "

に書き換えます。

すると mistext()は、

(ミサイルの座標(x,y)からx方向に-1,y方向に-1ずらした位置に、上書きモード1で)

x

xox

x

のように3行分の描画を行います。


--

mismove(gno,min_no,max_no)

ミサイルを動かします。

ミサイルグループ番号がgnoでミサイル番号がmin_no~max_noの

ミサイルのうち、有効(useflagが0以外)なものの座標を、

速度および角度の分だけ進めます。

また、ミサイルの座標(x,y)が、最小値~最大値の範囲を超えた場合には、

そのミサイルは 自動的に無効(useflag=0)になります。

gnoは省略可能です。省略すると0を指定したことになります。

min_noとmax_noも省略可能です。省略するとgnoに属する全ミサイルが移動対象になります。


(v17.00から引数にgnoが追加になりました。このため、過去との互換性がなくなっています)


(戻り値なし)


--

mistext(a1,a2,a3,gno,min_no,max_no)

文字列配列に文字でミサイルを描画します。

文字列配列a1の添字a2~a3の要素内の

ミサイル座標(x,y)の位置に ミサイルの表示文字列を描画します。

ミサイルグループ番号がgnoでミサイル番号がmin_no~max_noの

ミサイルのうち、有効(useflagが0以外)で、

useflagが1000以下のものがすべて描画されます。

gnoは省略可能です。省略すると0を指定したことになります。

min_noとmax_noも省略可能です。省略するとgnoに属する全ミサイルが描画対象になります。


例えば、mistext(bg,0,3) は、

bg[0]="-----"

bg[1]="-----"

bg[2]="-----"

bg[3]="-----"

で、

(グループ番号0に属する)

ミサイル0の座標が(1,1)で表示文字列が"#"

ミサイル1の座標が(2,2)で表示文字列が"o"

であれば、

bg[0]="-----"

bg[1]="-#---"

bg[2]="--o--"

bg[3]="-----"

となります。


(v17.00から引数にgnoが追加になりました。このため、過去との互換性がなくなっています)


(戻り値なし)


--

misfreeno(gno,min_no,max_no)

ミサイルの空番号を取得します。

ミサイルグループ番号がgnoでミサイル番号がmin_no~max_noの

ミサイルのうち、無効(useflag=0)であるものを探して、

その番号を返します。

無効なミサイルが存在しなかった場合には -1 を返します。

(無効なミサイルが複数あった場合、必ずしも若番の番号が返るとは限りません)

gnoは省略可能です。省略すると0を指定したことになります。

min_noとmax_noも省略可能です。省略するとgnoに属する全ミサイルが検索対象になります。


(v17.00から引数にgnoが追加になりました。このため、過去との互換性がなくなっています)


--

dismis(gno)

ミサイルグループ番号がgnoであるミサイルをすべて削除します。


(v17.00からミサイル番号noではなくミサイルグループ番号gnoを指定するようになりました。

このため、過去との互換性がなくなっています)


(戻り値なし)



--

sandmake(no,x,y,w,h,r,c,th,bm)

番号noの砂シミュレート用オブジェクトを生成します。

noには複数の砂シミュレート用オブジェクトを識別するための番号を指定します。

そして、画面上のシミュレート領域をx,y,w,hで指定します。

(領域の左上点を(x,y)、幅をw(px)、高さをh(px)とします)

rには、砂の移動確率を配列変数で指定します。

r[0]が上方向,r[1]が下方向,r[2]が左方向,r[3]が右方向,r[4]が移動なしの確率になります。

これらを合計が1になるように格納してください。

(実際には、合計が1以外でも動作します)

cには砂の色を指定します。(RGB各8ビット、合計24ビットの数値で色を指定します)

thには同色と判定するしきい値(0-255)を指定します。

bmには砂が端を超えて移動するかどうかを指定します。

bmに0を指定すると、端を超えた砂の移動はしません。

bmに1を指定すると、上下のみ端を越えた場合に反対側の端に移動します。

bmに2を指定すると、左右のみ端を越えた場合に反対側の端に移動します。

bmに3を指定すると、上下左右の端を越えた場合に反対側の端に移動します。

bmは省略可能です。省略した場合には1を指定したことになります。


本命令を実行すると、画面上のシミュレート領域のグラフィックスを読み込み、

砂の色の表示部分から砂の情報テーブルを生成します。

また、その他の色の表示部分から障害物の情報テーブルを生成します。

そして、sandmove()により砂を移動し、sanddraw()により砂の表示を行います。


(v3.62から引数にnoが追加になりました。このため、過去との互換性がなくなっています)


(v14.07から移動確率を配列変数で指定するようになりました。

このため、過去との互換性がなくなっています)


(戻り値なし)


例.

WAIT=10

setscsize(240,240)

wd=width

ht=height

soft2("end")

col(red)

linewidth(2)

line(0,ht*3/4,wd/2,ht*7/8)

col(white)

arc(wd/4,ht/8,wd/2,wd/2)

'テーブル生成'

r[0]=0 // 上方向の移動確率

r[1]=0.8 // 下方向の移動確率

r[2]=0.1 // 右方向の移動確率

r[3]=0.1 // 左方向の移動確率

r[4]=0 // 移動なしの確率

sandmake(0, 0, 0, wd, ht, r, white, 10)

'描画'

while (scan!=262144) {

cls()

sandmove(0)

col(red)

linewidth(2)

line(0,ht*3/4,wd/2,ht*7/8)

col(white)

sanddraw(0)

sleep(WAIT)

}


--

sandmove(no)

sandmake()で作成した番号noの砂シミュレート用オブジェクトについて、

すべての砂を移動します。

(v3.62から引数にnoが追加になりました。このため、過去との互換性がなくなっています)

(戻り値なし)


--

sanddraw(no)

sandmake()で作成した番号noの砂シミュレート用オブジェクトについて、

すべての砂を表示します。

消去は行わないため、画面のクリア(cls()等)は別途行う必要があります。

(v3.62から引数にnoが追加になりました。このため、過去との互換性がなくなっています)

(戻り値なし)


--

dissand(no)

番号noの砂シミュレート用オブジェクトを削除します。

(本命令はv3.62で追加されました)

(戻り値なし)



--

calcfractal(x,y,dr,di,mr,mi,cr,ci,rep,norm2)

フラクタルの座標(x,y)の値を計算して返します。

計算のパラメータは、以下を指定します。

dr:x座標が1増えたときの 複素平面上での実部の増分

di:y座標が1増えたときの 複素平面上での虚部の増分

mr:x座標が0のときの 複素平面上での実部の値

mi:y座標が0のときの 複素平面上での虚部の値

cr:フラクタル計算時の 定数cの実部の値

ci:フラクタル計算時の 定数cの虚部の値

rep:フラクタル計算時の 最大繰り返し計算回数

(repを省略すると50を指定したことになります)

(repに1000以上の値を指定すると1000を指定したことになります)

norm2:フラクタル計算時の 計算を停止するしきい値の2乗

(norm2を省略すると4を指定したことになります)


計算自体は以下のように行います。

座標(x,y)に対応する複素平面上の値をzとすると、

z=z*z+c (cは定数)

の計算を、|z|の2乗がnorm2より大きくなるまで 繰り返します。

そして繰り返した回数-1または最大計算回数repを戻り値として返します。


例.

WAIT=10

SIZE=256

setscsize(SIZE,SIZE)

sleep(WAIT)

funccall(calcfrac1())

end

func calcfrac1() {

// 初期化

min_r=-0.4

min_i=0.2

max_r=-0.3

max_i=0.4

con_r=-0.02

con_i=-0.695

delta_r=0

delta_i=0

x=0

y=0

rep=0

color1=0

t1=tick

t2=0

@(colortbl,0,0x5F5F5F,0x7F,0xFF,0x7F0000,0xFF0000,0x7F007F,0xFF00FF,

0x7F00,0xFF00,0x7F7F,0xFFFF,0x7F7F00,0xFFFF00,0xAFAFAF,0xFFFFFF)

// 増分を事前に計算

delta_r = (max_r - min_r) / SIZE

delta_i = (max_i - min_i) / SIZE

// フラクタルの計算と表示

for (y=0; y<SIZE; y++) {

for (x=0; x<SIZE; x++) {

// 専用命令使用

rep = calcfractal(x,y,delta_r,delta_i,min_r,min_i,con_r,con_i,51,4)

col(colortbl[rep & 0xF])

point(x,y)

t2=tick-t1

if (t2>1000) { t1=tick sleep(WAIT) }

}

}

}


--

drawshape(mode,x,y,w,h,r1,r2,n)

drawshape(mode,x,y,w,h)

決められたパターンの図形を表示します。

modeによって図形のパターンと塗りつぶしの有無を指定します。

また、modeによって引数の数も変化します。

modeに指定可能な値は以下の通りです。


mode=0:正多角形を表示します(塗りつぶしあり)

mode=1:正多角形を表示します(塗りつぶしなし)

このとき引数は drawshape(mode,x,y,w,h,r1,r2,n) になります。

本モードでは、左上座標が(x,y)で幅w,高さhの領域に 正多角形を描画します。

r1には開始角、r2には加算角、nには頂点数を指定します。

例えば、

drawshape(0,0,0,100,100,0,120,3) とすると正三角形を塗りつぶして表示します。

drawshape(1,0,0,100,100,0,72,5) とすると正五角形の輪郭を表示します。

drawshape(0,0,0,100,100,0,144,5) とすると星形を塗りつぶして表示します。


mode=100:上から見た四角すいを表示します(塗りつぶしあり)

mode=101:上から見た四角すいを表示します(塗りつぶしなし)

このとき引数は drawshape(mode,x,y,w,h) になります。

本モードでは、左上座標が(x,y)で幅w,高さhの四角形を、

対角線で4つのエリアに区切って表示します。

塗りつぶしありのときは、各エリアを異なる明るさで塗りつぶすことで影を表現します。


(戻り値なし)



--

intstradd(a1,a2)

数値の文字列を加算して文字列で返します。

文字列a1,a2を数値に変換し、加算した結果を再び文字列に変換して返します。

数値は整数のみ対応です。数値の桁数は10000桁まで対応です。

計算結果が10000桁を超えた場合には"Infinity"または"-Infinity"という文字が返ります。


例. y=intstradd("100","200") を実行すると y="300" になります。


例. y=intstradd("100","-200") を実行すると y="-100" になります。


--

intstrsub(a1,a2)

数値の文字列を減算して文字列で返します。

文字列a1,a2を数値に変換し、減算した結果を再び文字列に変換して返します。

数値は整数のみ対応です。数値の桁数は10000桁まで対応です。

計算結果が10000桁を超えた場合には"Infinity"または"-Infinity"という文字が返ります。


例. y=intstrsub("100","200") を実行すると y="-100" になります。


例. y=intstrsub("100","-200") を実行すると y="300" になります。


--

intstrmul(a1,a2)

数値の文字列を乗算して文字列で返します。

文字列a1,a2を数値に変換し、乗算した結果を再び文字列に変換して返します。

数値は整数のみ対応です。数値の桁数は10000桁まで対応です。

計算結果が10000桁を超えた場合には"Infinity"または"-Infinity"という文字が返ります。


例. y=intstrmul("100","200") を実行すると y="20000" になります。


例. y=intstrmul("100","-200") を実行すると y="-20000" になります。


--

intstrdiv(a1,a2,a3)

数値の文字列を除算して文字列で返します。

文字列a1,a2を数値に変換し、除算した結果を再び文字列に変換して返します。

数値は整数のみ対応です。数値の桁数は10000桁まで対応です。

a2を"0"にすると、"NaN","Infinity","-Infinity"等の文字が返ります。

a3で戻り値の種類を指定します。

a3に0を指定すると、商を返します。

a3に1を指定すると、余りを返します。

a3に2を指定すると、商と余りをカンマで区切って返します。

a3は省略可能です。省略した場合には0を指定したことになります。


例. y=intstrdiv("10","3") を実行すると y="3" になります。


例. y=intstrdiv("10","-3") を実行すると y="-3" になります。


例. y=intstrdiv("10","3",1) を実行すると y="1" になります。

(第3引数を1にすると余りを返す)


例. y=intstrdiv("10","3",2) を実行すると y="3,1" になります。

(第3引数を2にすると商と余りをカンマ区切りで返す)



--

vec3set(v1,x,y,z)

3次元ベクトルv1の要素を設定します。

3次元ベクトルは、以下のように要素数3の配列になります。

v1[0]=x

v1[1]=y

v1[2]=z

(戻り値なし)


--

vec3copy(v1,v2)

3次元ベクトルv1をv2にコピーします。

(戻り値なし)


--

vec3add(v1,v2,v3)

3次元ベクトルv1とv2を加算し、結果をv3に格納します。

(戻り値なし)


--

vec3sub(v1,v2,v3)

3次元ベクトルv1からv2を減算し、結果をv3に格納します。

(戻り値なし)


--

vec3scale(v1,k,v2)

3次元ベクトルv1の各要素をk倍し、結果をv2に格納します。

(戻り値なし)


--

vec3dot(v1,v2)

3次元ベクトルv1とv2の内積を計算し、結果の値を返します。


--

vec3cross(v1,v2,v3)

3次元ベクトルv1とv2の外積を計算し、結果をv3に格納します。

(戻り値なし)


--

vec3mag(v1)

3次元ベクトルv1の大きさを計算し、結果の値を返します。


--

vec3normalize(v1)

3次元ベクトルv1を大きさ1に正規化します。

(戻り値なし)



--

quemake(no,size,init)

キュー番号がnoのキューデータを、作成します。

sizeには、キューデータのサイズ(格納可能なデータの数)を指定します。

initには、データの初期値を指定します。

(戻り値なし)


--

quepush(no,data)

キュー番号がnoのキューデータに、データを1個追加します。

dataには、追加するデータを指定します。

キューデータのサイズを超えて追加した場合、最古のデータが削除されます。

(戻り値なし)


--

quepop(no)

キュー番号がnoのキューデータから、最新のデータを取り出して返します。

取り出したデータは、キューデータから削除されます。

(スタックとしての使い方になります)

キューデータが空の場合には、quemake()で指定した初期値(init)が返ります。


--

queshift(no)

キュー番号がnoのキューデータから、最古のデータを取り出して返します。

取り出したデータは、キューデータから削除されます。

(キューとしての使い方になります)

キューデータが空の場合には、quemake()で指定した初期値(init)が返ります。


--

queref(no,index)

キュー番号がnoのキューデータの、データを参照して返します。

indexには、参照するデータの番号を指定します(最新データを0として数えます)。

indexに存在しないデータの番号を指定した場合には、

quemake()で指定した初期値(init)が返ります。


--

queset(no,index,data)

キュー番号がnoのキューデータに、データを設定します。

indexには、設定するデータの番号を指定します(最新データを0として数えます)。

dataには、設定するデータを指定します。

indexに存在しないデータの番号を指定した場合には、何もしません。

(戻り値なし)


--

quecount(no)

キュー番号がnoのキューデータに、格納しているデータの数を返します。


--

disque(no)

キュー番号がnoのキューデータを、削除します。

(戻り値なし)


(2018-5-10)