창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳
-- 플레이어 위치를 저장하는 변수
-- 초기 시작지점은 5, 5로 설정.
playerx = 5
playery = 5
-- 박스의 위치를 저장하는 배열.
box = {}
-- 박스 목표 지점의 위치를 저장하는 배열.
goal = {}
-- 움직인 횟수 저장
moves = 0
-- 맵 데이터를 저장하는 8*8의 2차원 배열 Map 생성
map = {}
for a = 1, 8 do
map[a] = {}
for b = 1, 8 do
map[a][b] = 0
end
end
function makebox(x, y)
-- 새 박스를 만든다.
box[#box + 1] = {}
box[#box]["x"] = x
box[#box]["y"] = y
end
function makegoal(x, y)
-- 새 목표 지점을 만든다.
goal[#goal + 1] = {}
goal[#goal]["x"] = x
goal[#goal]["y"] = y
end
function successed()
-- 모든 박스가 목표 지점 위에 놓여 있는가?
for a = 1 , #goal do
if boxexist(goal[a]["x"], goal[a]["y"]) == 0 then
return false
end
end
return true
end
-- 맵 데이터 초기화
for a = 1, 8 do
for b = 1, 8 do
if (a == 1 or a == 8 or b == 1 or b == 8) then
map[a][b] = 1
end
end
end
makebox(4,3)
makebox(4,6)
makegoal(5, 3)
makegoal(5, 6)
function boxexist(x, y)
for a = 1, #box do
if (box[a]["x"] == x and box[a]["y"] == y) then
return a
end
end
return 0
end
function love.load()
tile = love.graphics.newImage("nokoban.png")
-- 쿼드 만들기
tileq = {}
for a = 1, 6 do
tileq[a] = love.graphics.newQuad(32 * (a - 1), 0, 32, 32, 192, 32)
end
end
function love.draw()
tempbuffer = 0
for a = 1, 8 do
for b = 1, 8 do
if (map[a][b] == 0) then
tempbuffer = 3
elseif (map[a][b] == 1) then
tempbuffer = 2
end
for c = 1, #box do
if (box[c]["x"] == b and box[c]["y"] == a) then
tempbuffer = 5
break
end
end
for c = 1, #goal do
if (goal[c]["x"] == b and goal[c]["y"] == a) then
if (tempbuffer == 5) then -- 상자와 목표 지점이 겹친다면 @로 표시
tempbuffer = 6
else
tempbuffer = 4
end
break
end
end
if (playerx == b and playery == a) then
tempbuffer = 1
end
-- 그린다
love.graphics.drawq(tile, tileq[tempbuffer], (b - 1) * 32, (a - 1) * 32)
end
end
end
코드를 펼쳐 보시면 아시겠지만, 바뀐 부분은 얼마 없습니다.
이미 Lua 소코반 글에서 이것저것 해 봤으니 바뀐 부분만 간략히 설명하겠습니다.
function love.load()
tile = love.graphics.newImage("nokoban.png")
-- 쿼드 만들기
tileq = {}
for a = 1, 6 do
tileq[a] = love.graphics.newQuad(32 * (a - 1), 0, 32, 32, 192, 32)
end
end
love 게임 엔진을 로드하면서 이미지를 불러오고 쿼드를 만듭니다.
이미지는 전의 글을 참고해 주세요.
쿼드는 for 문을 돌려서 만드는데, 가로 방향으로 32씩 쪼개서 만듭니다.
쿼드 테이블은 1씩 시작하고요.
tileq[1]은 플레이어 캐릭터, tileq[2]는 벽, tileq[3]는 뚫린 공간.. 이런 식으로 나눠집니다.
function love.draw()
tempbuffer = 0
for a = 1, 8 do
for b = 1, 8 do
if (map[a][b] == 0) then
tempbuffer = 3
elseif (map[a][b] == 1) then
tempbuffer = 2
end
for c = 1, #box do
if (box[c]["x"] == b and box[c]["y"] == a) then
tempbuffer = 5
break
end
end
for c = 1, #goal do
if (goal[c]["x"] == b and goal[c]["y"] == a) then
if (tempbuffer == 5) then -- 상자와 목표 지점이 겹친다면
tempbuffer = 6
else
tempbuffer = 4
end
break
end
end
if (playerx == b and playery == a) then
tempbuffer = 1
end
-- 그린다
love.graphics.drawq(tile, tileq[tempbuffer], (b - 1) * 32, (a - 1) * 32)
end
end
end
메인 루프의 역할을 계속 실행되는 콜백이 담당하게 되었습니다.
tempbuffer를 사용해 이전에는 "#", " ", "@" 등의 문자를 뿌려줬다면
이번에는 몇 번 쿼드를 뿌릴지를 담아뒀다가 뿌리게 됩니다.
-- 그린다 부분은, 현재 좌표 * 타일의 크기를 한 위치에 그리게 됩니다.
마이너스 1을 해 주는 이유는 테이블 인덱스가 1부터 시작하니, 그대로 하면 32,32부터 그려
위와 옆쪽에 각각 한 칸 씩 공백이 생기기 때문입니다.
이것으로 보여주는 부분은 어렵지 않게 완료했습니다만, asdw를 눌러도 전혀 움직이지 않습니다.
움직이는 부분은 하나도 구현하지 않았으니까요.
다음부터는 문자를 입력하고 엔터를 눌러 움직이는 방법에서 탈피하여 키보드를 누르는 즉시 움직이게 해 보겠습니다. 역시 Love2D의 콜백을 이용해서요.
다음에 봅시다.
+
그래픽 이식이 어려워 보이지만 엄청 편하네요.
이전 코드를 복사 붙여넣기 하고 조금만 다듬으면 되니까.
사람들은
겉에 보이는 것을 보고 프로그램을 판단하는 경향이 있는 듯. 아직 완성하지 못한 프로그램이던 게임이던 쓸데없는 기대를 받는 것이
싫다면 팀 내에서 가장 그림 못 그리는 사람이 그린 그래픽을 쓰세요. 그래픽은 나중에 완성되었을 때 정식으로 바꾸면 됩니다.
그럼 사실 아무것도 하지 않았는데도 갑자기 프로젝트가 급 진전 된 것으로 모두에게 생각되고.. 크흠흠.
참고로 포팅은 이식을 뜻함. 예를 들어 원래 PC용으로 만들어진 게임을 스마트폰용으로 이식하는 것을 '게임을 포팅한다' 라고 하기도 합니다. 이 글에서는 텍스트로 만들어진 게임을 그래픽으로 이식했기 때문에 포팅이라고 하였습니다.