チュートリアルWikiトップ


Tonyu Systemスクロールのサンプル

このサンプルの解説を読む前に、Tonyuの基本操作やチュートリアルなどを習得した後に読むと理解が深まると思います。

まずアーカイブをダウンロードしてください。

アーカイブを解凍し、解凍したフォルダ内のindex.cmmlをTonyuで開きます。

実行すると、画面が横にスクロールします。自機はカーソルキーで動きます。

プログラムの解説1 : ワールド座標

自機をダブルクリックすると次のようなコードが表示されます。

extends SpriteChar;
// 画面スクロールにあわせて自機がうごきます
scx=0; // スクロール位置用変数
while (1) {
$map.scrollTo(scx,0); // 画面左上の
ワールド座標が(scx,0)になるようにスクロール
scx+=1; // スクロール位置を1ドット上にずらす
x+=1; // スクロールにあわせて自分の座標を増やす

// $viewXを使って、画面上端のワールド座標 (x座標)を得ることができます。
if (getkey(37) && x>$viewX) x-=3; // 左
if (getkey(39) && x<$viewX+$screenWidth) x+=3; // 右

// $viewYを使って、画面上端のワールド座標 (y座標)を得ることができます。
if (getkey(38) && y>$viewY) y-=3; // 上移動
if (getkey(40) && y<$viewY+$screenHeight) y+=3; // 下移動
update();
}

注釈を見ると「ワールド座標」という用語があります。ワールド座標とは何でしょう。
今までTonyuでプログラムを作ってきた際に、x、yという変数を使ってオブジェクトの位置を指定したり参照したりしてきました。このように変数(数値)の組み合わせでオブジェクトの位置をあらわす手段のことを「座標」と思ってもらえればよいでしょう。
いままで扱ってきた座標は、

画面(ウィンドウ)の左上が(x,y)=(0,0)
画面(ウィンドウ)の右下が(x,y)=($screenWidth,$screenHeight)

となっていました。例えばウィンドウの大きさが560x384なら$screenWidthは560、$screenHeightは384となります。

このように画面(ウィンドウ)の左上を基準した座標を「スクリーン座標」と呼びます(下図参照)




ではスクリーンでない座標ってなんでしょう。次の図を見てください。これはこのサンプルで使われているマップの全体図です。ゲーム雑誌の攻略記事なんかでよくみる細長-いマップです。



例えば、この全体マップの中ほどにある、緑の
の場所に隠しアイテムがあるとしましょう(実際はないですけど)。

その場所を座標で指し示すにはどうすればよいでしょうか。
前述のスクリーン座標を使おうとするとまずい点があります。なぜなら、画面はどんどんスクロールしていくため、画面が右に流れれば隠しアイテムの場所も画面上では右に流れてしまい、画面上で「ここだ」ということができないためです。


上の図の左側の図では★のスクリーン座標は(472,154) 、右側の図では(227,154)となります

そこで登場するのがワールド座標です。マップ全体に次の図のような座標をあてはめたものがワールド座標になります。



ワールド座標を用いて
の位置を表すと(1080,154) となります。

プログラムの解説2 : スクロールする、スクロールした位置を調べる

実は今までオブジェクトの座標として使っていたxやyの値は、そのオブジェクトの位置をワールド座標で表しているのです。
にもかかわらず、今まで


「x=0にするとオブジェクトがウィンドウの左端に、y=0にすると上端に移動します....」

などと、x,yをスクリーン座標のように扱っていました。それでも何も問題はありませんでした。
なぜなら、Tonyu起動時に表示される画面は

「ウィンドウの左上がワールド座標(0,0)になるように表示」

していたからです。この場合、スクリーン座標とワールド座標は値として同じものになります。(次の図参照)



さて、もう一度プログラムを見てみましょう

extends SpriteChar;
// 画面スクロールにあわせて自機がうごきます
scx=0; // スクロール位置用変数
while (1) {
$map.scrollTo(scx,0); // 画面左上のワールド座標が(scx,0)になるようにスクロール
scx+=1; // スクロール位置を1ドット上にずらす
(中略)
update();
}

$map.scrollTo(scx,0); というメソッド呼び出しに注目しましょう。これがスクロールを行うということは、TonyuヘルプのAPIリファレンスにも書いてあります。
例えば、このプログラムのwhileループを500回まわると、scxの値が500になります。
この場合
$map.scrollTo(scx,0);

$map.scrollTo( 500 ,0);
と同等になります
注釈に
// 画面左上のワールド座標が(scx,0)になるようにスクロール
と書いてあります。この場合ワールド座標が(500,0)になるようにスクロール
します。つまり、次の図のようにスクロールします。



さらに、プログラムを詳しくみていきましょう。
プログラムを実行してみるとわかりますが、自機は画面の端まで移動するとそれより外側には移動できなくなります。
そのための判定をしている部分はプログラム上では次の部分です

// $viewXを使って、画面上端のワールド座標(x座標)を得ることができます。
if (getkey(37) && x>
$viewX ) x-=3; // 左
if (getkey(39) && x<
$viewX +$screenWidth) x+=3; // 右

//
$viewYを使って、画面上端のワールド座標(y座標)を得ることができます。
if (getkey(38) && y>
$viewY) y-=3; // 上移動
if (getkey(40) && y<
$viewY +$screenHeight) y+=3; // 下移動

$viewX,$viewY という変数が使われています。この2つの変数を参照することで
現在、画面左上はワールド座標でどの位置にあたるのかを得ることができます。
xやyといった値は、自機の位置をワールド座標で表していますので、
画面スクロールするにつれて自分の移動できる範囲も移動していきます。
次の図のように、画面内で移動できる範囲は、左端が$viewX、右端が$viewX+$screenHeightになります。
ちなみに、このプログラムは横にしかスクロールしないので、$viewYはずっと0
です。よって$viewYはなくても正しく動作します。
ここではスクロール方向に縦が加わったときも考え、$viewYをわざと用いています。