プログラミング未経験だけどゲームつくる - 3 : キャラクターが歩いて向きを変える【LOVE2d】

こんばんは、サトウダイスケです。
最近夜中はLOVE2dをいじくりまわすのが日課になってきました。

さて、前回はよく使う関数等をモジュール化するという話だったんですけど、言語初心者の僕にはオブジェクト指向やらクラスやインスタンスやら継承やらはちょっとすぐにはわからなかったので取り敢えずそれっぽく動くのを目指します。

取り敢えず、猫ちゃんが歩いたり振り向いたり静止するようになりました。

function love.load()
	love.graphics.setBackgroundColor( 256, 256, 256 )
    love.graphics.setDefaultFilter('nearest', 'nearest')
    cat = love.graphics.newImage('images/neko_for_sprite.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

	snd = love.audio.newSource("sound/jump06.wav", "static")

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

	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

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
		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
		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)
			love.audio.play(snd)
			cat_now = cat_jump
		end
	end

end

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

たぶん汚いソースですがお許しを。

	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}

前回の歩いたりジャンプしたりしている変数をテーブルというものに入れてみました。time=1/fpsと本当はしたいのですが、エラー出るのでこの中では使えないみたいです。おいおいロジック勉強します。

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

前回はずっと猫ちゃんがその場で歩きつづけていたので、

キー操作がなかった場合は静止するようにしました。cat_nowがcat_idleの場合は静止画です。

-- キー操作による移動の計算
	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
		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
		end
		dir = 1	
	else
		if cat_now ~= cat_jump then
			cat_now = cat_idle	
		end
	end
	x = x + dx

やっとゲームっぽくなってきましたが、左と右に動くようにしました。

最初は向いた方向が変わらずバックをするマイケルになってしまったので、向きをdirで今の方向で把握。1が左向き / -1が右向きです。

dir_swtichで振り向いた瞬間を判断しています。わかりやすいように文字列で「left_to_right」「right_to_left」を向いたときに一度だけ格納しています。なぜ向いた瞬間が知りたいかというと、画像がズレてしまうからです。

これを思い出した。


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

振り向き際に一度だけx座標をscale×16px分ズラしています。
画像の反転自体はscale*dirで。

それっぽくはなってきましたかね。

小さな石を避けるゲームくらいならできそうな気がしてきました。
当たり判定でジャンプしたときに座標変えたり、画面をスクロールしたり、やることはまだまだありそうだけど...

次回は画面に文字を出してみたいと思います。

おやすみです。









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