본문 바로가기

프로그래밍/Love2D

Love2D(LÖVE)로 플랫포머 게임 개발해보자! (2) 콘솔 로그, 코드 분리

오늘은 비교적 짧게 포스팅할 계획이다. 아직까지도 프레임워크 자체를 익히는 과정이기도 하고, 오늘 정리할 내용과 바로 다음에 정리할 클래스까지는 가야 본격적으로 개발을 시작할 수 있다고 생각하기 때문이다. 잡설은 이쯤하고 바로 시작하자.

 


콘솔

지난 정리글들을 보면 알겠지만, 기껏 개발 환경을 열심히 구축했는데, print문이 제대로 출력되지 않아 눈가리고 코딩하는 꼴이 되었을 것이다. 개발을 조금이라도 해봤으면 알겠지만 콘솔에 무언가 텍스트를 출력한다는 것 자체가 디버깅에 있어서 매우매우 중대한 역할을 수행하기 때문이다. 물론 고수는 디버거를 쓰겠다만, 그럼에도 난 이 방식을 포기할 수 없다.

 

그래서 어떻게든 콘솔을 출력시킬 방법을 찾고 있었고, 드디어 그 방법을 찾았다.

이 익스텐션을 설치해주면 된다. 이건 love2d로 개발함에 있어 도움이 될만한 기능을 구현한 익스텐션으로, 당연히 테스트 실행까지 지원하고 있다. 장점은 콘솔창을 띄울 수 있다는 것이고, 단점은 이전처럼 버튼 딸깍으로 테스트를 진행할 수는 없다는 것이다. 우선 이 익스텐션을 설치하고, 바로 설정으로 들어가자.

설정창에 들어가서, 위 이미지와 같은 옵션을 체크하면 콘솔창이 제대로 출력될 것이다. 한번 테스트를 해보자.참고로 게임 실행은 ALT+L키로 할 수 있다.

오라, 달콤한 콘솔이여.

게임을 실행하면 게임창과 함께 여분의 콘솔창이 함께 출력된다. 하지만 여기서 약간의 불편함이 생기는데, 게임 화면이 커지면 콘솔창을 제대로 볼 수 없게 된다는 것이다. 이 부분은 어쩔 수 없긴 하다. 게임이라 하면 언젠간 전체화면 환경에서 구동을 테스트해야 할지도 모르니... 그럼에도 테스트가 불편하다면 아래와 같은 방법을 제시해주고 싶다.

 

본격적인 설명에 들어가기 앞서,

이놈은 이제 지우도록 하자.

 

 

conf.lua

conf.lua는 love2d의 모듈이 실행되기 이전에 먼저 실행되어 게임의 이런저런 설정을 진행할 수 있다. vscode를 통해 주로 코딩을 해봤다면, 설정을 json의 형태로 조정하지 않던가? 그것과 비슷하다고 보면 된다.

conf.lua는 반드시 파일명을 conf.lua로 설정해야 하고, 반드시 main.lua와 같은 경로에 존재해야 한다. 위 사진과 같은 그림이 그려지면 설정은 준비된 것이다. 오늘 여기서는 간단하게 화면 크기만 조정해볼까 한다.

conf.lua에는 아래와 같이 내용을 입력해준다.

-- love2d 게임의 설정을 다루는 내장함수
function love.conf(t)
    -- 게임화면 크기 설정. 단위는 당연하게도 px다.
    t.window.width=720
    t.window.height=360
end

conf.lua에는 반드시 love.conf 함수만을 사용해야 한다. 여기서 설정에 관한 코드를 관할하기 때문이다. 여기서 t는 게임의 설정을 담은 table이다. 해당 인자를 통해 설정 항목을 불러올 수 있으니 꼭 선언하도록.

보다 자세한 설명은 공식 가이드라인을 참고하면 되겠다.

 

Config Files - LOVE

Introduction If a file called conf.lua is present in your game folder (or .love file), it is run before the LÖVE modules are loaded. You can use this file to overwrite the love.conf function, which is later called by the LÖVE 'boot' script. Using the lov

love2d.org

 

참고로 위의 설정을 저장하고 실행하면 아래와 같이 나온다.

 

 

코드 분리

사실상 love2d를 고른 이유이자 프레임워크가 가지는 가장 큰 특징이라고 할 수 있겠다. 당연하게도, love2d는 코드를 파일 단위로 구분지을 수 있다. main.lua에 모든걸 적어넣기엔 현실적으로 불가능하기 때문에, 여러 개의 코드 파일로 구분지어 이들을 불러오는 식으로 코드를 짜내려가는 편을 추천한다. 이를 통해 각 기능마다 필요한 코드들을 폴더로 구분짓고, 이들을 하나하나 불러오는 식으로 유기적으로 연결할 수 있다는 것이다. 마치 거미줄로 집을 만드는 거미와 같은 기분을 느낄 수 있지 않을까?

 

본격적인 진행을 위해 우선 외부의 코드를 2개 만들고자 한다. 하나는 리턴이 없지만 함수가 있고, 또 하나는 함수는 없지만 리턴은 있는 코드다.

 

-- localFunc.lua
function calculator(a, b, mode)
	-- 입력한 모드에 따라 사칙연산을 수행하는 코드
    if mode==0 then
        print(a,"+",b,"=",a+b)
    elseif mode==1 then
        print(a,"-",b,"=",a-b)
    elseif mode==2 then
        print(a,"*",b,"=",a*b)
    elseif mode==3 then
        print(a,"/",b,"=",a/b)
    else
        print(a,",",b,",mode==",mode)
    end
end
-- localData.lua
-- 단순히 변수의 값을 출력하는 코드
local val=30
return val

위 코드는 각각 localFunc.lua, localData.lua로 생성했고, 계층구조는 아래와 같이 설정했다.

localFunc.lua는 main.lua와 같은 위치에, localData.lua는 dataScript폴더 내에 저장한 느낌. 그럼 이제 본격적으로 이들을 불러와 활용해보자.

-- main.lua
function love.load()
    -- 외부의 스크립트는 require를 이용해 불러올 수 있음
    require("localFunc")
    -- 외부 함수는 별도의 인스턴스 선언 없이 전역함수처럼 호출 가능
    print(calculator(1,2,0))

    -- 리턴이 존재하는 스크립트의 경우, 임의의 변수에 할당해줌
    local value=require("dataScript.localData")
    -- 임의의 변수에 받아낸 리턴을 출력하는 모습
    print("value==",value)
end

 

기본적으로 내가 불러오고자 하는 스크립트는 require()를 이용해 불러올 수 있다. require()를 사용하는 코드와 같은 위치에 있는 코드라면 별도의 경로 선언 없이 해당 스크립트의 파일명만 string형으로 입력해주면 그대로 사용할 수 있다. 만약 특정 경로에 있는 코드를 불러오고자 한다면, 현재 파일의 위치에서 접근하고자 하는 파일의 경로를 입력하면 된다. 특이사항이라면 \대신 .으로 경로를 구분한다는 점.

 

위 코드의 실행 결과는 아래와 같다.

 

번외1) love.load() vs love.update()

 

 

Love2D(LÖVE)로 플랫포머 게임 개발해보자! (1) 기초 문법 정리

원래라면 지난주에 글을 썼어야 했지만.... 지스타 참여 이슈로 이번에 글을 쓰게 됐다.원래라면 바로 그래픽 연동부터 들어가려 했지만.... 생각보다 이해가 안돼서 기본부터 차근차근 쌓아가기

koilsdevelopment.tistory.com

이전 게시글에 간단하게 언급했지만, 이제 print를 확인할 수 있으니 직접 확인해볼 수 있다. love.load()와 love.update()중 어느 것이 먼저 실행될까?

우선 코드는 아래와 같이 작성했다.

function love.load()
    print("love.load() 실행!")
end

function love.update(dt)
    print("love.update() 실행!")
end

그런데 지금와서 생각해보면 당연히 load 먼저 실행되고 update가 실행될 것 같긴 한데, 그래도 결과는 직접 보는 편이 좋을 것 같아서 한번 진행해보고자 한다.

그렇게 실행한 결과....!!

love.load() 승!

예상한대로 love.load()가 먼저 실행되는 모습을 확인할 수 있다. 그런데 잠깐, 이번에는 한글이 제대로 출력이 안되네? 엄....

매번 정리글을 쓸 때마다 숙제가 하나씩 생기는 기분이다. 이번에는 한글을 제대로 출력할 수 있게 해야지....

 

번외2) local

local은 변수나 함수를 외부에서 접근하지 못하도록 막아주는 역할을 한다. 이는 외부에서는 호출하지 못하고 내부에서만 조작해야 할 경우에 주로 사용된다. 간단하게 테스트해보자.

앞서 생성했던 localFunc.lua에서 함수 앞에 local을 붙이고 실행해 볼 계획이다. 작성된 코드는 아래와 같다.

-- localFunc.lua
local function calculator(a, b, mode)
	-- 입력한 모드에 따라 사칙연산을 수행하는 코드
    if mode==0 then
        print(a,"+",b,"=",a+b)
    elseif mode==1 then
        print(a,"-",b,"=",a-b)
    elseif mode==2 then
        print(a,"*",b,"=",a*b)
    elseif mode==3 then
        print(a,"/",b,"=",a/b)
    else
        print(a,",",b,",mode==",mode)
    end
end

이후 ALT+L을 눌러 실행하면 아래와 같은 결과가 나올 것이다.

어찌보면 당연한 결과다. 이를 잘 활용하여 적의 고정 체력 설정, 게임의 물리엔진 기본 중력값 등을 안전하게 조작할 수 있을 것이다.

 


 

계속 본격적인 게임개발보단 기본적인 내용만 다루고 있기에 지루해할 사람이 있을지도 모르겠다. 하지만 지금 다루는 과정은 게임 개발에 있어 필요하다고 생각되는 기능들만 뽑아서 최대한 압축하여 다루고 있기에 조금만 감내해주길 바란다. 이 다음에는 클래스에 대해 다루고, 클래스까지 다루고 나면 나머지는 직접 기능을 구현해보면서 천천히 익혀도 괜찮을 것 같다. 그럼 오늘의 정리글은 여기서 마치도록 하겠다.