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

スポンサードリンク

関連コンテンツ

オススメ記事

キャラを決まった間隔ずつ動かすよ!

小学生からのJavaScript入門。キャラを決まった間隔ずつ動かす!

小学生からのプログラミング入門講座(にゅうもんこうざ)、第8弾です。 前回は、キャラクターの画像(がぞう)をスムーズに動かす方法でしたが、スピードが速すぎたので、画像の移動間隔(かんかく)を短く

【Android Studio】アプリ開発の基本とそれぞれのファイルの役割を覚える。

iPhone持ってないみなさん、一緒にAndroidアプリ開発しましょう。@It_is_Rです。 Androidアプリ開発、5回目となりました。 今回は Android Studio でアプリ

小学生から始めるプログラミング入門。プログラミングってなぁに?

2020年から小学校でプログラミングが必修(ひっしゅう)となりますが、「プログラミングなんてやったことないし、何から初めていいのか分からない」といった方も多いのではないでしょうか。 プログラミン

java

Javaのクラスとメソッドの違いとは?ゲーム風に解説。

この頃小説を読んでいなく、何か読みたいなと思っている@It_is_Rです。 Javaを勉強し始めたばかりの人は、何やら難しい単語に混乱する人も多いでしょう。その中で、クラスとメソッドって一体何が

【Android Studio】じゃんけんゲームの作り方(アプリ開発の基本)

限りなくじゃんけんが弱い@It_is_Rです。 Androidアプリ開発、11回目となりました。 そろそろ何かアプリを作ってみたいですよね。基本は大事ですが、一番つまらないですね。 そこ

【Android Studio】Button(ボタン)を作る基本中の基本。

ボタンを作る基本中の基本ですが、ボタンを作ること自体が基本中の基本です。@It_is_Rです。 タイトルなんてどうだっていいんです。肝心のなのは真心です。 Androidアプリ開発、7回目とな

ファイルを分けるべよ!

小学生からのJavaScript入門。ファイルを分けて管理してみよう!

小学生からのJavaScript入門講座(にゅうもんこうざ)、第5弾です。 前回はりこちゃんを方向キーで操作(そうさ)することができるようになりました。 しかしプログラムを作ってくと、コンピュ

【Bootstrap 4】パンくずリスト(Breadcrumb)を作ってみよう!

Bootstrap4の使い方、第4回目となりました。 サイトを作っていると必然的に必要になるのがパンくずリストです。 パンくずリストは、サイト訪問者が今どのページにいるのかということを分かりや

WordPress | ツイート数やシェア数付きのSNSシェアボタンを自作しよう!

最近SNSシェアボタンを作り直した@It_is_Rです。 せっかく作ったんだから、シェアするのだよ、みんな。 そこで今回は、Twitter や Facebook、GooglePlus、はてな

【Bootstrap 4】badgeを使ってテキスト横に小さな文字を入れる方法

前にBootStrap4の記事を書いていましたが、日にちが空いてしまいましたね。@It_is_Rです。 前回は全体的な機能とアラートの使い方を紹介しました。 今回はバッジの使い方を紹介していき

コメントをどうぞ!

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