背景をスクロールする(2/2)

 3.背景を描画する

 マップ上の現在位置mappntに対応するデータを配列変数backmapから読み取り、描画します。mappntはステージが始まってから何ドットスクロールしたかを表しています。1つのマップチップの縦幅が64ドットですから、例えばmappntが256の時、画面の下端に表示する行はbackmap.0.4のデータに対応する絵です。(ステージ1の場合です。)つまり、mappnt/64番目の要素です。画面の縦幅がysizeですから、ysize/64行分のデータを表示します。ysizeは448ですから7行分、つまりbackmap.0.4〜backmap.0.10です。

  mappntが256の時

 mappntが64の倍数の時はこれでいいのですが、そうでない時はどうでしょうか。mappntが258の時、今のを2ドット下にずらした絵になるはずです。260の時は、4ドット下にずらした絵です。つまり、mappnt\64ドットずらします。そうすると画面の上の方が空いてしまいますね? そこで、ysize/64より1行多く描きます。
 以前の講座、「画面の大きさを調整する」で、画面内に入っている部分だけを描画するようにしましたから、はみ出している部分を気にする必要はありません。

 ボス戦の時はどうしたらよいでしょうか? 何通りかのやり方が考えられます。

 ここでは3番目の方法にします。backmap.0.0〜backmap.0.63を通常戦、backmap.0.64〜backmap.0.71をボス戦用のマップデータとします。ループにするというのは、backmap.0.71の次はbackmap.0.64に戻って描画するという事です。

 背景を描画する処理は、「マップ上の位置を2つ進める」処理の前に書きます。プログラムは以下のようになります。
    s=stageno-1
    repeat ysize/64+1
        i=cnt
        if mappnt<4096 {
            n=mappnt/64+i
        }
        else {
            n=(mappnt/64+i-64)\8+64
        }
        1行描画する処理
    loop
 1行描画する処理をysize/64+1行分行っています。
 nは、各行に対応するbackmapの要素の番号を求めています。mappntが4096(=64ドット×64行)以上の時、ボス戦です。通常戦の時、mappntが64の倍数でない時でもmappnt/64+iで求まります。割り算した結果は小数点以下が切り捨てられるからです。
 mappntは背景がループすることとは関係なくどんどん増えていきます。ボス戦の時は、要素番号は64から始まる値でした。通常戦の時と同じようにして求めた値mappnt/64+iから64を引くと、0から始まる値になります。7の後は0に戻るようにしたいので、"\8"を行います。これに64を足すと、64から71までの値になります。

 1行描画する処理は、以下のようになります。
    repeat xsize/64
        gdx=cnt*64
        gdy=ysize-64-(64*i)+(mappnt\64)
        x=0
        str x
        strmid x,backmap.s.n,cnt*3,1
        int x
        gdox=x*64
        y=0
        str y
        strmid y,backmap.s.n,cnt*3+1,1
        int y
        gdoy=y*64
        gdw=64
        gdh=64
        gosub *Graphic_Draw
    loop
 横にxsize/64個マップチップを描きます。
 描画するy座標(gdy)の計算ですが、下端の行の、マップチップの上端はysize-64です。各行のy座標はysize-64-(64*i)となります。それをmappnt\64ドット下にずらすのですからysize-64-(64*i)+(mappnt\64)となります。
 backmapから対象となるマップチップの横位置、縦位置を読み取り、64倍して絵のファイル中の座標(gdox,gdoy)を求めています。


 以上をまとめますと、背景をスクロールする処理は以下のようになります。
sample10.as

	; プログラム起動時の初期設定
	#include "backmap.as"

	; ゲームスタート時の初期設定
	stageno=1

	; 背景を描画
	s=stageno-1
	repeat ysize/64+1
		i=cnt
		if mappnt<4096 {
			n=mappnt/64+i
		}
		else {
			n=(mappnt/64+i-64)\8+64
		}
		repeat xsize/64
			gdx=cnt*64
			gdy=ysize-64-(64*i)+(mappnt\64)
			x=0
			str x
			strmid x,backmap.s.n,cnt*3,1
			int x
			gdox=x*64
			y=0
			str y
			strmid y,backmap.s.n,cnt*3+1,1
			int y
			gdoy=y*64
			gdw=64
			gdh=64
			gosub *Graphic_Draw
		loop
	loop
backmap.as
	; 地形マップ

	sdim backmap,14,3,100

	; ステージ1のデータ
	backmap.0.71="40,71,71,71,40"
	backmap.0.70="40,71,42,71,40"
	backmap.0.69="40,71,71,71,40"
      ・
      ・
      ・

実行画面
実行画面


[プログラム全体と絵をダウンロード]
※「ゲームスタート時の初期設定」の"stageno=1"を2や3に変えてみて下さい。

ひとくちメモ:
・配列変数の要素の数
 dim文やsdim文で、要素の数を宣言しますが、使う要素の数とぴったり同じにしても構いませんし、後で増やすかもしれないので、少し余裕を持ったキリのいい数字にするのも手です。
 
・配列変数の添え字
 命令の引数には計算式を書くことができますが、配列変数の添え字には計算式を書くことはできませんので注意して下さい。
  ×  a=1:b.(a+1)=3
  ○  a=1:c=a+1:b.c=3
 
・ファイルの分割
 プログラムが長くなってくると、スクロールしまくらなければならなくなってしまいますよね? ある程度長くなってきたらファイルを分けた方がいいです。また、Windows2000やXPの場合は無制限なのですが、95/98/Meの場合はHSPスクリプトエディタで扱える最大ファイルサイズは48000バイトまでという制限があります。
 
・「デフォルトで」
 デフォルトは「既定値」という意味です。つまり、初期値として設定されている値や状態です。「デフォルトで」と言えば「何も指定しなければ」という意味になります。本講座で、いくつかウィンドウの大きさも字の色も指定しないプログラムを例として書いています。この場合デフォルトで640×480のウィンドウが表示されます。ひょっとしたら環境によって違うかもしれませんが、背景は白で文字色が黒です。  配列変数は、dim文で宣言すると、同時に各要素に0が代入されるということがHSPのヘルプに明記されています。普通の変数の場合、何も代入しなければ0が入っていると書きましたが、それはどこかに明記されているわけではありません。調べてみたらそうだったというだけのことです。次のような簡単なプログラムで調べることができます。
    mes a
    stop
 HSPが将来バージョンアップしても同じとは限りません。ですから変数にデフォルトで0が入っていることを前提としたプログラムを書くべきではありません。
 
・バイト
 バイトは単位で、8ビットが1バイトです。1バイトで表せる数値は、最小値が%00000000つまり0、最大値は%11111111つまり255です。ですから256通りの値を表せます。
 HSPの数値は32ビットの整数ですが、4バイトの整数であるとも言えます。
 1キロバイト(KB)は1000バイトです。が、1024バイトだという人もいます。いまだにどちらが正しいのか分かりません。分からなくても別に困りません。1メガバイト(MB)は1000キロバイトです。これも、1024キロバイトだという人もいます。
 
・なぜコンピュータの世界では中途半端な数が多用されるのか
 本講座もそうですが、プログラミングの本やコンピュータ関係の本を読むと、16や64や256、65536といった数がたくさん出てきます。これは、16進数で表すと$10、$40、$100、$10000です。以前に、パソコンは絵も音楽も文章も、すべて2進数のデータとして取り扱っているという話をしました。16進数は2進数の4桁を1桁にまとめたものです。ですから、コンピュータにとっては16進数で表した時にキリがいい数字の方が扱いやすいのです。先ほどの1024もそうです。これは16進数で$400なのでキリがいいのです。
 
・文字コード
 半角文字は1バイト、全角文字は2バイトであると書きました。実は、文字には対応する数字が割り当てられているのです。例えば"a"は97、"b"は98、といった具合です。これを文字コードといいます。コンピュータは、文字列を文字コードに直して記憶しています。この割り当て方は1種類ではありません。何種類かが規格として定められています。シフトJISコード、EUCコード、ASCIIコード、Unicode等の規格です。例えば、本サイトはシフトJISコードに従って表示するようになっています。
「半角文字は1バイト」というのは、半角文字には1バイトの数値が割り当てられているということです。つまり0から255までの数値です。全角文字には2バイト、つまり0から65535までの数値が割り当てられています。
 全角文字は扱わず、すべてを1バイトで表すASCIIコード、半角か全角かに関わらず、すべてを2バイトで表すUnicodeもありますが、Windowsでは文字列はシフトJISコードで表されます。他のOSでは別のコードです。シフトJISコードでは半角文字は1バイト、全角文字は2バイトです。
 strmidでは文字単位ではなく、バイト単位で数えます。
  "abcdあいうed"
 この文字列で、"e"は10バイト目です。(一番左を0バイト目として数えます。)
 "bc"は2バイト分の文字列です。"あい"は4バイト分、"うe"は3バイト分の文字列です。
 上の場合、5バイト目から4バイト分取り出したり、3バイト目から2バイト分取り出したりすると、変な文字列になってしまいますのでご注意下さい。

 ちなみに、文字に対応する文字コードは以下のようにして調べることができます。
  • 半角文字(例えば、"A")の場合
    a="A"
    peek b,a,0
    mes b
    stop
  • 全角文字(例えば、"あ")の場合
    a="あ"
    peek b,a,0
    peek c,a,1
    mes b
    mes c
    stop
 peek文の第1引数は取り出したコードを代入する変数、第2引数は取り出す対象となる変数、第3引数は何バイトめを取り出すか、です。
 
・絵について
 背景を暗めの色に、キャラクタを明るめの色にすると、見やすいかと思います。背景もキャラクタも明るい色にしたい場合、キャラクタに暗い色で縁をつけると、見やすいと思います。
  明るい背景に明るいキャラ
 

[目次へ][前へ][次へ] inserted by FC2 system