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|ノベルゲーム風にキー入力で文字を切り替える方法!

スポンサードリンク

関連コンテンツ

オススメ記事

webpack-dev-serverの基本的な使い方と設定方法の詳しい解説

あとで見ようとブラウザのタブを開きすぎて、どれがどれだか分からなくなる@It_is_Rです。 webpack-dev-serverを使えば、とても簡単にwebpackでの開発サーバーを立ち上げる

【Android Studio】開発したアプリの実機テストを行う方法。

どうも、頭がすっからかんの@It_is_Rです。 やかましいわ。 今回は Android Studio で実機テストする方法を紹介します。 これからアプリ開発をしていく上で必要不可欠な実機テ

wordpress

WordPress管理画面のテーマカスタマイザーに独自の項目を追加。

WordPressみたいに私自身の人生もカスタムできたらいいのに。@It_is_Rです。 WordPressのカスタマイズは、公開しているサイトだけではありません。 管理画面をカスタマイズする

【Gitの使い方 – その5】リモートリポジトリ(GitHub)へPushしてみよう!

現在、新曲熱意制作中の@It_is_Rです。 さて、Gitの使い方5回目の今回は、GitHubのリモートリポジトリを作成し、そこにローカルリポジトリをPushする方法を紹介します。 [se

HTML5とCanvasを使うべ!

小学生からのJavaScript。HTML5とCanvasを使ってみよう!

小学生からのプログラミング講座(こうざ)、第9弾です。 これまでの講座(こうざ)では、JavScriptの基本(きほん)について学び、キャラクターの操作(そうさ)ができるようになりました。 こ

wordpress

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

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

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

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

WordPress|ショートコードの作り方&使い方。確実に使いこなす為のガイド。

前回、WordPressで、特定のカテゴリ一覧を表示する方法について書きました。 改めまして、@It_is_Rです。 特定のカテゴリ一覧を表示したとき、ショートコードというものを使いましたが、

Swift

【Xcode7】Swift2使ってみた。playgroundで遊びながら覚える。

最近は押入れの中で寝るのが日課の@It_is_Rです。 押入れは寝心地がいいです。部屋も押入れ分だけ広くなるし。 SwiftはAppleが出しているプログラミング言語です。Swiftを使うこと

enchant.js100行未満!!本格シューティングゲーム作り方。

昨日歩き回ったせいで、足がかなり痛い@It_is_Rです。 さて、今回はenchant.jsのネタです。enchant.jsを使うと、javascriptのプログラムがものすごく簡単に書けてしま

コメントをどうぞ!

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