ゲーム開発講座
Chapter1-4
-キャラクターを動かしてみようだよの巻-
 
 
-はじめに- 
 
こんにちわ皆さん 
もしくはこんばんわ皆さん 
ゲーム開発講座の時間だぜ
おっはー 
皆、今日も頑張りまショイ! 
んで、今日はなにすんの?
そうだな。 
やっぱりゲームっていったらキャラクターを動かしたりしたいよな。 
難しい事はしないけどキー入力の方法やキャラクターの綺麗なアニメーションをしようか。
あいあいさー
んじゃ、今回の素材だよ。 
サンプルダウンロード 
haikei2_01.bmpとpoti2_01.bmpは1-2の再録だから 
同じフォルダで作業するなら上書きしてもいいよ。
絵の滑らかな表示方法とその応用
さて、グラフィックを軽く表示する方法といこうか。
あれ? 
gcopyはもうやったろ? 
picloadで一々ロードするより何十倍も早い方法じゃないか。
うん、そうなんだけどね。 
あれだけじゃちょっと遅いんだ。 
それに画面に絵を表示させたときちらつきが出る。 
前回のRPGのサンプルやったとき、コマンドを選択する毎に 
画面が一瞬チラっと点滅してたのは気づいたかい?
動体視力が犬並みの私が気づかないはずないさ! 
たしかにちらちらしてたね。
もしあの方法でシューティングゲームなんて作ろうとしたら 
画面のいたるところで点滅しまくって目がやられちゃう上に 
凄く処理が重くなる。 
なぜあんな事になるかと言うと、gcopyで普通に画面をコピーすると 
画面をコピーする→コピーしたものを表示させる 
という処理が成される。 
このコピーしたものを表示させるという処理が結構重く、 
何度もそれをするとちらつきが出る。
んじゃ、どうすればいいの?
HSPにはコピーしたものを表示させないようにする命令があるんだ。 
それが 
redraw p1 
p1を0にすると画面の描画をOFFにし、 
1にすると画面を描画する事が出来るんだ。 
んじゃ、サンプルで比較してみようか。 
	;redrawを使わないで表示してみる。
	buffer 2:picload "haikei2_01.bmp"
	buffer 3:picload "poti2_01.bmp"
	gsel 0
	gmode 2
	repeat
	gcopy 2,0,0,640,480
	gcopy 3,0,0,300,480
	await 0
	loop
どうだ? 
えらいことになてるだろ。
うわぁ、ちかちかしてるー! 
これは酷い。
だろ? 
今度はどうだい? 
	;redrawを使ってみる。
	buffer 2:picload "haikei2_01.bmp"
	buffer 3:picload "poti2_01.bmp"
	gsel 0
	gmode 2
	repeat
	redraw 0
	gcopy 2,0,0,640,480
	gcopy 3,0,0,300,480
	await 0
	redraw 1
	loop
問題ないだろ? 
今度は速度を見てみようか。 
repeatの回数を100にして両方を比べてみてくれ。 
プログラム終了時間に差が出ただろう。 
redrawは今後ゲームを作るときには無くてはならないものと思ってくれ。
なるほど、かなり差が出るね。
あとこの命令は画面のエフェクト効果を出す時にも結構使えたりするぞ。 
redraw p1,p2,p3,p4 
画面描画のON、OFFはその効果を部分的にする事ができる。 
p2,p3に左上の座標、そしてp4,p5に実行するサイズを入れる事が出来る。 
まずredraw 0を行い画面全体の描画をOFFにした後、画面をコピーし、 
部分的に表示していくと効果のかかった表示方法が出来る。 
簡単な方法だとこんな感じだな。 
	buffer 2:picload "haikei2_01.bmp"
	buffer 3:picload "poti2_01.bmp"
	gsel 0
	gmode 2
	redraw 0		;まず画面描画をOFFにする
	gcopy 2,0,0,640,480	;画面コピーを行う
	gcopy 3,0,0,300,480

	repeat 16
	repeat 40
	redraw 1,cnt*16+x,0,1,480	;横1ドット縦480ドットを部分的に描画
	loop
	wait 1
	x+
	loop
	stop
表示方法が効果的になっただろ?
おお凄い! 
凄いけどどういう原理でこういう風に出来ているのか判らない! 
cntっていう変数があるけどこれどういうのなの?
cntというのはrepeatでループした回数が勝手に入る変数なんだ。 
repeatの中にrepeatを作るとcntの中身は後者のループ回数が入り、 
loopを抜けないと前者の数字が入らないから注意してくれ。 

まずソースの12行目、 
redraw 1,cnt*16+x,0,1,480 
ってのがあるよな? 
これは座標cnt*16+x,0の位置から1,480の一本の棒状に画像を描画するという命令になる。 
cntの中身が0、xの中身が0の場合、座標0,0の位置から1,480サイズの画面描画がなされる。 
ループしているから勿論、cntの中身は+1されていき、1ループするとcntの中身が1になり 
xの中身が0なので 
cnt*16+xの式は1*16+0になり 
座標16,0の位置から1,480サイズの画面描画される。 
つまりループするごとに16ドットづつ距離をおいて1本の棒状に描画されていくんだ。 

ループは40回されると抜け、15行目で変数xは+1され、またループされる。 
すると今度はcntの中身0、xは1になるから式は 
0*16+1で座標は1,0になる、cntが+1されると 
1*16+1で17,0、 
コレを繰り返すことによって画面がじょじょに表示されていくんだ。

お、奥深い。 
確かに前にいった通り算数の計算だけど、その計算式を自分で編み出す事が重用なんだね。 
じゃあ一つ考えてみようか・・・こうだ! 
	buffer 2:picload "haikei2_01.bmp"
	buffer 3:picload "poti2_01.bmp"
	gsel 0
	gmode 2
	redraw 0		;まず画面描画をOFFにする
	gcopy 2,0,0,640,480	;画面コピーを行う
	gcopy 3,0,0,300,480

	repeat 240
	redraw 1,0,cnt*2,640,1		;1ドットづつ間隔をあけて描画
	wait 1
	loop
	repeat 240
	redraw 1,0,cnt*2+1,640,1	;さっきの式に+1する
	wait 1
	loop
	stop
1ドットづつ間隔をあけて表示して次にその隙間を埋めて行ったんだ。
よし良いぞポチ! 
ディモールト良し! 
んじゃ、次いってみるか。
沢山のキャラクターを同時にアニメーションさせる
じゃあさっきのを応用してキャラクターのアニメーションをやってみようか。
アニメーションなら作ったことあるよ。 
こういうgifアニメなんだけどね。 
 
gifアニメを作るソフトに絵を登録していったら 
順番に絵がぱらぱら漫画の方式で動いてくれるんだ。
ちくワかよ。 
HSPも似たようなもんでまぁキャラクターのアニメーションはパラパラアニメだ。 
3Dになると四肢を動かすプログラムだとかそういうのになるんだけど 
2Dのは古来よりパラパラアニメなんだ。
んじゃあ、gifファイルをロードしたらキャラクターが動いてくれるってこと?
そーじゃないんだなコレが。 
hsp3.x系だとgifはロードできるけど2.6じゃ出来ない。 
最近までgifは著作権問題で扱いが難しかったんだ。 
使用するのも作るのもgifを開発した所の著作権が関わってきてたんだけど 
最近問題なくなったんで3.x系でロードできるようになったんだ。 

とまぁ、それはいいとして。 
2.6じゃロードできないし3.0でもロードしても最初の1コマ目の絵しか表示されない。 
アニメーションを勝手にしてくれないんだ。

うぇー。 
んじゃ、どうするの? 
アニメーションを登録していくプログラムがあると見た! 
私って偉いねぇ!
ねぇよ。 
いや、無いことは無いしそのうちやるけど 
基本命令文には無い。
なん・・・だと!?
ポチ、お前はすでにアニメーションを作る方法を知ってるんだぜ。 
すでに知っている命令だけでアニメーションを作る事が出来る。
はははご冗談を。 
嘘をつく奴は誰だ、お前だ!
(ああ、ポチが駄目な子に) 
絵を指定した位置だけを表示する方法はやったよな? 
アレを使ったら作れると思わないか? 
な?
うーん? 
あ、そうだな、ちょっとまって。 
何か思いつきそうな、今のどの所辺りまで来てる・・・。 
はっ! 
まったくわからんわい!
だめだこいつ・・・早くなんとかしないと。 
サンプルの中にこんな画像ファイルあるよな? 
(animedot.bmp) 
 
 
うんあるね。 
なんか似た絵が並んでる。
これはパラパラ漫画みたいに作ったもので 
連続的に表示させると歩いてるアニメーションになる。 
ちょっと時間無かったから絵が適当だけどな。 
ポチ自体適当なキャラだからまぁいいか!
な、なんだってー!? 
適当とか言うな!
この絵は全部同じ間隔で描かれていて1つのコマにつき 
64x70のサイズで作られてるんだ。 
ゲームを作るときアニメーションさせるドット絵は常に同じサイズにしておくと 
非常に作りやすいから覚えといてくれ。 
じゃあ一番簡単な方法でアニメーションを作ってみるか。 
	buffer 2:picload "animedot.bmp"
	gsel 0
	repeat
		repeat 8
			redraw 0
			gcopy 2,cnt*64,70,64,70		;ループするごとにコピー元の位置を64ドットずらす
			redraw 1
			wait 5
		loop
	loop
どうだい、ちゃんと動いてるだろ?
本当だ! 
ああそうか、ループするごとにcntの中身が1づつ足されていって 
それに64掛けることによってコピーする位置をオートで指定するんだね。
そうそう。 
それでループを抜けるとcntの中身はリセットされるから1枚目の絵に勝手に戻る。 
でも、こうするとそのアニメだけにループが必要になるからcntではなく専用の変数を作って 
その数値を監視して一定の数字になったら0に戻すような作りのほうが良いから、こうなるな。 
	buffer 2:picload "animedot.bmp"
	gsel 0
*anime
	redraw 0
	gcopy 2,ani*64,70,64,70		;ループするごとにコピー元の位置を64ドットずらす
	redraw 1
	wait 5
	ani+1				;複雑な計算じゃない場合こういう式でもOK
	if ani=8:ani=0
goto anime
 
こうやると何か良い事あるの?
うーんそうだなぁ。 
アクションゲームとか画面内にいる敵やキャラクターみんな 
違う動きしてるだろ? 
最初のプログラムだと皆同じ動きになっちまう。 
各自変数をもっているから別々の動きが出来るんだ。
そっか。 
じゃあ最初のはそういう多数のアニメを必要にしない時だけ 
使えるものと考えたらいいね。
んじゃ、次に。 
このアニメーションの絵、下の行を見ると8枚の絵が並んでるよな。 
コレ実は3枚同じ絵があるんだ。 
上の行のポチの絵は5枚だろ? 
下のは上の絵の1→2→3→4→5→4→3→2 
という順で書いてるんだ。 
でも上の五枚でもアニメーションが出来る。
それって 
gcopy 2,0,0,64,70 
gcopy 2,64,0,64,70 
gcopy 2,128,0,64,70 
て描いていくってこと? 
面倒くさくない?
いいや? 
スイッチになる変数を作ればいいじゃないか。 
スイッチが0の時は表示位置が加算され、スイッチが1なら表示位置が減算される。 
こうすれば反復するアニメーションが作れるってわけだ。 
	buffer 2:picload "animedot.bmp"
	gsel 0
*anime
	redraw 0
	gcopy 2,ani*64,0,64,70
	redraw 1
	wait 5
	if sic=0:ani+1			;スイッチが0なら加算
	if sic=1:ani-1			;スイッチが1なら減算
	if ani=4:sic=1			;アニメが端まできたらスイッチの切り替え
	if ani=0:sic=0			;アニメが端まできたらスイッチの切り替え
	goto anime
 
そっか、こうすると画像の容量を小さくできるんだ。
次に配列変数をやるか。 
配列変数とは、そうだな。 
今までは変数は一つの箱として扱ってきたよな。 
そこで配列変数はマンションだと思ってほしい。 
マンションは一棟で何個も部屋があるよな。 
その部屋の中に内容を入れる事が出来るんだ。
それが出来るとどうなるの?
例えばモンスターが3体いるとする。 
ヒットポイントを割り当てるのにそれぞれに変数を作るとしよう。 
ehp0 ehp1 ehp2 
こうして3つの変数が作られる。 
この場合3つとも個々を手動で計算していかなければいけない。 
コレがシューティングとか沢山のものを計算する時になると大変だよな。 

でも配列変数にするとこんな感じになる 
ehp.0 ehp.1 ehp.2 
ぱっと見てあまり変わりがわからないように思えるけど配列にするとこういう事が出来る。 
repeat 
if ehp.cnt<=0:mes ""+cnt+"番の敵は死んでるよ" 
loop 
こうすると何百という変数を管理するとき凄く便利になるだろ?

おおう、確かにコレは便利だ!
配列変数の作り方は前にならったsdimと同じなんだ。 
sdimは文字の拡張の命令だったよな、数字の拡張の命令はdimだ。 
dim p1,p2 
p1には配列変数を作りたい変数名を入れる。 
p2は配列の数を入れるんだ。 
p2に10といれたら0から9番までの配列変数を作る事が出来る。 

sdimの場合も同じで 
sdim p1,p2,p3 
p1とp2は以前話た通りでp1は変数名、p2は拡張する文字数。 
p3で配列の数を入れるんだけどこの時メモリの使用量は 
p2xp3の数字になるからとりすぎには注意だ!

なんとなく配列変数の良さがわかったよ。 
具体的に使うとどんな感じ?
そうだな、じゃあ使い手がちょっと数値を変えるだけで 
画面が劇的に変化するようなものを作ってみるか。 
	buffer 2:picload "animedot.bmp"
	gsel 0
	kazu=20				;同時に表示する数
	dim ani,kazu			;アニメーション番号
	dim x,kazu			;x座標
	dim y,kazu			;y座標
	randomize			;ランダムを完全ランダム化
	repeat kazu			;各自の場所とアニメ開始位置をランダムで決める
		rnd ani.cnt,8		
		rnd x.cnt,576
		rnd y.cnt,410
	loop
	color 255,255,255
	gmode 2
*anime
	redraw 0
	boxf 0,0,640,480
	repeat kazu
		pos x.cnt,y.cnt:gcopy 2,ani.cnt*64,70,64,70
		ani.cnt+1
		if ani.cnt=8:ani.cnt=0
	loop
	redraw 1
	wait 5
	goto anime
コレはkazuという変数の中に数字を入れることによって 
オートでポチの数が変わるってプログラムだ。 
kazuの中を20にすると画像を表示するループ回数が20回になり 
配列変数aniの0番から19番まで順番に処理されていく。 
もし配列変数じゃなかったら膨大な命令文になるだろ?
私が沢山いる! 
・・・あれ? 
折角だからとgmode 2を使って透過させたんだけど 
すごい残像がでる! 
なにこれ!?
そりゃそうだ。 
画像の上に画像を表示できるだろ? 
つまりソレって前の画像が残るってことだ。 
だからこういう時は一度表示した後全て消してまた表示すればいいんだ。
そうか、clsか!
cls駄目!絶対!
嘘だ!
clsは画像もボタンも消してくれる便利な命令に思えるけどそうでもない。 
gmodeのモードを初期化するしredrawもリセットされる。 
なにより処理に時間がかかる。 
もし使うとすごく画面がチラつくぞ。 
便利だけど使い方を気をつけなければいけない機能という事を覚えておいてくれ。
うぎぎ、じゃあどうすれば!
そうだなぁ、背景の絵がある場合はおなじ位置のおなじサイズを切り取ればいい。 
面倒な場合は全サイズを切り取るといいけど残像を消す位置が小さい場合は一々コピーしたほうが 
処理が軽くなるぞ。 
この場合背景が白いから指定範囲を白く塗りつぶす命令文を使ってみるか。 
boxf p1,p2,p3,p4 
この命令はcolorで指定した色を指定した範囲塗りつぶすんだ。 
p1,p2に塗りつぶす左上になるx,y座標、p3,p4に塗りつぶす右下のx,y座標を入れてくれ。 
ところで左上、右下て書いてるけどp3,p4の位置は別に右下になくてもいいんだけどね。
説明の便宜上ってやつか。 
じゃあさっきのプログラムをこうすればいいんだね。 
	buffer 2:picload "animedot.bmp"
	gsel 0
	kazu=20				;同時に表示する数
	dim ani,kazu			;アニメーション番号
	dim x,kazu			;x座標
	dim y,kazu			;y座標
	randomize			;ランダムを完全ランダム化
	repeat kazu			;各自の場所とアニメ開始位置をランダムで決める
		rnd ani.cnt,8		
		rnd x.cnt,576
		rnd y.cnt,410
	loop
	color 255,255,255	;塗りつぶす色設定
	gmode 2			;透過設定
*anime
	redraw 0
	boxf 0,0,640,480
	repeat kazu
		pos x.cnt,y.cnt:gcopy 2,ani.cnt*64,70,64,70
		ani.cnt+1
		if ani.cnt=8:ani.cnt=0
	loop
	redraw 1
	wait 5
	goto anime
 
そそ、良い感じだ。 
200コくらいなら軽く動くと思うぜ。 
さて次にキャラクターを動かしてみるか。
キー入力をしてみよう。
じゃあ次はキー入力だ。 
ていっても難しい事はない。 
キー入力を感知する命令は3つあるんだけど一番簡単で便利なのをやるか。 
stick p1,p2,p3 
この命令はキー入力をした時指定した変数にその入力したキー情報が入るんだ。 
p1にキー情報を入れる変数。 
p2に指定したキー情報を入れると連射機能が搭載される。 
p3に1と入れると実行しているプログラムが選択されていない場合キーの受付を無視できる。 
p1に指定した変数に入るキー情報は 
  1   カーソルキー左(←) 
  2   カーソルキー上(↑) 
  4   カーソルキー右(→) 
  8   カーソルキー下(↓) 
 16   スペースキー 
 32   Enterキー 
 64   Ctrlキー 
128   ESCキー 
256   マウスの左ボタン 
512   マウスの右ボタン 
1024  TABキー 
あとこの命令文は常に実行されないとキー情報を取得できないから気をつけてくれ。 
repeatやgotoを使ったループ中に入れてくれ。 
あと、waitやawaitをそのループ中に入れないとキー情報を上手く取得してくれないから気をつけてくれ。
そのキー情報ってのがよく解からないんだけど。
たとえば 
stick stc 
とすると、←を押すとstcの中身が1になり、 
スペースを押すとstcの中身が16になる。 
←と↑を同時に押すと両方の情報が足されて3になる。
ん・・・んー? 
ちょっとまって、例えばstcの中身が1の時、 
if stc=1:x-1 
と、してキャラクターの座標を上に移動させることは出来る。 
でも←と↑を押すと3だとして 
if stc=3:x-1:y-1 
で左斜め上に移動できるとしよう、しかし他のボタンも同時に押されたとしたら? 
そうなったら何百通りもifを用意しないと駄目になるんじゃないの?
うん、そうやるとものすごい大変だよな。 
でも1行で解決する方法があるんだ。 
それが計算式の「&」だ。 
&とは変数の中に「それが含まれているか」を調べる事が出来る。 
その含まれているかというのはちょっと特殊でね。 
二進数て解かる?
んーん。 
わかんにゃーい。
わかんにゃいか。 
えーと俺たちが普段つかってる0から9で区切る数字は十進数。 
0と1だけで区切るのが二進数。 
二進数は0と1だけど1111と書いていた場合それは千百十一という数字じゃあない。 
二進数の1111は十進数の15になる。 
二進数の数え方は、数字の一文字目が1なら+1、二文字目が1なら+2、三文字目が1なら+4、 
四文字目が1なら+8になる。 
この数字を全て足すと15になるんだ。 
1001の場合一文字目が1だから+1、二文字目と三文字目は0なので無視し、 
四文字目が1なので+8で、二進数の1001は十進数では9になる。 
二進数は一番最初の文字が1で、一行増えるごとに二倍になっていく。 
その数字の組み合わせであらゆる数字にする事ができるんだ。
うーん、よく解からないしそれが解かって何になるのかも解からない。
つまり、←と↑とスペースを同時に押した時、 
stcの中身は1+2+16で19になる。 
19は二進数では11001なんだ。 
ただ19という数値を見たときその中に何が含まれていると言われても解からないよな? 
でも11001とすると19は 
1と2と16の数字が含まれた数というのが解かる。 
1から二倍していった数値だけ足していくという条件で出来た数値は 
何と何を足してその数値になるかを調べる事が出来るんだ。 
そこで「&」だ。 
stcの中身が19の場合、 
if stc&2 
とするとstcの中の数字19を作るために必要な要素として2が存在するので 
そのifは可となって処理することが出来る。
ごめんなさい! 
ますます解からない!
んー。 
まぁ解からなくてもいいよ。 
原理を説明しただけだから使い慣れたとき見ると解かると思う。 
とりあえず使ってみようか。 
	repeat
		stick stc		;キー入力チェック
		redraw 0
		color 255,255,255:boxf 0,0,320,240	;画面をリフレッシュ
		color 0,0,0
		if stc&1:pos 0,0:mes "左を押されてる"
		if stc&2:pos 0,20:mes "上を押されてる"
		if stc&4:pos 0,40:mes "右を押されてる"
		if stc&8:pos 0,60:mes "下を押されてる"
		redraw 1
		wait 5
	loop
どうだい? 
ボタンを押した瞬間押したボタンが表示されるよな。 
そこでp2に連射機能を付けたいキー情報を入れると表示させつづける事が出来る。 
この場合1+2+4+8で15と入れるといい。 
	repeat
		stick stc,15		;キー入力チェック
		redraw 0
		color 255,255,255:boxf 0,0,320,240	;画面をリフレッシュ
		color 0,0,0
		if stc&1:pos 0,0:mes "左を押されてる"
		if stc&2:pos 0,20:mes "上を押されてる"
		if stc&4:pos 0,40:mes "右を押されてる"
		if stc&8:pos 0,60:mes "下を押されてる"
		redraw 1
		wait 5
	loop
 
なるほど、つまり表を見て 
if キー情報の変数&キー情報 
というのを作ればいいんだね。 
最初からそう言えよ人が悪いなぁ。
・・・だよねー。
よし、じゃあそれを踏まえてこんな感じで作ってみたよ。 
	buffer 2:picload "animedot.bmp"
	gsel 0
	color 255,255,255
	gmode 2
*anime
	stick stc,15
	if stc&1:x-2		;キャラが左に移動する
	if stc&2:y-2		;キャラが上に移動する
	if stc&4:x+2		;キャラが右に移動する
	if stc&8:y+2		;キャラが下に移動する
	redraw 0
	boxf 0,0,640,480
	pos x,y:gcopy 2,ani*64+320,0,64,70		;ループするごとにコピー元の位置を64ドットずらす
	redraw 1
	wait 5
	ani+1
	if ani=4:ani=0
	goto anime
 
よーしやれば出来るじゃないか。 
んじゃ、今回はここまで。
次回予告
んじゃ、大体の基礎知識がついたって事で次から 
ゲームを作るためのプログラムの組み方をやっていくぞ。 
もしここまでで理解できていない所があったら何度も読んで 
ソースの中の数値を変えたりして理解してくれ。
ところでどんなゲームを作るの?
アドベンチャーゲームを作るよ。 
ADVというのはサウンドノベルに似ているやつだ。 
逆転裁判の探偵パートの部分みたいなアレね。
あれかー。 
でももうそういうの作れると思うよ私。
そいつぁどうかな? 
ゲームを作る時にはそのゲーム専用のツールを作る所から始まる。 
そうしないとゲームを作るのに時間がかかるし面倒だからな。 
ツール作れないだろ?
なるほど、ツクールを作ってからつくーるのね。
・・・まぁそんな所だ。 
さて毎回へんなオチで終わってるが折角の一章の最後だ。 
最後くらいサービスシーンでシメようぜ! 
新装開店なんだしな!
な、ちょ・・・マブかよ! 
・・・しょうがないなぁ。
うわ・・・コノ人本当に脱いじゃったよ。 
こっちが恥ずかしくなるていうか、恥ずかしさのあまり出血しちゃったよ
な、折角頑張ったのに何その扱い!?
また見てね!(笑
ちくしょうー。 
また次回!
今日はここまで。
 
今回のまとめ 
redraw p1,p2,p3,p4,p5 
画面の再絵画設定。 
絵画を一時的に停止し、一度に同時に画像を表示する事が出来る。 
p1を0にすると停止し、1にすると絵画する。 
p2,p3で設定を反映させる位置を決め、p4,p5で設定を反映させるサイズを決める。 
p2〜p5を省略すると全画面に反映される。 
多くの画像を表示させる場合、停止しておいて画像をコピーし、表示させるとかなり高速に表示させることが出来る。 
	buffer 2:picload "animedot.bmp"
	gsel 0:gmode 2
	randomize
	color 255,255,255
	button "普通",*hutu
	button "モード",*smode
	stop
*hutu
	boxf 64,0,640,480
	repeat 2000
	rnd x,512:rnd y,410
	pos x+64,y:gcopy 2,0,0,64,70
	loop
	stop

*smode
	redraw 0
	boxf 64,0,640,480
	repeat 2000
	rnd x,512:rnd y,410
	pos x+64,y:gcopy 2,0,0,64,70
	loop
	redraw 1
	stop
 
dim p1,p2 
数字型の配列変数を作る。 
1つの変数の中に数個の情報を入れる事が出来る。 
p1に変数名、p2に配列の数。 

sdim p1,p2,p3 
文字列型の配列変数を作る。 
p1に変数名、p2に変数に入れる事の出来る文字数、p3に配列の数。 
メモリの消費はp2xp3の数になるので注意。 

配列変数は変数に「.」をつけその後に番号を入れる。 
配列の数を10にすると0〜9まで使う事が出来る。 
配列変数は大量のデータを連続的に処理する時に非常に有効に使える。 
	dim renzoku,10

	repeat 10			;各配列に数字を入れていく
	renzoku.cnt=cnt*64
	loop

	repeat 10			;各配列に入った数字を出力
	mes "配列変数renzokuの"+cnt"番目に入っている数字は"+renzoku.cnt
	loop
	stop
   
				;雪を降らせます
	screen 0,320,240	;絵画サイズが小さいほど高速に絵画できる
	kazu=500		;雪の最大数
	dim x,kazu		;雪のX座標
	dim y,kazu		;雪のY座標
	dim iro,kazu		;雪の色
	dim soku,kazu
	repeat kazu
		rnd x.cnt,320		;それぞれの雪のX座標を設定
		rnd y.cnt,240		;それぞれの雪のY座標を設定
		rnd iro.cnt,120		;それぞれの雪の色を設定
		rnd soku.cnt,2		;各自落下速度を設定
	loop

*kaiga
	redraw 0
	color 0,0,0:boxf 0,0,320,240		;画面を黒く塗りつぶす。
	repeat kazu
	color iro.cnt,iro.cnt,iro.cnt*2		;青の数を高くする
	pos x.cnt,y.cnt:mes "・"		;指定位置に雪を表示
	y.cnt+(soku.cnt+1)			;雪の位置を下に移動させる
	if y.cnt>=240:rnd x.cnt,320:y.cnt=0	;雪が下まで落ちると上に戻す
	loop
	redraw 1
	await 10
	goto *kaiga
 

stick p1,p2,p3 
キー入力の情報を取得。 
p1にキー入力情報を入れる変数を入れる。 
特定のキーを押された時、変数にキーの情報が入り、同時に押された時その情報は加算される。 
  1   カーソルキー左(←) 
  2   カーソルキー上(↑) 
  4   カーソルキー右(→) 
  8   カーソルキー下(↓) 
 16   スペースキー 
 32   Enterキー 
 64   Ctrlキー 
128   ESCキー 
256   マウスの左ボタン 
512   マウスの右ボタン 
1024  TABキー 
加算された情報はifの条件式で「&」を使う事によって何が加算されたかを調べる事が出来る。 
また、この命令はループ中でwait、又はawaitを入れないと情報が更新されない。 
この命令は一度キーを押すと一度キーを放し再度押さないとキー情報を取得できない。 
p2にキー情報を入れると、入れたキー情報を連続して取得することが出来る。 
連射やキャラクターの移動等のときに有効です。 
p3を1にするとウィンドウが非アクティブの時キー情報を受け付けないようにすることが出来ます。 
	screen 0,320,240
	buffer 2:picload "animedot.bmp"
	gsel 0
	gmode 2
	repeat
		stick stc,1+2+4+8	;キー入力をチェック
		if stc&1:x-		;十字キーのどれかを押された時、何をするかの判断する。
		if stc&2:y-		;変数xやyの数値を変えてposでその座標を指定することによって
		if stc&4:x+		;キャラクターの移動を表現する。
		if stc&8:y+
		redraw 0
		color 255,255,255:boxf 0,0,320,240		;画面を漂白化
		color 0,0,0:pos 0,0
		mes "座標X="+x+" Y="+y+" キー情報="+stc	;情報の表示
		pos x,y:gcopy 2,320,0,64,70			;キャラクターを指定位置に表示
		redraw 1
		await 10		;無限ループ中にはawaitやwaitは欠かせない
	loop
 
もどる