小学生からのJavaScript講座です。
このシリーズでは、ゲームをつくりながらJavaScriptの使い方を学んでいきます。
前回、画面に文字を表示するためのクラスを作ったのですが、それをもう少しアレンジして、もっとかっこよく文字を表示できるようにしてみましょう。
今回は画面に文字を改行する方法と、一文字ずつ表示する方法を紹介します。
うーん、やっぱり長い文章を入力すると、画面からはみ出ちゃうし、一気に文字が表示されるってのもかっこ悪いな……
文字の表示の話? やっぱりそうだよね。山田先生に訊きに行ってみる?
うん、一緒に行こうよ!
前回までのプログラムについて
前回、画面上に文字を表示することができるようになりました。
しかしこの文字を表示するプログラムでは、長い文章を打ち込むと、画面の右端へはみ出してしまっています。
これを解決するには、改行できるようにする必要があります。
また前回のプログラムの場合、文字が一気に表示されてしまいかっこ悪かったです。
やはり文字は一文字ずつ順番に表示させたいですね。
では、ここからは前回のプログラムを改良していきましょう。
文字を一文字ずつ表示できるようにする
よく来たべな。今日は何だったべかな
文字の表示だよ
そうそう、画面からはみ出てしまうんだったべな
あと、文字を一文字ずつ表示する方法も知りたいの
そうだべか。じゃあ順番に作っていくべかな。
とりあえず、まずは文字を一文字ずつ表示する方法を覚えて、それから改行の方法を覚えるべ
では、まず文字を一文字ずつ表示できるようにしてみましょう。
前回のgame.jsをカスタマイズしていきます。
Gameクラスでは、8、40、42行目に追加しています。
Labelクラスはある程度改変しているので、前回のソースとじっくりと見比べてみてください。
game.js
'use strict';
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++;
//もしコンソールで確認したいならば以下を追加
console.log( this.frame );
//_main()を呼び出す(ループさせる)
requestAnimationFrame(this._main.bind(this));
}
//ゲームにテキストなどを表示するための関数
add( obj, x, y ) {
obj.x = x || 0;
obj.y = y || 0;
this.objs.push( obj );
}
}
class Label {
//Labelの初期設定
constructor( label ) {
this._text = '';
this._charcnt = 0;
this.label = label;
this.font = "24px 'ヒラギノ角ゴ Pro', 'Hiragino Kaku Gothic Pro', 'MS ゴシック', 'MS Gothic', sans-serif";
this.color = '#fff';
this.baseline = 'top';
this.interval = 0;
}
//Labelを表示するための関数(メインループから呼び出される)
render( ctx, frame ) {
ctx.fillStyle = this.color;
ctx.font = this.font;
ctx.textBaseline = this.baseline;
if ( this.interval === 0 ) ctx.fillText( this.label, this.x, this.y );
else {
if ( this._charcnt < this.label.length && frame%this.interval === 0 ) {
this._text += this.label.charAt( this._charcnt );
this._charcnt++;
}
ctx.fillText( this._text, this.x, this.y );
}
}
}
59〜65行目に注目してください。
ここでは文字を表示するための初期設定を書いています。
これらは、実際にラベルを表示したい時に、設定を変更することができます。
また最初に_(アンダーバー)が入力されているもの(_textや_charcnt)は、クラスの外側から設定を変更されては困るので、分かりやすくするために_(アンダーバー)を入れています。最初に_(アンダーバー)が付いているものに限っては、クラスの外側から設定を変更してはいけません。
GameクラスやLabelクラスを直して、文字が一文字ずつ表示されるようになったべよ。あとはscript.jsで、GameクラスとLabelクラスを呼び出していくべよ
さらにscript.jsからは、以下のように呼び出します。
10行目を見てください。これは文字が表示される時間の間隔を示すものです。
今回は「10」と入力しました。
この値が大きいほど間隔が広くなり(ゆっくり文字が表示される)、小さいほど間隔が短く(素早く文字が表示される)ようになります。
script.js
'use strict';
const str = '吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。';
//ゲームのオブジェクトを640×480サイズで作る
let game = new Game( 640, 480 );
//ラベルオブジェクトを作る
let label = new Label( str );
label.interval = 10;
//add()を使って、ゲームにラベルを表示
game.add( label, 0, 0 );
//ゲームスタート
game.start();
これでとりあえず一文字ずつ表示されるようになります。
しかしまだ、長い文章を入力した場合、画面右端から文字がはみ出してしまう問題を解決していません。
なので、あらかじめ決められた文字数で改行するプログラムを作ってみましょう。
文字列を改行できるようにしてみよう!
では長い文章を入力した時に、改行できるようにプログラムを作り直してみましょう。
画面の外にはみ出ちゃうのを、早く直したいよ
そうだべな。今から直すべよ
ちなみに、それぞれの役割を。
this._text[] : 表示したい文字列を代入。配列にして、添字を行数とします。
this._displayLength : 実際に画面に表示されている文字数。一文字表示されるごとに1つずつ増えていきます。
this._line : 表示する文字列の行数
this.label : 表示したい文字列
this.font : 表示したい文字列のフォント
this.color : 表示したい文字列の色
this.maxLength : 表示したい文字列の、一行の最大文字数
this.baseline : 表示したい文字列のベースライン
this.interval : 文字列を表示する速度
_(アンダーバー)が最初についているものは、クラスの外から変更されるとあまりよろしくないものです。
クラス外から変更できるものとできないものをしっかり区別しておきましょう。
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._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;
}
//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.length/this.maxLength );
//文字列の行数だけ繰り返す
for( var i=0; i<this._line; i++ ) {
this._text[i] = this._text[i] || '';
this._text[i] = this.label.substr( i*this.maxLength, this.maxLength );
//文字列の表示
ctx.fillText( this._text[i], this.x, this.y + ( i * 25 ) );
}
}
//文字を表示する間隔(はやさ)が0以外の場合、一文字ずつ表示していく
else {
if( this._displayLength < this.label.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.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に移りましょう。
Gameクラスで設定した部分も、場合によっては変更したかったりしますね。
変更したい場合は以下のソースの10、11行目のように設定します。
今回の場合では
10行目は、文字を表示する速度、
11行目は、一行に表示する最大文字数を変更しています。
script.js
'use strict';
const str = '吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニヤーニヤー泣いていた事だけは記憶して居る。';
//ゲームのオブジェクトを640×480サイズで作る
let game = new Game( 640, 480 );
//ラベルオブジェクトを作る
let label = new Label( str );
label.interval = 10;
label.maxLength = 32;
//add()を使って、ゲームにラベルを表示
game.add( label, 0, 0 );
//ゲームスタート
game.start();
実際の動きを確認したい場合はこちらから。
ちゃんと改行されてる!
すごい、綺麗に一文字ずつ表示もされてるね
まとめ
今回は文字を改行する方法と、一文字ずつ表示する方法を紹介しました。
しかしまだまだこのプログラムでは問題があります。ゲームでは文字を切り替える必要があるのです。
次回は文字を切り替えられるようにしていきましょう。
やった。文字も綺麗に表示できるようになった!
でも、キー入力やマウスクリックとかで、次の文章を表示できるようにしたいよね
そうだべな。でもそれはまた次回にするべよ
早く知りたいよー
わだずは家で音楽を聞きたいんだべ
好きな曲があるの?
いや、わだずがハマっているのはイヤホンだべ。あのコードを見ていると、いてもたってもいられなくなるんだべ
……
えっ?
このシリーズの一覧はこちら
- 小学生からのプログラミング入門。プログラミングってなぁに?
- Scratchの使い方と、ゲーム作りの基礎知識を学ぼう! 小学生からのプログラミング入門
- Scratchでじゃんけんゲームを作ろう! 小学生からのプログラミング入門
- Scratchでシューティングゲームを作ろう! 小学生からのプログラミング入門
- Scratchでピアノ鍵盤を作って音を鳴らそう! 小学生からのプログラミング入門
- テキストエディタ(Visual Studio Code)をインストールしてみよう! 小学生からのプログラミング入門
- Visual Studio Codeを日本語化してみよう! 小学生からのプログラミング入門
- JavaScriptでおみくじを作ろう! 小学生からのプログラミング入門
- JavaScriptで今月の残り日数を計算してみよう! 小学生からのプログラミング入門
- JavaScriptで画像を表示してみよう! 小学生からのプログラミング入門
- JavaScriptで画像を移動してみよう! 小学生からのプログラミング入門
- 【JavaScript】キー入力でキャラを動かしてみよう! 小学生からのプログラミング入門
- 【JavaScript】ファイルを分けて管理してみよう! 小学生からのプログラミング入門
- 【JavaScript】オブジェクトを使ってみよう! 小学生からのプログラミング入門
- 【JavaScript】ゲームのメインループを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】キャラを決まった間隔ずつ動かす! 小学生からのプログラミング入門
- HTML5とCanvasを使ってみよう! 小学生からのプログラミング入門
- 【JavaScript】迷路やRPGで使えるマップを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】マップでキャラを動かせるようにしよう! 小学生からのプログラミング入門
- 【JavaScript】クラスの概念をしっかりと理解しよう! 小学生からのプログラミング入門
- 【JavaScript】プログラム全体をクラスを使って作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】文字を表示するクラスを作ってみよう! 小学生からのプログラミング入門
- 【JavaScript】改行と一文字ずつ画面に表示する方法! 小学生からのプログラミング入門
- 【JavaScript】ノベルゲーム風にキー入力で文字を切り替える方法! 小学生からのプログラミング入門
- JavaScriptでRPGを作ろう!スマホにも対応したゲームの作り方
- webpackを使ってゲームエンジンを作ろう!(JSライブラリの作り方)
- WindowsにPythonをインストールしてみよう!小学生からのPython入門
- MacにPythonをインストールしてみよう!小学生からのPython入門
- Pythonでじゃんけんゲームを作ってみよう!小学生からのPython入門
- Pythonのtkinterを使って、ウィンドウを表示してみよう!
- Pythonのtkinterで、画像つきのおみくじゲームを作ろう!