【Bラボデジタルサイネージ7】ページの自動切り替え

![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fuser-images.githubusercontent.com%2F29194025%2F137117015-af05fe4f-7c32-4e38-876f-e153ff2f2f7d.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=2bbf46fb5c1d8dec16f2fcb5d089fde2)

https://github.com/ohayota/BLabo-digital-signage

本記事は、[株式会社 函館ラボラトリ](http://www.hakolab.co.jp)が運営する「[Bラボ](http://www.hakolab.co.jp/b-lab/index.html)」における、大人向け「看板アプリ（デジタルサイネージ）を作るコース」用教材テキストです。

http://www.hakolab.co.jp/b-lab/index.html

1. [【Bラボデジタルサイネージ1】Processing+ラズパイでデジタルサイネージを作る！](https://qiita.com/ohayota/items/f4aa3e1b452060eb52ad)
2. [【Bラボデジタルサイネージ2】ラズパイ初期設定](https://qiita.com/ohayota/items/88fbcf177e6606311efb)
3. [【Bラボデジタルサイネージ3】準備プログラム作成＆機能実現の方針決定](https://qiita.com/ohayota/items/41a746d2258673726541)
4. [【Bラボデジタルサイネージ4】レイアウトの基準になるグリッドを表示する「GridModule」](https://qiita.com/ohayota/items/df704f523b5aa4dbb180)
5. [【Bラボデジタルサイネージ5】レイアウトの基準になる枠を表示する「PlaceholderModule」](https://qiita.com/ohayota/items/f52a10660009794afd9f)
6. [【Bラボデジタルサイネージ6】画像を全画面表示する「FullImageModule」](https://qiita.com/ohayota/items/4a9c8423459c251f4911)
7. **【Bラボデジタルサイネージ7】ページの自動切り替え（本記事）**
8. [【Bラボデジタルサイネージ8】設置されている場所の名前を表示する「LocationModule」](https://qiita.com/ohayota/items/046b361d945a709c4605)
9. [【Bラボデジタルサイネージ9】現在の時間を表示する「DateModule」](https://qiita.com/ohayota/items/6b80137e33bfb4172de6)
10. [【Bラボデジタルサイネージ10】ページ切り替えの時間が分かる「ProgressBarModule」](https://qiita.com/ohayota/items/9f3b6f9f32b7d93ef2a7)
11. [【Bラボデジタルサイネージ11】現在の表示中のページが分かる「PageControlModule」](https://qiita.com/ohayota/items/23acc993dca47286fffb)
12. [【Bラボデジタルサイネージ12】現在の天気を表示する「WeatherRModule」](https://qiita.com/ohayota/items/d9b1d21037dcedcfd78c)
13. [【Bラボデジタルサイネージ13】直近2件のバス時刻表を表示する「BusRModule」](https://qiita.com/ohayota/items/93d7c9b5328188b3c5b6)
14. [【Bラボデジタルサイネージ14】ごみ出しカレンダーを表示する「GomiRModule」](https://qiita.com/ohayota/items/40ed5db352a688637f83)
15. [【Bラボデジタルサイネージ15】（発展編）ツイートを表示する「TwitterRModule」](https://qiita.com/ohayota/items/6367fad7beaf9ad9ea1c)
16. [【Bラボデジタルサイネージ16】開店／閉店を表示する「OpenCloseRModule」](https://qiita.com/ohayota/items/284b5c7e7101f602016f)
17. [【Bラボデジタルサイネージ17】部屋の温度を表示する「TemperatureRModule」](https://qiita.com/ohayota/items/386c27a021601fb3ccfd)
18. [【Bラボデジタルサイネージ18】部屋の明るさを表示する「BrightnessRModule」](https://qiita.com/ohayota/items/76279927b4ef35eaf628)
19. [【Bラボデジタルサイネージ19】起動画面を表示する「LaunchingScreenModule」](https://qiita.com/ohayota/items/0b6bdeda68c36707f762)
20. [【Bラボデジタルサイネージ20】RModuleの影を実装](https://qiita.com/ohayota/items/57242f18653ccf7eb83b)


# 作るもの

読み込んだ画像を画面全体に表示する機能を使って、複数のページを作ります。
複数のページを用意したら、10秒経つとページが切り替わるようにします。

1ページ目はこちら。

![0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368192/6fa2b0a6-7f02-c4bf-304c-b6959e1f443f.png)

2ページ目はこちら。

![1920x1080.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368192/9247137f-11bb-b03a-a456-3acf2a7f721f.jpeg)

この2ページを自動的に切り替えます。


# 画像を読み込む

まずは、先程の「1920x1080」と書かれた画像を保存し、「ad0.jpg」という名前をつけます。
（.png形式など別の形式の場合は、.jpg形式に変換してください。）

Processingの画面上のタブで、「スケッチ > スケッチフォルダーを開く」を選ぶと、開いている.pdeファイルが一覧で表示されます。
「data」フォルダの中に、新たに「ad」フォルダを作ってください。
表示したい画像を「data/ad」フォルダの直下においてください。（ドラッグ＆ドロップ）

ここで用意した「ad0.jpg」の「ad」は、広告画像として表示する画像につける名前になります。
広告画像を表示するときは1枚だけでなく、複数枚のスライドショーになる場合もあるでしょう。
広告画像を複数枚表示するときは、2枚目以降の画像を「ad1.jpg」「ad2.jpg」...のように命名していきます。

次に、Processingで画像「ad0.jpg」を読み込みます。
読み込んだ画像を保存するための配列`adImage`を用意します。

``` java:DigitalSignage.pde
/* 略 */

PImage background;
PImage[] adImage; /* 追加 */

void settings() {
  size(1920, 1080);
  //fullScreen();
}

/* 略 */
```

次に、「すべてのページの枚数」である変数`PAGE_ALL_COUNT`と、「広告画像の枚数」である変数`AD_IMAGE_COUNT`を置きます。

``` java:DigitalSignage.pde
/* 略 */

PImage background;
PImage[] adImage;

final int PAGE_ALL_COUNT = 2; /* 追加 */
final int AD_IMAGE_COUNT = 1; /* 追加 */

void settings() {
  size(1920, 1080);
  //fullScreen();
}

/* 略 */
```

配列`adImage`へ画像を読み込みます。
その準備として、広告画像（ad0.jpg）が格納されているフォルダのパスを、変数で定義しましょう。

``` java:DigitalSignage.pde
/* 略 */

PImage background;
PImage[] adImage;

final int PAGE_ALL_COUNT = 2;
final int AD_IMAGE_COUNT = 1;

final String AD_PATH = "ad/"; /* 追加 */

void settings() {
  size(1920, 1080);
  //fullScreen();
}

/* 略 */
```

今後、data/ad/ad0.jpgに入っている広告画像は、Processingのプログラム内で`AD_PATH + ad0.jpg`のように表すことができます。
次に`Initialize.pde`内に新しい関数`initializeImage()`を作り、関数内で画像を読み込みましょう。

``` java:Initialize.pde
/* 略 */

void initializeImage() {
  adImage = new PImage[AD_IMAGE_COUNT];
  for (int i = 0; i < AD_IMAGE_COUNT; i++) {
    adImage[i] = loadImage(AD_PATH + "ad" + i + ".jpg");
  }
}
```

「広告画像の枚数」である変数`AD_IMAGE_COUNT`とfor文を使い、広告画像をすべて配列に読み込んでいます。
関数`initializeImage()`はまだどこからも呼び出されていないので、関数`initialize()`内で呼び出すようにします。

``` java:Initialize.pde
void initialize() {
  initializeImage(); /* 追加 */
  initializeGrid();
  initializePlaceholder();
}

/* 略 */
```

これで、画像の読み込みが実装できました。


# ページ更新用の関数

今までは1ページだけ表示してきましたが、2ページ以上となると、「今何ページ目を表示しているか」を管理する必要があります。
「今何ページ目か」がわかるように、変数をひとつ定義しましょう。

``` java:DigitalSignage.pde
/* 略 */

PImage background;
PImage[] adImage;

final int PAGE_ALL_COUNT = 2;
final int AD_IMAGE_COUNT = 1;

int nowPageID = 0; /* 追加 */

final String AD_PATH = "ad/";

void settings() {
  size(1920, 1080);
  //fullScreen();
}

/* 略 */
```

`nowPageID`が0のとき1ページ目、1のとき2ページ目...という風に、この変数によって何ページ目を表示するか管理します。
次に、`nowPageID`の値を変更する関数を定義します。

``` java:DigitalSignage.pde
/* 略 */

void updateNowPageID(boolean isIncrement) {
  if (isIncrement) {
  } else {
  }
}
```

関数`updateNowPageID`は、`nowPageID`を増やす／減らすときに実行する関数です。
引数`isIncrement`がtrueのときは増やし、falseのときは減らします。
増やす／減らすときの処理を実装します。

``` java:DigitalSignage.pde
/* 略 */

void updateNowPageID(boolean isIncrement) {
  if (isIncrement) {
    nowPageID = (nowPageID + 1) % PAGE_ALL_COUNT; /* 追加 */
  } else {
    nowPageID = (nowPageID + PAGE_ALL_COUNT - 1) % PAGE_ALL_COUNT; /* 追加 */
  }
}
```

これで、関数によって`nowPageID`を更新する準備ができました。


# 広告画像を表示

モジュールを表示するときに実行される関数`drawModules()`を作ります。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  drawFullImageModule(background);
  drawGridModule();
  drawPlaceholderModule();
}

void drawModules() { /* 追加 */
}

/* 略 */
```

いま`draw()`内にある3つの処理は、新しく作った関数に入れましょう。
そして、`draw()`内で`drawModules()`を呼び出すように書き換えましょう。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  drawModules(); /* 追加 */
}

void drawModules() {
  drawFullImageModule(background); /* 移動 */
  drawGridModule(); /* 移動 */
  drawPlaceholderModule(); /* 移動 */
}

/* 略 */
```

次に、`nowPageID`に応じて表示するページを変えるような実装にしましょう。
if文を使って実装します。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  drawModules();
}

void drawModules() {
  /* 追加 */
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
  }
}

/* 略 */
```

`nowPageID`が1のときには、読み込んだ広告画像を表示するようにしましょう。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  drawModules();
}

void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    drawFullImageModule(adImage[0]); /* 追加 */
  }
}

/* 略 */
```

この記述を追加した時点で、2ページ目（`nowPageID`が1のとき）で広告画像が表示できるようになっています。
試しに、`nowPageID`の初期値をいじってみましょう。

``` java:DigitalSignage.pde
/* 略 */

int nowPageID = 1; /* 変更 */

/* 略 */
```

実行すると、2ページ目が表示されるようになっています。

![1920x1080.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368192/9247137f-11bb-b03a-a456-3acf2a7f721f.jpeg)

確認できたら、**初期値を0に戻してください**。

``` java:DigitalSignage.pde
/* 略 */

int nowPageID = 0; /* 変更 */

/* 略 */
```

次は、一定の秒数でページが自動切り替えされるようにしてみましょう。


# 10秒間隔でページ切り替え

![0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368192/6fa2b0a6-7f02-c4bf-304c-b6959e1f443f.png)

![1920x1080.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368192/9247137f-11bb-b03a-a456-3acf2a7f721f.jpeg)

現状実装できている2ページ（上の2枚の画像）を、10秒間隔で切り替えられるようにしましょう。
1つのページに留まる秒数を定義しましょう。

``` java:DigitalSignage.pde
/* 略 */

PImage background;
PImage[] adImage;

final int STAY_SECOND = 10; /* 追加 */

final int PAGE_ALL_COUNT = 2;
final int AD_IMAGE_COUNT = 1;

int nowPageID = 0;

final String AD_PATH = "ad/";

void settings() {
  size(1920, 1080);
  //fullScreen();
}

/* 略 */
```

`STAY_SECOND`の秒数は変えてもいいですが、**必ず60の約数にしてください**。

次に、データを更新するときの処理を記述する関数`updateDatas()`を実装します。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  drawModules();
}

void updateDatas() { /* 追加 */
}

/* 略 */
```

`updateDatas()`内では、今後は時刻や`nowPageID`など、さまざまなデータを更新する処理を書いていきます。
ここではページ切り替えだけ実装します。

``` java:DigitalSignage.pde
/* 略 */

void updateDatas() {
  /* 追加 */
  if (second() % STAY_SECOND == 0) {
    updateNowPageID(true);
  }
}

/* 略 */
```

これで、10秒経過したときに`nowPageID`が増えます。

`updateDatas()`は、モジュールを描画する前に実行する必要がある関数です。
`draw()`内の最初で実行するようにしましょう。

``` java:DigitalSignage.pde
/* 略 */

void draw() {
  updateDatas(); /* 追加 */
  drawModules();
}

/* 略 */
```

これにより、ページ切り替えが実装できました。
実行して10秒ほど待ってみると、画面が自動で切り替わるようになっているはずです。
（実行のタイミングによっては、10秒たたずに切り替わるかもしれません。）


# 最後に

これでページの自動切り替えが実装できました。
次は、**[設置されている場所の名前を表示する「LocationModule」](https://qiita.com/ohayota/items/046b361d945a709c4605)**を実装してみましょう。

https://qiita.com/ohayota/items/046b361d945a709c4605