プログラミング未経験だけどゲームつくる - 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で。
それっぽくはなってきましたかね。
小さな石を避けるゲームくらいならできそうな気がしてきました。
当たり判定でジャンプしたときに座標変えたり、画面をスクロールしたり、やることはまだまだありそうだけど...
次回は画面に文字を出してみたいと思います。
おやすみです。
この記事が気に入ったらサポートをしてみませんか?