はじめに
素の JavaScript でノベルゲームを作ってみようと思いたちました。
・ゲームの中では比較的簡単そう
・昔よく遊んでいたのでノスタルジーを感じる
・作りたいゲームの構想があるので、まずはその土台にしたい
といった理由です。
GitHub も上げておきますので、ぜひ「ここが変だよ」「ここはこうした方がいい」などアドバイス頂けたら嬉しいです ✨
目次
まずは画像を表示させてみる
画像の描画は canvas で作ることにします。
当初、ひとつの canvas に対して背景・キャラクターを表示させようとしたのですが、
描画の順番などに気を使う必要があったりが面倒な気がしたのと、
単純にレイヤーが分かれているほうが後々楽そうだと思ったので canvas をふたつ使うことにしました。
<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 で適当に整えます。
背景画像はみんちりえ様から、
キャラクター画像はわたおきば様
より使用させていただいております。素晴らしい絵をありがとうございます!
//読み込み時に実行される関数
(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);
});
}
とりあえず関数で作っていき、なんかごちゃごちゃしてきたなーと思ったらクラス構文でまとめ直すかもしれません。
なんかこれだけで雰囲気出てますね!いい感じです:)
テキストを表示させてみる
ノベルゲームなのだから、テキストが表示されなければ話になりません。
テキストはとりあえずソースコードにベタ打ちしておきます。仕様はまったく考えていないのですが、後で修正するとしてとりあえず作っていきます。
//テキストを読み込み
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 から、それを呼び出します↓↓
//読み込み時に実行される関数
(function () {
drawBGImage("/images/background/田舎の家の縁側(日中).jpg");
drawCharaImage("/images/character/patient/josei_11_gray.png");
initRevealTextMessage("女の子「いい縁側ですね 気に入りました」"); //ここで呼び出し
})();
こんな感じ ↓↓
おお〜、それっぽいですね!なんだか懐かしいです笑
次にやること
現時点では一文だけしか表示させられないので、まだノベルゲームには程遠いですね。。。
次回は、テキストを配列にして複数のテキストを表示させられるようにすること、
またクリック等でテキスト送りをする挙動を実装していきたいです。
(まだまったく仕様を考えていませんが…😓)
謝辞
使用素材
背景画像 みんちりえ様
キャラクター画像 わたおきば様
コードなど諸々の参考
Drew Conley様
https://gamedevshift.com/pizza-legends