ゲームを作ろう! 脱出ゲームその1 文字を一文字ずつ表示


多少分岐はあっても、読むこと主体のノベルゲームを作ってみます。
イメージとしては「かま●たちの夜」みたいなアレです。
これまではボタンを表示して、ボタンをクリックして先に進む形式にしていましたが、キーボードのキーのみで読み進めるゲームを作ってみましょう。
できればセーブ機能も入れたいですね。

……まず、ノベルを作らないと話にならないじゃないか。w
ひとまず、どうでもいいから何かしら文章を書きましょう。

GraphicsWindow.Width = 800
GraphicsWindow.Height = 600
GraphicsWindow.Title = "novel"

windowX = 15
windowY = 15

backsky = Shapes.AddImage("D:\sora.jpg")

GraphicsWindow.BrushColor = "WhiteSmoke"
GraphicsWindow.PenColor = "DimGray"

window = Shapes.AddRectangle(GraphicsWindow.Width - windowX * 2, GraphicsWindow.Height - windowY * 2 )
Shapes.SetOpacity(window, 70)
Shapes.Move(window, windowX, windowY)

GraphicsWindow.BrushColor = "SteelBlue"
GraphicsWindow.PenColor = "SteelBlue"
sankaku1 = Shapes.AddTriangle(windowX, windowY, windowX, windowY*2, windowX*2, windowY)
sankaku2 = Shapes.AddTriangle(windowX, GraphicsWindow.Height - windowY, windowX, GraphicsWindow.Height - windowY*2, windowX*2, GraphicsWindow.Height - windowY)
sankaku3 = Shapes.AddTriangle(GraphicsWindow.Width - windowX, windowY, GraphicsWindow.Width - windowX, windowY*2, GraphicsWindow.Width - windowX*2, windowY)
sankaku4 = Shapes.AddTriangle(GraphicsWindow.Width - windowX, GraphicsWindow.Height - windowY, GraphicsWindow.Width - windowX, GraphicsWindow.Height - windowY*2, GraphicsWindow.Width - windowX*2, GraphicsWindow.Height - windowY)

GraphicsWindow.PenColor = "Black"
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.FontSize = 24
GraphicsWindow.FontName = "Rounded M+ 1p medium"

text[1][1] = "「キミ、名前は?」"
text[1][2] = "ぼくは彼女に尋ねた。"
text[1][3] = "「わたし? わたしの名前は、マオーコ」"
text[1][4] = "「マオーコ? 変わった名前だな……」"
text[1][5] = "「そんなことないわ。なら、あなたの名前は何?」"
text[1][6] = "「ぼくはユーテルヴォガリア・シャフォンレーム。長いからユーシャ"
text[1][7] = "と呼ばれている」"
text[1][8] = "「あなたこそ変な名前じゃない。わたしの名前は由緒正しいのよ。"
text[1][9] = "魔王の血筋に代々受け継がれていて……」"
text[1][10] = "「まさか、魔王の娘だから『魔王・子』なんてダサいネーミング……"
text[1][11] = "えっ、ま、魔王!?」"
text[1][12] = "ぼくは驚いた。"
text[1][13] = "まさか、こんな所に魔王の娘が居るなんて。"

For i = 1 To 13
textShape[1][i] = Shapes.AddText(text[1][i])
Shapes.Move(textShape[1][i], 20, 20 + (35 * (i - 1)))
EndFor

Timer.Tick = yajirusi
Timer.Interval = 1000

GraphicsWindow.BrushColor = "LightCyan"
GraphicsWindow.PenColor = "MidnightBlue"

Sub yajirusi
  Shapes.HideShape(next)
  next = Shapes.AddTriangle(750, 550, 750, 570, 770, 560)
  Shapes.Animate(next, 10, 0, 1000)
EndSub

ノベル

……意味がわからない文章ですね。
背景はjpg画像です。適当に描きました。
Shapeオブジェクトでちょっとした飾りみたいなものも付けています。

text[1][1]は、「1ページ目の文章の1行目」という意味で名前を付けています。
だから上に載せた文章は、1ページ目の1〜13行目の文章ということです。
For構文で文章をまとめてShapeオブジェクトにした後に、Shapes.Moveで移動させています。移動の際は行ごとにy座標を35ピクセル移動させるようにしました。

また、今回は自家製 Rounded M+という、フリーフォントを使わせていただきました。
どのフォントにしても、サイズを大きめにしないと、文字の輪郭がギザギザして見にくくなりますので(「アンチエイリアス」で検索してください)、フォントサイズを24と大きめにしました。

最後のタイマーイベントは、右下の矢印をアニメーションさせるためのものです。
この矢印が表示されている時は次ページへ移動できる、という意味で付けました。

今回はまず、
「文字を一文字ずつ表示していく」
方法を考えます。
上の画面を実行すると、13行目まで一気に表示されます。
ですがこの手のノベルゲームは、1文字ずつ順に表示される演出が付いているのがほとんどです。
どうやったら1文字ずつ表示できるでしょうか。
ここでは、Textオブジェクトを使ってみます。

一行目は
text[1][1] = "「キミ、名前は?」"
です。
『「キミ、名前は?」』という表示部分はカギかっこ等の記号を含めて9文字あります。
この9文字を順に表示するのだから、一度文章を文字ごとにバラバラにして、それぞれを表示していくことになりそうです。
(なお、テキストの長さ、つまり文字数はText.GetLength(text)で求められます)

Text.GetSubText(text, start, length)
を使ってみましょう。
startが開始位置、lengthが文字の長さです。

Text.GetSubText(text[1][1], 1, 1)……text[1][1]の1文字目『「』
Text.GetSubText(text[1][1], 2, 1)……text[1][1]の2文字目『キ』
Text.GetSubText(text[1][1], 3, 1)……text[1][1]の3文字目『ミ』

……を取得できます。
これらを、少しずつタイミングをずらしながら配置すれば良さそうですね。
文字数について新たに「n」という変数を使い、For構文で1行分、書いてみました。

For n = 1 To Text.GetLength(text[1][1])
  textShapemoji[1][1][n] = Shapes.AddText(Text.GetSubText(text[1][1], n, 1))
  Shapes.Move(textShapemoji[1][1][n], 20 + (24 * (n - 1)), 35)
  Program.Delay(50)
EndFor

最後のProgram.Delay(50)で、文字の表示が1文字につき50ミリ秒かかるようになります。
これは1行分なので、これを13行分にすると……

For i = 1 To 13
  For n = 1 To Text.GetLength(text[1][i])
    textShapemoji[1][i][n] = Shapes.AddText(Text.GetSubText(text[1][i], n, 1))
    Shapes.Move(textShapemoji[1][i][n], 20 + (24 * (n - 1)), 20 + (35 * (i - 1)))
    Program.Delay(50)
  EndFor
EndFor

まとめて、こうなります。
実行してみると、50ミリ秒だと、「音読するならこれくらい」という感じになります。
多分、もっと早く読みたいという人も居るでしょう。
30〜50ミリ秒くらいの間で調整したい感じですか。
これはプレイヤーが調整するようにしても良いかもしれませんね。設定画面を出して。

For i = 1 To 13
  For n = 1 To Text.GetLength(text[1][i])
    textShapemoji[1][i][n] = Shapes.AddText(Text.GetSubText(text[1][i], n, 1))
    Shapes.Move(textShapemoji[1][i][n], 20 + (24 * (n - 1)), 20 + (35 * (i - 1)))
    Program.Delay(50)
  EndFor
  Program.Delay(500)
EndFor

ちなみに、上のように更にProgram.Delayを入れれば、1行毎に少し時間を置いて表示ができます。

これで1ページ分の表示がなんとかできました。
次は、2ページ目の表示について。

次:その2 キーを押して読み進める


▲TOPへ戻る