창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳
-- 플레이어 위치를 저장하는 변수
-- 초기 시작지점은 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
function printmap()
-- 맵을 표시하는 printmap 함수
tempstr = ""
for a = 1, 8 do
for b= 1, 8 do
tempbuffer = ""
if (map[a][b] == 0) then
tempbuffer = " "
elseif (map[a][b] == 1) then
tempbuffer = "#"
end
for c = 1, #box do
if (box[c]["x"] == b and box[c]["y"] == a) then
tempbuffer = "o"
break
end
end
for c = 1, #goal do
if (goal[c]["x"] == b and goal[c]["y"] == a) then
if (tempbuffer == "o") then -- 상자와 목표 지점이 겹친다면 @로 표시
tempbuffer = "@"
else
tempbuffer = "."
end
break
end
end
if (playerx == b and playery == a) then
tempbuffer = "P"
end
tempstr = tempstr..tempbuffer
end
print(tempstr)
tempstr = ""
end
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
while(true) do
-- 메인 무한 루프
os.execute("clear") -- 화면을 지운다. OS가 아닌 Scite 환경에서는 제대로 동작하지 않음.
printmap()
print("")
print("움직임: "..moves)
if (successed() == true) then -- 모든 상자를 목표 지점으로 옮김.
print("축하합니다!")
print("당신은 주어진 과업을 무사히 완수하였습니다!")
io.read()
return
else --아직 더 옮겨야 함! 게임이 안 끝났음...
print("어느 방향으로 이동할까요?")
print("a: 왼쪽 d: 오른쪽 w: 위 s: 아래 q: 종료 :")
choose = io.read()
if (choose == "a") then
if (map[playery][playerx - 1] == 0) then
if (boxexist(playerx - 1, playery) ~= 0) then
if (boxexist(playerx - 2, playery) == 0) then
if map[playerx - 2][playery] == 0 then
box[boxexist(playerx - 1, playery)]["x"] = box[boxexist(playerx - 1, playery)]["x"] - 1
playerx = playerx - 1
moves = moves + 1
end
end
else
playerx = playerx - 1
moves = moves + 1
end
end
elseif (choose == "s") then
if (map[playery + 1][playerx] == 0) then
if (boxexist(playerx, playery + 1) ~= 0) then
if (boxexist(playerx, playery + 2) == 0) then
if map[playerx][playery + 2] == 0 then
box[boxexist(playerx, playery + 1)]["y"] = box[boxexist(playerx, playery + 1)]["y"] + 1
playery = playery + 1
moves = moves + 1
end
end
else
playery = playery + 1
moves = moves + 1
end
end
elseif (choose == "d") then
if (map[playery][playerx + 1] == 0) then
if (boxexist(playerx + 1, playery) ~= 0) then
if (boxexist(playerx + 2, playery) == 0) then
if map[playerx + 2][playery] == 0 then
box[boxexist(playerx + 1, playery)]["x"] = box[boxexist(playerx + 1, playery)]["x"] + 1
playerx = playerx + 1
moves = moves + 1
end
end
else
playerx = playerx + 1
moves = moves + 1
end
end
elseif (choose == "w") then
if (map[playery - 1][playerx] == 0) then
if (boxexist(playerx, playery - 1) ~= 0) then
if (boxexist(playerx, playery - 2) == 0) then
if map[playerx][playery - 2] == 0 then
box[boxexist(playerx, playery - 1)]["y"] = box[boxexist(playerx, playery - 1)]["y"] - 1
playery = playery - 1
moves = moves + 1
end
end
else
playery = playery - 1
moves = moves + 1
end
end
elseif (choose == "q") then
os.execute("clear")
print("그럼 안녕!")
io.read()
return
end
end
end
코드는 요약글로,
-- 박스 목표 지점의 위치를 저장하는 배열.
goal = {}
목표지점에 관한 코드는 박스에 관한 코드와 상당히 유사합니다.
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
모든 목표 지점 위에 박스가 놓여 있는지를 확인한다.
주석이랑은 말이 살짝 다른데, 그거나 그거나...
if (goal[c]["x"] == b and goal[c]["y"] == a) then
if (tempbuffer == "o") then -- 상자와 목표 지점이 겹친다면 @로 표시
tempbuffer = "@"
else
tempbuffer = "."
end
break
end
목표 지점과 상자가 겹칠 경우, 알기 쉽게 저렇게 표시한다.
makegoal(5, 3)
makegoal(5, 6)
맵 위에 목표 지점을 만든다.
if (successed() == true) then -- 모든 상자를 목표 지점으로 옮김.
print("축하합니다!")
print("당신은 주어진 과업을 무사히 완수하였습니다!")
io.read()
return
else --아직 더 옮겨야 함! 게임이 안 끝났음...
모든 목표 지점 위에 박스가 올라가있다면 축하한다고 메세지를 보여주고 끝낸다.
이제 게임의 뼈대는 다 만들어졌습니다. 갖고 놀 수 있어요.
그리고, 방금 게임을 더 재미있게 만들기 위해서 생각난 기능이 있습니다.
첫번째는 맵 에디터와 맵 고르기 기능입니다. 맵 하나만 플레이하자니 지루하고
또 코드를 직접 뜯어고치자니 번거로우므로 맵 데이터 프로그램을 하나 만들어서 맵을 만들고
만들어진 맵을 읽어와서 플레이 할 수 있게 하는 것도 좋을 것 같고요.
또 하나는 랭킹입니다.
최대한 적은 움직임 수로 상자를 옮긴 사람 순으로 기록해서 플레이어들에게 경쟁심을 유발시키는 겁니다.
뭐.. 이런 게 생각났다는 것이지, 만들 생각은 아직 없습니다.
(언제는 무슨 맵에디터 만들 것 처럼 굴더니만!)
나중에 잉여력이 넘치면 만들어보도록 하겠습니다.
첨부 파일은 완성된 파일입니다. (본 글에는 포함되어 있지 않음.)
nokoban.lua 라는 것으로 exe가 아니라 아쉽게도 실행할 수 없습니다.
lua 인터프리터를 설치하면 PC에서도 맥에서도 리눅스에서도(제가 리눅스입니다!), 심지어 안드로이드나 ios 환경에서도 실행이 가능합니다.. 만 여러분은 lua 인터프리터도 없고 그걸 깔지도 않으시겠죠.
그러므로 리눅스 환경에서의 구동 스크린샷을 보여드리겠습니다. (본 글에는 포함되어 있지 않음.)