Love2D(LÖVE)로 플랫포머 게임 개발해보자! (4) 이미지 불러오기, 이동
??? : 이 사람은 한달에 한번씩 강좌를 쓰네....
그도 그럴게 최근 이것저것 손을 벌려보고 있습니다. 하지만 늘 뭔갈 해도 시간이 부족한데, 어디서 시간이 새나가는지 한번 검토좀 해봐야겠습니다...
각설하고, 오늘의 강좌 시작합니다.
이미지 불러오기
결국 게임을 만들거면 이미지가 필요할 것입니다. 물론 이미지 없이 도형만 이용해서 게임을 만들수도 있겠지만, 절대다수의 사람들은 자신만의 세계관을 가지고 그걸 표현하고자 할 것입니다. 그럼 이미지는 어떻게 불러오는가?
이를 진행하기 위해 loadImage.lua 파일을 생성했다. 코드는 아래와 같다.
-- loadImage.lua
function love.draw()
coffee=love.graphics.newImage("불러올 이미지 경로")
--love.graphics.draw(이미지, x, y, 각도, x비율, y비율, x원점, y원점)
love.graphics.draw(coffee, 64, 64)
end
이후 main.lua는 아래와 같이 코드를 끌어왔다.
-- main.lua
function love.load()
require "loadImage"
end
실행 결과는?
이미지와 같은 느낌으로 결과물이 나올 것이다.
그렇다. 이게 끝이다. 경로를 먼저 불러온 뒤, 찾아낸 파일을 그려내면 된다. 이런 방식이면 폴더를 불러온 뒤, 폴더 뒤에 각 이미지 파일명만 따로 지정해주는 식으로도 응용이 가능할 것으로 보인다.
여기서 유의할 점은 경로를 입력할 땐 기존 다른 코드파일 불러올때마냥 하는게 아니라 /로 구분을 확실히 지어줘야 한다는 것이다. "C/Users/...." 같은 식으로 말이다. 그리고 이미지 크기를 조절 못하냐고 물어볼 수 있는데, love.graphics.draw의 매개변수 중 5~6번째(각도 이후)가 이미지의 크기 비율을 조정하는 값이니 이를 참고하면 좋을 것 같다. 기본 1.0에 점점 줄이거나 늘리는 식이다.
캐릭터 이동
이제 캐릭터 이동을 구현해보자.
필자는 지난 강좌에서 사용했던 클래스 폴더에 새 파일을 만들었다. 이름은 movableSquare.lua다. 지금부터 이 코드를 이용해 아까 호출한 이미지를 움직이게 해볼 것이다. 거두절미하고 작성한 코드부터 보자.
-- movableSquare.lua
Square=Object:extend()
function Square:new(x, y, sx, sy, speed)
self.x=x
self.y=y
self.sx=sx
self.sy=sy
self.speed=speed
self.leftInput=false
self.rightInput=false
self.upInput=false
self.downInput=false
end
function Square:draw()
imgSrc=love.graphics.newImage("Sources/Sprites/Refresh0529_16.png")
love.graphics.draw(imgSrc, self.x, self.y, 0, self.sx, self.sy)
end
function Square:update(dt)
-- 방향키 입력에 따른 이동 처리
if self.leftInput then
self.x=self.x-self.speed*dt
self.leftInput=false
print("leftOff")
end
if self.rightInput then
self.x=self.x+self.speed*dt
self.rightInput=false
print("rightOff")
end
if self.upInput then
self.y=self.y-self.speed*dt
self.upInput=false
print("upOff")
end
if self.downInput then
self.y=self.y+self.speed*dt
self.downInput=false
print("downOff")
end
end
function Square:keypressed(key)
--키 입력 처리
if key=="left" then
self.leftInput=true
print("leftOn")
end
if key=="right" then
self.rightInput=true
print("rightOn")
end
if key=="up" then
self.upInput=true
print("upOn")
end
if key=="down" then
self.downInput=true
print("downOn")
end
end
참고로 이 코드를 사용하기 위해선 classic.lua가 필요하다. 이후 main.lua는 아래와 같이 설정해준다.
--main.lua
function love.load()
Object=require "classic"
require "StudyAboutClass.movableSquare"
rPlr=Square(64, 64, 1, 1, 1000)
end
function love.update(dt)
rPlr:update(dt)
end
function love.draw()
rPlr:draw()
end
function love.keypressed(key)
rPlr:keypressed(key)
end
실행결과는 방향키를 입력하면 이미지가 해당 방향으로 이동할 것이다. 꾹 누를 경우의 대응이 안되는데 이는 좀 더 알아보고 점프 구현하면서 수정하는 시간을 가져보겠다.
이번에는 함수 단위로 코드를 설명해보고자 한다.
Square:new()
코드의 기본 정보를 초기화하는 부분이다. 여기선 이미지를 그려내기 위한 정보 x, y, sx(x비율), sy(y비율), 그리고 이미지의 이동속도를 설정할 speed를 초기화했다. 그리고 각 입력에 대한 정보를 얻기 위해 방향Input를 false로 초기화했다. 이에 대해서는 아래 keypressed부분에서 후술하겠다.
Square:draw()
이미지를 불러오는 부분이다. 당장 위에서 잘 실행했다면 그대로 잘 이행할 수 있으리라 믿는다. 특별한 차이점이라면 이미지의 위치나 비율을 self에 초기화된 값을 사용한다는 점 정도 되겠다.
Square:keypressed()
키 입력을 받아내는 함수다. key라는 매개변수를 받고 있으며, 이 key에는 플레이어가 입력한 키 정보가 저장된다. 비교 가능한 키에 대한 정보는 이곳에 정리되어있고, 위와 같이 if문의 형태로 비교를 진행해준다. 그리하여 만약 키보드 입력이 들어왔다면 Square:new()에서 선언했던 방향Input 값을 true로 변경해준다.
Square:update()
이후 이미지의 이동은 여기서 처리가 된다. 만약 방향Input값이 참일 경우, 오브젝트를 스피드*델타타임만큼 이동시킨 뒤 방향Input을 다시 false로 만들어주면 이동 처리가 끝난다.
왜 굳이 복잡하게?
여기서 의문이 하나 들 것이다. keypressed에서 이동을 처리하면 될 것이지 왜 굳이 keypressd와 update로 코드를 나눈 것일까? 그 이유는 각 내장함수별로 수행할 수 있는 기능이 다르기 때문이다. keypressed는 키를 입력받을 수 있지만 델타타임, 즉 dt를 입력받을 수 없다. dt가 필요없다면 keypressed에서 추가 코드를 작성해도 괜찮겠지만, 캐릭터를 프레임 단위로 이동시키기 위해서 입력만 받게 됐다. 반대로 update는 델타타임을 활용할 수 있지만 키를 입력받을 수 없다. 그래서 keypressed에서 키 입력을 받아낸 뒤, 이를 받아낸 정보를 기반으로 코드를 수행하게끔 코드를 분리시켰다.
love..draw같은 다른 코드들도 마찬가지다. 각 내장함수마다 제공하는 기능이 다르고, 수행 가능한 코드가 다르다. 그러므로 각 기능마다 어떻게 코드를 분리시키고 또 어떻게 조화시키는지가 love2d의 핵심이라고 말할 수 있겠다.
오늘의 강좌는 이쯤해두고 다음에는 점프 및 판정을 구현하는 시간으로 찾아오겠다.