◆PROCESSING 逆引きリファレンス
カテゴリー:ゲーム作成
背景画像をスクロールするには
【解説】
シューティングゲームなどでは、自機の背景画像がスクロール表示されるものが、良くあります。
あれは、どういった仕組みで実現しているのでしょうか?。
いろいろなやり方がありますが、ここではシンプルな方法を紹介します。
例として横スクロールを取り上げてみましょう。背景となる画像が、右から左に向けて、自動的に流れていく(スクロールする)仕組みを考えてみます。
(画像URL:GATAG | フリーイラスト素材集 様)
これは、あらかじめ横長の背景画像(backImg)を用意しておき、背景画像から画面に表示する画像の幅分だけを切り出しながら、次々と表示する事で実現可能です。
(画像URL:GATAG | フリーイラスト素材集 様、illust-AC 様:ナガミネ さん)
絵にすると、上記のような感じです。
最初は背景画像の左端(SX=0)から、画面の表示幅(width)分だけ画像を切り出して(赤枠部分:①)、画面に表示します。
次にSXを少し右にずらして、SXから画面の幅分だけ画像を切り出して(黄枠部分:②)、画面に表示します。
その次は、またSXを少し右にずらして、青枠部分(③)を切り出して、画面に表示します。
これを繰り返していくと、人間には背景画像が流れていくように見えるのです。
【構文】
PImage img = createImage( int w, int h, int format ) ;
img :生成された画像領域
w :生成する画像の横幅
h :生成する画像の高さ
format:生成する画像の種類
生成する画像の種類は、RGB、ARGB、ALPHAから選択可能。ARGBは透過色付きのRGB画像。ALPHAは透過色付きのグレースケール画像。
【注意】
注意としては、下図のように切り出す部分が、背景画像の右端を超えてしまった時です。
(画像URL:GATAG | フリーイラスト素材集 様)
図では★印の部分が、画面に表示したい幅(width)にくらべて不足しています。
このような場合は、SXからbackImage.widthまで(黄色枠①の部分)を表示用画像として複写した後で、不足している★部分を、背景画像の先頭部分(黄色枠②の部分)から継ぎ足すように複写します。
(画像URL:GATAG | フリーイラスト素材集 様)
これをグルグルと繰り返せば、横スクロールの完成です。
背景となる画像は、普通に loadImage すればOKです。表示用の画像は createImage 命令で画面と同じ大きさの画像領域を作成し、そこに背景画像から必要な部分を切り取って複写します。
(画像URL:GATAG | フリーイラスト素材集 様)
上記の図では、背景画像(haikei)の(SX, SY )の位置から、CutWidth、height の大きさの画像を、haikei.get 命令で cutLeftImg 変数に取り出しています。
取り出した画像は、createImg 命令で生成した表示用画像領域(map)に、map.set 命令で貼り付けます。
画像の読み込み、画像の切り取り、および画像の貼り付けについては、以下の記事を参照して下さい。
【関連記事】
サンプルプログラム
横スクロールの例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
final int SCROLL_SPEED = 4; //スクロール速度 PImage haikei; //スクロール用画像 int sx, sy; //切り出し位置 void setup(){ size( 600, 400 ); //スクロール用画像を読み込む haikei = loadImage( "haikei.png" ); sx = 0; sy = 0; } //--------------------------------------------- //スクロール用画像から、画面に表示したい部分を //切り取って、表示用画像として生成する処理 //--------------------------------------------- PImage getDispImg(){ int cutWidth = width; //切り出せる幅 int overWidth = 0; //飛び出し幅(解説の★幅) //表示用画像領域を作成 PImage map = createImage( width, height, ARGB ); //切り出したい画像の幅が、スクロール用画像の左端から //はみ出した時 if( sx + width > haikei.width ) { //切り出せる幅と、飛び出した幅を計算 overWidth = (sx + width) - haikei.width; cutWidth = width - overWidth; } //スクロール用画像から、一部を切り出して、貼り付ける PImage cutLeftImg = haikei.get( sx, 0, cutWidth, height ); map.set( 0, 0, cutLeftImg ); //もし飛び出していたら、スクロール用画像の左端から、 //飛び出し幅分の画像を切りとって、mapの右側に貼り付ける if( overWidth > 0 ) { PImage cutRightImg = haikei.get( 0, 0, overWidth, height ); map.set( cutWidth, 0, cutRightImg ); } //次の切り出し位置を、右にずらす(スクロールする) sx = sx + SCROLL_SPEED; if( sx >= haikei.width ) { //切り出し位置が、スクロール用画像の右端になったので //先頭に戻す sx = 0; } //作成した表示用画像を返却する return( map ); } void draw(){ //スクロール用画像の一部を取得して、背景として表示する PImage back = getDispImg(); background( back ); } |
実行すると、1/60秒ごとに、背景画像が右から左に4ピクセルずつスクロールします。
<出力サンプル>
(画像URL:GATAG | フリーイラスト素材集 様)
下記はサンプルプログラムと同じ動きになるように、 P5.js で書き直したものです。動作イメージを確認できます(P5.jsではスクロールスピードを遅くしてあります)。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。