메뉴 건너뛰기

창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳

-- 플레이어 위치를 저장하는 변수
-- 초기 시작지점은 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 인터프리터도 없고 그걸 깔지도 않으시겠죠.

그러므로 리눅스 환경에서의 구동 스크린샷을 보여드리겠습니다. (본 글에는 포함되어 있지 않음.)

조회 수 :
752
등록일 :
2013.09.17
08:33:59 (*.209.135.92)
엮인글 :
게시글 주소 :
https://hondoom.com/zbxe/index.php?mid=study&document_srl=703465
List of Articles
번호 제목 글쓴이 날짜 조회 수
145 이미지 그리는 방법: 2편. 부제: 쿼드! 노루발 2013-09-17 819
144 이미지 그리는 방법 1편 노루발 2013-09-17 812
» Lua 소코반: 목표 지점을 만들고, 상자가 모두 옮겨지면 게임을 끝내자! 노루발 2013-09-17 752
142 Lua 소코반: 상자를 만들고 옮기고 상자와 상자가 겹치거나 상자와 벽이 겹치지 않게 해 보자! 노루발 2013-09-17 677
141 Lua 소코반: 벽을 뚫고 나가지 않게 해보자! 노루발 2013-09-17 695
140 Lua 소코반: 플레이어를 그리고 움직이게 해보자 노루발 2013-09-17 757
139 Lua 소코반: 맵을 뿌리자. 노루발 2013-09-17 832
138 소코반: 맵을 초기화하자. 노루발 2013-09-17 588
137 [Love2D] 일단 뭔가 해보자 노루발 2013-09-17 455
136 Love2D: 콜백 함수들 노루발 2013-09-17 537
135 love.graphics.print 한국어 출력 노루발 2013-09-17 429
134 Love2D를 사용하기 위한 Lua 강좌: 변수형 노루발 2013-09-17 446
133 Love2D를 사용하기 위한 Lua 강좌: 코딩 스타일, 변수 노루발 2013-09-17 584
132 Love2D를 사용하기 위한 Lua 강좌: 입출력과 기본 노루발 2013-09-17 701
131 Love2D? 개요, 설치, 실행. 노루발 2013-09-17 462
130 멘탈붕괴의 절정을 부르는 파일입출력 노루발 2013-09-17 273
129 [Lua] Split 노루발 2013-09-17 359
128 love.update(dt) 에서 버벅이는 현상. 노루발 2013-09-17 255
127 [Lua] 테이블 노루발 2013-09-17 1422
126 cocos2d-x CCMenuItem 자신을 지웠을 때 생기는 에러 똥똥배 2013-09-13 441