JavaScript で本格的なノベルゲームを作ってみる #1

## はじめに

素の JavaScript でノベルゲームを作ってみようと思いたちました。

・ゲームの中では比較的簡単そう
・昔よく遊んでいたのでノスタルジーを感じる
・作りたいゲームの構想があるので、まずはその土台にしたい

といった理由です。
[GitHub も上げておきます](https://github.com/Neru-K/novelgame-javascript)ので、ぜひ「ここが変だよ」「ここはこうした方がいい」などアドバイス頂けたら嬉しいです ✨

## 目次

> [まずは画像を表示させてみる](#まずは画像を表示させてみる)
>[テキストを表示させてみる](#テキストを表示させてみる)
>[次にやること](#次にやること)
>[謝辞](#謝辞)
>[連載一覧](#連載一覧)

<a id="anchor1"></a>

## まずは画像を表示させてみる

画像の描画は canvas で作ることにします。
当初、ひとつの canvas に対して背景・キャラクターを表示させようとしたのですが、
描画の順番などに気を使う必要があったりが面倒な気がしたのと、
単純にレイヤーが分かれているほうが後々楽そうだと思ったので canvas をふたつ使うことにしました。

```html:index.html

<div id="game-container">
    <canvas id="background-layer" width="1920" height="1080"></canvas>
    <canvas id="character-layer" width="1920" height="1080"></canvas>
    <div class="message_box">
    <p class="text_message_p"></p>
    </div>
</div>

```

サイズなどはとりあえず仮です。

あとはテキストを表示させるウィンドウの要素も作っておきました。重要ですね！
JS を読み込んで画像を表示させ、CSS で適当に整えます。

背景画像は[みんちりえ](https://min-chi.material.jp/)様から、
キャラクター画像は[わたおきば](https://wataokiba.net/)様
より使用させていただいております。素晴らしい絵をありがとうございます！

```javascript:main.js

//読み込み時に実行される関数
(function () {
  drawBGImage("/images/background/田舎の家の縁側（日中）.jpg");
  drawCharaImage("/images/character/patient/josei_11_gray.png");
})();

//背景の描画
function drawBGImage(src) {
  const canvas = document.querySelector("#background-layer");
  const ctx = canvas.getContext("2d");
  const img = new Image();
  img.src = src;

  img.addEventListener("load", (event) => {
    ctx.drawImage(img, 0, 0);
  });
}

//キャラクターの描画
function drawCharaImage(src) {
  const canvas = document.querySelector("#character-layer");
  const bgcanvas = document.querySelector("#background-layer");
  const ctx = canvas.getContext("2d");
  const img = new Image();
  img.src = src;

  img.addEventListener("load", (event) => {
    const posX = (bgcanvas.width - img.width) / 2;
    ctx.drawImage(img, posX, 100);
  });
}


```

とりあえず関数で作っていき、なんかごちゃごちゃしてきたなーと思ったらクラス構文でまとめ直すかもしれません。

表示してみるとこんな感じ ↓↓
![novelgame.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455043/15e473e9-5e9f-2558-5e2b-bb99076ed699.jpeg)

なんかこれだけで雰囲気出てますね！いい感じです:)

<a id="anchor2"></a>

## テキストを表示させてみる

ノベルゲームなのだから、テキストが表示されなければ話になりません。
テキストはとりあえずソースコードにベタ打ちしておきます。仕様はまったく考えていないのですが、後で修正するとしてとりあえず作っていきます。

```javascript:revealTextMessage.js

//テキストを読み込み
function initRevealTextMessage(text) {
  let chars = [];
  const text_message_p = document.getElementsByClassName("text_message_p")[0];
  text.split("").forEach((char) => {
    let span = document.createElement("span");
    span.textContent = char;
    text_message_p.appendChild(span);

    chars.push({
      span,
      delayAfter: char === " " ? 0 : 60,
    });
  });

  revealTextMessage(chars);
}

//一文字ずつ表示
function revealTextMessage(list) {
  let timeout;
  const next = list.splice(0, 1)[0];
  next.span.classList.add("revealed");

  if (list.length > 0) {
    timeout = setTimeout(() => {
      revealTextMessage(list);
    }, next.delayAfter);
  } else {
    clearTimeout(timeout);
  }
}
```

2 つ関数を作りました。

initRevealTextMessage でまずテキストを一度読み込みます。
CSS で opacity:0;になっているのでこの時点ではテキストは見えません。
テキストを1文字ずつspanタグで囲み、それをrevealTextMessageに渡します。
ループさせて、一文字ずつ時間差で表示させるという流れです。

最初に作ったmain.js から、それを呼び出します↓↓

```javascript:main.js
//読み込み時に実行される関数
(function () {
  drawBGImage("/images/background/田舎の家の縁側（日中）.jpg");
  drawCharaImage("/images/character/patient/josei_11_gray.png");
  initRevealTextMessage("女の子「いい縁側ですね 気に入りました」"); //ここで呼び出し
})();
```

こんな感じ ↓↓
![画面収録 2022-09-23 20.55.09 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455043/3c9b4c2d-9a12-a20f-bf91-4cb3dce41f89.gif)
おお〜、それっぽいですね！なんだか懐かしいです笑

<a id="anchor3"></a>

## 次にやること

現時点では一文だけしか表示させられないので、まだノベルゲームには程遠いですね。。。
次回は、テキストを配列にして複数のテキストを表示させられるようにすること、
またクリック等でテキスト送りをする挙動を実装していきたいです。
（まだまったく仕様を考えていませんが…😓）

<a id="thanks"></a>

## 謝辞

使用素材
背景画像 [みんちりえ](https://min-chi.material.jp/)様
キャラクター画像 [わたおきば](https://wataokiba.net/)様

コードなど諸々の参考
[Drew Conley](https://gamedevshift.com/pizza-legends)様
https://gamedevshift.com/pizza-legends

<a id="articles"></a>

## 連載一覧

> [JavaScript で本格的なノベルゲームを作ってみる #1](http://qiita.com)