1. HOME
  2. »
  3. プログラミング・Web
  4. »
  5. JavaScript
  6. »
  7. JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

小学生からのJavaScript講座です。

前回、文字を一文字づつ表示させる方法と改行の方法を紹介しました。
今回はこのプログラムに、キー入力によって文字を切り替えられる機能をつけてみましょう。

アル

アル

ゲームはやっぱりキー入力で順番に物語を読んでいきたいよね


りこ

りこ

今日はそれを教えてもらえるんでしょ? 山田先生のところに行ってみようよ!


アル

アル

うん!

目次
  1. 前回までのプログラムについて
  2. 配列を使って文章を作っていこう
  3. 配列からのデータを表示できるようにしてみよう!
  4. 文字を切り替える関数を作ろう
  5. 全体のソース
  6. まとめ

前回までのプログラムについて

前回までで、文字を一文字ずつ表示させ、改行するプログラムができています。

javascript

山田

山田

こんなプログラムだったべな……でも、長い文章を入力した場合、画面が文字で埋まってしまうんだべよ


りこ

りこ

そうならないようにキー入力で次の文章に切り替えられるようにして、一文ずつ表示されるようにしたいね!

配列を使って文章を作っていこう

文字を切り替えられるようにするには、配列(はいれつ)を使って文章を入力しておくと便利です。

山田

山田

小学生からのJavaScript。迷路やRPGで使えるマップを作ってみよう!で紹介した、配列の使い方は覚えてるべか?


アル

アル

そういえば、そんなのがあったような……


山田

山田

忘れてしまったならば、そのページで復習してからこの先へ進んでいくべよ

まず、配列を使わない場合、文字を変数に代入するには以下のようにします。

const str = '吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。';

上を配列を使うとこのようになります。
ここでは、切り替えたい文章ごとに区切っています。

const str = [
	'吾輩は猫である。',
	'名前はまだ無い。',
	'どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。'
];

アル

アル

配列って、ジャニーズのメンバーを覚えさせておくだけじゃなくて、こんな使い方もできるんだね。


りこ

りこ

配列の何番目かによって文字を切り替えるのね!

上の配列を使った例では、つまりこのように代入されていることになります。

str[0] : 吾輩は猫である。
str[1] : 名前はまだ無い。
str[2] : どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。

つまり、配列の添字(そえじ)を指定することで、文字が切り替わるというふうになります。
なので、スペースキーで文字を切り替えたい時は、スペースキーが押された時に添字の数値を1増やすというふうに作ります。

配列からのデータを表示できるようにしてみよう!

このままだとまだ画面に文字は表示されません。
game.jsファイルをなおして、画面に配列からのデータを表示できるようにしてみましょう。

前回作ったgame.jsファイルのLabelクラスを変更していきます。
変更した場所は5,6行目、19行目、23行目、30行目、33行目です。

//Labelクラス
class Label {
  //Labelの初期設定
  constructor( label ) {
    //表示している場所の行数(追加)
    this._visibleLine = 0;
    //〜省略〜
  }
 
  //Labelを表示するための関数(メインループから呼び出される)
  render( ctx, frame ) {
    ctx.fillStyle = this.color;
    ctx.font = this.font;
    ctx.textBaseline = this.baseline;
 
    //文字を表示する間隔(はやさ)が0の場合は、文字を一気に表示
    if ( this.interval === 0 ) {
      //表示する文字数を、1行に表示する最大の文字数で割り、切り上げることで、その文字列が何行になるのかが分かる
      this._line = Math.ceil( this.label[ this._visibleLine ].length/this.maxLength ); //変更
      //文字列の行数だけ繰り返す
      for( var i=0; i<this._line; i++ ) {
        this._text[i] = this._text[i] || '';
        this._text[i] = this.label[ this._visibleLine ].substr( i*this.maxLength, this.maxLength ); //変更
        //文字列の表示
        ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
      }
    }
    //文字を表示する間隔(はやさ)が0以外の場合、一文字ずつ表示していく
    else {
      if( this._displayLength < this.label[ this._visibleLine ].length && frame%this.interval === 0 ) { //変更
        this._text[this._line] = this._text[this._line] || '';
        //this.labelに代入されている文字列を、this._text[this._line]に一文字ずつ入れていく
        this._text[this._line] += this.label[ this._visibleLine ].charAt( this._displayLength ); //変更
        this._displayLength++;
        if ( this._displayLength % this.maxLength === 0 ) {
          this._line++;
        }
      }
      for( var i=0; i<this._line+1; i++ ) {
        this._text[i] = this._text[i] || '';
        ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
      }
    }
  }
}

山田

山田

上の例だとthis.label[0]を表示させていることになるんだべ


りこ

りこ

this._visibleLineには0が代入されているからだね!

実際にブラウザで見ると、このようになります。
javascript

山田

山田

ちなみに6行目でthis._visibleLineに1を代入すると「名前はまだ無い。」と表示され、2を代入すると「どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。」と表示されるんだべ


アル

アル

キー入力があったらこの数値を切り替えるっていうプログラムを作ればいいんだね?

文字を切り替える関数を作ろう

文字を切り替える命令を書いていきたいのですが、今回は文字を切り替える為の関数を作る方法にしましょう。

山田

山田

文字を切り替える関数を作っていくべ!


アル

アル

うん!


山田

山田

今回は「次へ」ということで、「next()」という関数にしてみたべ

class Label {
	//Labelの初期設定
	constructor( label ) {
		//〜省略〜
	}
	
	//次の行への切り替え機能
	next() {
		this._visibleLine++;
		this._text = [];
		this._displayLength = 0;
	}

	//Labelを表示するための関数(メインループから呼び出される)
	render( ctx, frame ) {
		//〜省略〜
	}
}

このthis._visibleLine++;で次の行へ、this._text = [];this._displayLength = 0;で、今代入されている文字や数値を初期化しています。

山田

山田

これで文章を切り替えられるようになったべ。でも3行しか入力していないべから、3回スペースキーを押すと、エラーになって何も表示されなくなってしまうべ。エラーはコンソールを見ると分かるべよ。
このエラーの回避(かいひ)方法はまた別の記事で学んでいくべ

枠内をクリックして、スペースキーを押してみてね!

全体のソース

最後に全体のソースを確認しておきましょう。

game.js

'use strict';

//Gameクラス
class Game {
	constructor( width, height ) {
		this.objs = [];

		this.frame = 0;

		//もしもwidthやheight何も代入されていなければ、320を代入する
		this.width = width || 320;
		this.height = height || 320;

		this.canvas = document.getElementById( 'canvas' );
		//canvasの横幅とたて幅
		canvas.width = this.width;
		canvas.height = this.height;

		this.ctx = canvas.getContext( '2d' );
	}

	//start()を呼び出すことで、メインループが開始される。
	start() {
		this._main();
	}

	//メインループ
	_main() {
		//背景を黒く塗りつぶす
		this.ctx.fillStyle = "#000";
		this.ctx.fillRect( 0, 0, this.width, this.height );

		//ゲームに登場するものの数だけ繰り返す
		for (let i=0; i<this.objs.length; i++) {
			//ゲームに登場するもののクラスから、render()を呼び出す
			this.objs[i].render( this.ctx, this.frame );
		}

		//フレーム
		this.frame++;

		//_main()を呼び出す(ループさせる)
		requestAnimationFrame(this._main.bind(this));
	}

	//ゲームにテキストなどを表示するための関数
	add( obj, x, y ) {
		obj.x = x || 0;
		obj.y = y || 0;
		this.objs.push( obj );
	}
}

//Labelクラス
class Label {
	//Labelの初期設定
	constructor( label ) {
		this._text = [];
		//表示している文字列の長さ
		this._displayLength = 0;
		//表示している場所の行数(追加)
		this._visibleLine = 0;
		this._line = 0;
		this.label = label;
		this.font = "20px 'ヒラギノ角ゴ Pro', 'Hiragino Kaku Gothic Pro', 'MS ゴシック', 'MS Gothic', sans-serif";
		this.color = '#fff';
		this.maxLength = 30;
		this.baseline = 'top';
		this.interval = 0;
	}

	//次の行への切り替え機能
	next() {
		this._visibleLine++;
		this._text = [];
		this._displayLength = 0;
	}

	//Labelを表示するための関数(メインループから呼び出される)
	render( ctx, frame ) {
		ctx.fillStyle = this.color;
		ctx.font = this.font;
		ctx.textBaseline = this.baseline;

		//文字を表示する間隔(はやさ)が0の場合は、文字を一気に表示
		if ( this.interval === 0 ) {
			//表示する文字数を、1行に表示する最大の文字数で割り、切り上げることで、その文字列が何行になるのかが分かる
			this._line = Math.ceil( this.label[ this._visibleLine ].length/this.maxLength );
			//文字列の行数だけ繰り返す
			for( var i=0; i<this._line; i++ ) {
				this._text[i] = this._text[i] || '';
				this._text[i] = this.label[ this._visibleLine ].substr( i*this.maxLength, this.maxLength );
				//文字列の表示
				ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
			}
		}
		//文字を表示する間隔(はやさ)が0以外の場合、一文字ずつ表示していく
		else {
			if( this._displayLength < this.label[ this._visibleLine ].length && frame%this.interval === 0 ) {
				this._text[this._line] = this._text[this._line] || '';
				//this.labelに代入されている文字列を、this._text[this._line]に一文字ずつ入れていく
				this._text[this._line] += this.label[ this._visibleLine ].charAt( this._displayLength );
				this._displayLength++;
				if ( this._displayLength % this.maxLength === 0 ) {
					this._line++;
				}
			}
			for( var i=0; i<this._line+1; i++ ) {
				this._text[i] = this._text[i] || '';
				ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
			}
		}
	}
}

script.js

'use strict';
 
const str = [
	'吾輩は猫である。',
	'名前はまだ無い。',
	'どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。'
];

//ゲームのオブジェクトを640×480サイズで作る
let game = new Game( 640, 480 );
 
//ラベルオブジェクトを作る
let label = new Label( str );
label.interval = 5;
label.maxLength = 32;
 
//add()を使って、ゲームにラベルを表示
game.add( label, 0, 0 );

//キーボードが押された時
addEventListener( "keydown", () => {
	const key_code = event.keyCode;
	//先ほど登録したスペースキーが押された時、label.next()を実行
	if( key_code === 32) label.next();
	event.preventDefault();		//方向キーでブラウザがスクロールしないようにする
}, false);

//ゲームスタート
game.start();

まとめ

今回はキー入力で文字を切り替える方法を紹介しました。

アル

アル

これで長い文章も順番に表示できるね!


りこ

りこ

これで私と錦戸くんのラブラブノベルゲームがつくれるのね! きゃー!


アル

アル

またそれかよ……ちぇっ


りこ

りこ

夏は錦戸くんと海水浴、冬は私が編んだマフラーを錦戸くんにプレゼントするの


山田

山田

毛糸なら、わたすの毛を使って作るといいべよ。うぇ……おぇ……。はぁすっきりだべ。ほら、毛玉が出てきたべよ。


りこ

りこ

……


アル

アル

絶対いらない……

この企画の一覧はこちら

  1. 小学生からのプログラミング入門。JavaScriptでおみくじを作ろう!
  2. 小学生からのJavaScript入門。今月の残り日数を計算してみよう!
  3. 小学生からのJavaScript入門。画像の表示と移動をしてみよう!
  4. 小学生からのJavaScript入門。キー入力でキャラを動かしてみよう!
  5. 小学生からのJavaScript入門。ファイルを分けて管理してみよう!
  6. 小学生からのJavaScript入門。オブジェクトを使ってみよう!
  7. 小学生からのJavaScript入門。ゲームのメインループを作ってみよう!
  8. 小学生からのJavaScript入門。キャラを決まった間隔ずつ動かす!
  9. 小学生からのJavaScript。HTML5とCanvasを使ってみよう!
  10. 小学生からのJavaScript。迷路やRPGで使えるマップを作ってみよう!
  11. 小学生からのJavaScript。マップでキャラを動かせるようにしよう!
  12. 小学生からのJavaScript。クラスの概念をしっかりと理解しよう!
  13. 小学生からのJavaScript。プログラム全体をクラスを使って作ってみよう!
  14. 小学生からのJavaScript。文字を表示するクラスを作ってみよう!
  15. 小学生からのJavaScript。改行と一文字ずつ画面に表示する方法!
  16. JavaScript|ノベルゲーム風にキー入力で文字を切り替える方法!

スポンサードリンク

関連コンテンツ

オススメ記事

VCCW

VCCW で、超簡単に WordPress のローカル開発環境を整える方法。

考えすぎて間違った方向へ進む、@It_is_Rです。 WordPress のローカル開発環境を作りたい時、 VCCW を使うと便利です。 今回は、 その方法を紹介します。 VCC

リセットCSS は何を使う? まとめ8選と2019年版ランキング

Web開発でブラウザごとの表示の違いをリセットしてくれる リセットCSS というものがあります。 しかし、何を使っていいのかと感じている人もいると思います。 今回はこの リセットCSS につい

WordPress

WordPressカスタマイズ。テンプレートのファイル構成をチェック。

二兎を追う者は一兎をも得ず。でも、三兎を追えばそのうちの一兎ぐらい得られるんじゃ無いかと思い、その努力の割に何も得られないのが@It_is_Rです。やかましいわ。 今回の記事は初のWordPre

Scratchで じゃんけんゲームを作ろう!

小学生から始めるScratch入門。じゃんけんゲームを作ろう!

小学生から始めるScratch入門です。 前回、スクラッチでシューティングゲームを作りました。 今回はじゃんけんゲームを作ってみましょう。 プロローグ [serif icon=

wordpress

【WordPress】パンくずリストをプラグイン無しで自作する方法

※追記(2018/2/12) もっと高機能になるように、改良修正しました。 人生で3回ほど死にそうになったことがある@It_is_Rです。 WordPressのパンくずリストを作

メインループを作ってみよう!

小学生からのJavaScript入門。ゲームのメインループを作ってみよう!

小学生からのJavaScript入門講座(にゅうもんこうざ)、第7弾です。 突然(とつぜん)ですが、ゲーム開発(かいはつ)の基本として大切なことってなんだったか覚えていますか? そうです。「変

JavaScriptマンガ講座。初心者でも痛いほど理解できる変数の使い方。(実践編)

押入れが部屋になっている@It_is_Rです。 今回の記事はJavaScriptマンガ講座、2回目となりました。 この企画はJavaScriptをフザケまくって覚えようというものです。

【Bootstrap 4】記事一覧ページなどで使える「カード」の使い方

Bootstrap4の使い方、第7回目です。 トップページなどを見ると、記事の一部が抜粋された記事一覧が表示されているサイトをよく見かけます。 今回はそんな記事一覧ページを作るのに便利な「カー

KSSでスタイルガイドを作る方法。インストールと使い方。

そのうちWordPressのテーマを作る方法の解説とかしたいなーと思っている@It_is_Rです。 いま準備中ですので、もうちょっとお待ちくださいねー。 そして今回ですが、KSSを使ったスタイ

小学生からのJavaScript入門。画像の表示と移動をしてみよう!

小学生からのJavaScript入門、第3弾です。 今回はゲーム開発(かいはつ)へもう一歩踏み込んでみましょう! [serif icon="aru-s.jpg" name="アル"]うーん……

コメントをどうぞ!

メールアドレスが公開されることはありません。