プログラミング未経験だけどゲームつくる - 4 : テキストを一文字ずつ出してみる【LOVE2d】

こんばんは、サトウダイスケです。
本業は映像制作と野外映画フェスです。

本当はフェスでインタラクティブな美術設計したい関係で、ラズパイいじながらPythonでもやろうかなと思ってたんですけど、Pixel Art Park - 日本最大級のドット絵の祭典で好きな作家さんたちを見てたら自分も何かゲームつくってみたくなってLOVE2dはじめました。

さて、前回は猫ちゃんがジャンプしたり歩き回るようになりましたが、今回はテキストメッセージを出してみたいなと思ってます。

結論から言うとまだよくわかってないです。

こちらのサイトを参考にして組み込んでみました。

function love.load()
	love.graphics.setBackgroundColor( 256, 256, 256 )
    love.graphics.setDefaultFilter('nearest', 'nearest')

    cat = love.graphics.newImage('images/neko_for_sprite.png')
    background = love.graphics.newImage('images/background.png')

    cat_walk = love.graphics.newQuad(0, 0, 16, 16, cat:getDimensions())
    cat_jump = love.graphics.newQuad(0, 0, 16, 16, cat:getDimensions())
    cat_idle = love.graphics.newQuad(0, 0, 16, 16, cat:getDimensions())

	cat_now = cat_idle

	x = 0
	
	speed = 200
	dir = 1
	right_to_left = 0
	scale = 8
	chara_w_h = 16

	walk = {}
	walk = {fps=4, num_frames=2, xoffset, timer=1/4 ,frame=1}

	jump = {}
	jump = {fps=8, num_frames=10, xoffset, timer=1/8 ,frame=1}

	local snd

	-- フォントや文字の設定
	utf8 = require("utf8")
  message_font = love.graphics.newFont("k8x12.ttf", 30)
  love.graphics.setFont(message_font)
  message01 = {"めがさめると、おいしそうなにおいがしたんだ。","なぜかうれしくなって、いっぱいはしってた。"}
  message_h = 40 -- 1行の高さ
  st = love.timer.getTime() -- 開始時刻を記録

  -- 音楽の設定
  snd_jump = love.audio.newSource("sound/jump06.wav", "static")
  snd_message = love.audio.newSource("sound/select03.wav", "static")
  snd_walk = love.audio.newSource("sound/putting_a_jar.wav", "static")
  bgm = love.audio.newSource("sound/yuuenchi.wav", "static")

  -- 音楽の再生
  bgm:play()
  bgm:setLooping(true)

end

function love.update(dt)

	if dt > 0.035 then return end	--処理落ち対策

	-- 猫が停止している表現
	if cat_now == cat_idle then
		cat_idle:setViewport(0, 0, 16, 16)
	end

	-- 猫が歩いているアニメーション表現
	if cat_now == cat_walk then
		walk.timer = walk.timer - dt
		if walk.timer <= 0 then
			walk.timer = 1 / walk.fps
			walk.frame = walk.frame + 1
			if walk.frame > walk.num_frames then walk.frame = 1 end
			walk.xoffset = 16 * walk.frame
			cat_walk:setViewport(walk.xoffset-16, 0, 16, 16)
		end
	end

	-- 猫が歩いているアニメーション表現
	if cat_now == cat_walk then
		walk.timer = walk.timer - dt
		if walk.timer <= 0 then
			walk.timer = 1 / walk.fps
			walk.frame = walk.frame + 1
			if walk.frame > walk.num_frames then walk.frame = 1 end
			walk.xoffset = 16 * walk.frame
			cat_walk:setViewport(walk.xoffset-16, 0, 16, 16)
		end
	end

	-- 猫がジャンプしているアニメーション表現
	if cat_now == cat_jump then
		jump.timer = jump.timer - dt
		if jump.timer <= 0 then
			jump.timer = 1 / jump.fps
			jump.frame = jump.frame + 1
			if jump.frame > jump.num_frames then
				jump.frame = 1
				cat_now = cat_idle
			end
			jump.xoffset = 16 * jump.frame
			cat_jump:setViewport(jump.xoffset-16, 0, 16, 16)
		end
	end

	-- キー操作による移動の計算
	local dx = 0
	if love.keyboard.isDown("right") then
		dx = speed * dt
		if dir == 1 then
			dir_switch = "left_to_right"
		end
		if cat_now ~= cat_jump then
			cat_now = cat_walk
      love.audio.play(snd_walk)     
		end
		dir = -1
	elseif love.keyboard.isDown("left") then
		dx = -speed * dt
		if dir == -1 then
			dir_switch = "right_to_left"
		end
		if cat_now ~= cat_jump then
			cat_now = cat_walk
      love.audio.play(snd_walk)
		end
		dir = 1	
	else
		if cat_now ~= cat_jump then
			cat_now = cat_idle	
		end
	end
	x = x + dx

	-- キー操作によるジャンプの計算
	if cat_now ~= cat_jump then	--ジャンプしてる最中ではないことの確認
		if love.keyboard.isDown("space") then
			love.audio.stop(snd_jump)
			love.audio.play(snd_jump)
			cat_now = cat_jump
		end
	end

end

function love.draw()

  -- love.graphics.setColor(255, 255, 255 , 0.4)
  -- love.graphics.draw(background,1,-220,0,1,1)

  love.graphics.setColor(0, 0, 0 , 255)
  love.graphics.rectangle("fill", 0, window_h/2.8+scale*chara_w_h, window_w,  window_h)

	-- 猫の座標
	love.graphics.setColor(255, 255, 255)
	if dir_switch == "left_to_right" then
		x = x + chara_w_h*scale
	elseif dir_switch == "right_to_left" then
		x = x - chara_w_h*scale
	end
	love.graphics.draw(cat, cat_now, window_w-20+x, window_h/2.8, 0, scale*dir, scale)
  -- love.graphics.draw(cat, cat_now, window_w/2-scale*chara_w_h/2+x, window_h/2.8, 0, scale*dir, scale)

	dir_switch = 0

	-- 文字出し
  love.graphics.setColor(255, 255, 255)
  message_quantity = (love.timer.getTime() - st) / 0.1  -- 表示する文字数(経過時間÷0.1秒)
  message_y = window_h-window_h/3.8 -- 1文字目を表示するy座標
  i = 1 -- 何文字目か
  for j, s in ipairs(message01) do -- message を順に処理
    message_x = math.floor(window_w/14)  -- 行の1文字目を表示するx座標(行変わりで初期化)
    for pos, code in utf8.codes(s) do
      if i > message_quantity then break end  -- 表示する文字数を超過していれば終了
      local ss = utf8.char(code) -- 文字を1つずつ取り出す
      love.graphics.print(ss, message_x, message_y) -- 表示
      message_x = message_x + message_font:getWidth(ss) -- 文字の幅だけ右にずらす
      i = i + 1 -- 忘れないように!
    end
    message_y = message_y + message_h -- 行の高さだけ下にずらす
    i = i + 5 -- 行ごとに間を置く(10文字ぶん)
  end

  
end

-- command+F5で更新する関数
love.keypressed = function(key, unicode)
  if 'f5' == key then
    love.filesystem.load('main.lua')()
    love.load()
    love.audio.play(snd_message)
    love.audio.stop(bgm)
  end
end

非効率なのでもうこんなにソースコード長いです。

  message_font = love.graphics.newFont("k8x12.ttf", 30)
  love.graphics.setFont(message_font)
  message01 = {"めがさめると、おいしそうなにおいがしたんだ。","なぜかうれしくなって、いっぱいはしってた。"}
  message_h = 40 -- 1行の高さ

まずは、love.loadで、フォントを読み込んでいます。
使用しているのは、8×12 ドット日本語フォント「k8x12」のフリーフォント。

テキストは適当です。

	-- 文字出し
  love.graphics.setColor(255, 255, 255)
  message_quantity = (love.timer.getTime() - st) / 0.1  -- 表示する文字数(経過時間÷0.1秒)
  message_y = window_h-window_h/3.8 -- 1文字目を表示するy座標
  i = 1 -- 何文字目か
  for j, s in ipairs(message01) do -- message を順に処理
    message_x = math.floor(window_w/14)  -- 行の1文字目を表示するx座標(行変わりで初期化)
    for pos, code in utf8.codes(s) do
      if i > message_quantity then break end  -- 表示する文字数を超過していれば終了
      local ss = utf8.char(code) -- 文字を1つずつ取り出す
      love.graphics.print(ss, message_x, message_y) -- 表示
      message_x = message_x + message_font:getWidth(ss) -- 文字の幅だけ右にずらす
      i = i + 1 -- 忘れないように!
    end
    message_y = message_y + message_h -- 行の高さだけ下にずらす
    i = i + 5 -- 行ごとに間を置く(10文字ぶん)
  end

テキスト出しはこちら。
冒頭の参考サイトを元に書いているのですが、ちょっと難しくなってきて理解が追いつかなくなってきました。なんとなくわかるけど。文字出しのSEをlove.audio.playすると永遠にループしてしまったり...

 message_quantity = (love.timer.getTime() - st) / 0.1  -- 表示する文字数(経過時間÷0.1秒)

現在の時刻からloadしたときの時刻を引いて0.1で割ると文字数になる...?

そこの理解は一旦置いておいて、次は当たり判定と石ころてきなものを作りたいなと思います。

この記事が気に入ったらサポートをしてみませんか?