루아 Love 2D엔진 게임만들기 튜토리얼 3이다.

 

이 문서에는 Love 2D 게임으로 간단한 도형 클릭 게임을 만들어 본다.

 

튜토리얼 2까지 진행했다면 이제 도형(사각형, 원)을 게임창에 자유자재로 그릴 수 있을 것 이다. 도형의 위치, 크기, 색상을 바꿔가며 그려봤다면 충분하다. 요새 나오는 게임처럼 그래픽이 화려하지 않아서 맥이 빠질 수도 있겠지만 도형 그리기가 모든 2D게임에 적용되는 기본 원리이기 때문에 장족의 발전이다.

 

도형에다가 화려한 스프라이트를 입히면 순식간에 근사한 게임으로 바뀐다. Love2D를 사용해서 게임의 배경 이미지를 넣고 스프라이트를 넣는 일은 쉬운 일이다. 그보다 중요한 것은 게임에셋(그래픽, 오디오 등의 요소)을 가지고 게임의 알고리즘을 구현하는 일이다.

 

Love2D 게임의 예 - 모바일 게임

oh my giraffe · a delightful game of survival

 

oh my giraffe · a delightful game of survival

oh my giraffe for Linux oh my giraffe requires LÖVE 0.9.0 - 0.9.2

www.ohmygiraffe.com


천리길도 한걸음 부터! 간단한 클릭 게임을 통해 게임의 알고리즘을 배울 수 있다. 프로그래밍을 하다보면 지루한 순간이 찾아오는데 너무 심각하게 생각할 필요는 없다. 이것도 세상 다른 일들과 다를바 없다. 남들이 감탄할 만한 결과물을 내놓기 위해서는 오랜 시간의 수련이 필요하다. 누구나 쉽게 할 수 있는 일이라면 그 가치도 낮기 마련이다.

 

게임을 구현하기 위해서는 여러가지 알고리즘이 들어간다. 쉬운 것도 있고 어려운 것도 있으며 어려운 프레임워크의 작동법을 익혀야 하는 것일 수도 있다. 이런 것들을 하루아침에 배운다고 기억나지도 않을 것이며 응용력은 더욱 발휘하기가 쉽지 않다.

 

급하게 마음을 먹기보다는 하루에 한가지를 배운다고 생각하는게 좋다. 하루에 한개의 알고리즘을 온전히 자기 것으로 만든다면 3개월이면 거의 100개의 알고리즘이다. 그 정도면 뭔가를 만들어 볼만하다. 시간이 조금 더 지나 6개월 정도 노력한다면 근사한 작품을 만들 수 있을 것이다. 시작할 때 보면 까마득한데 6개월이란 시간은 금방 지나간다. 다만 아무나 잘되는게 아니라 그 기간동안 성실하게 할 수 있는 사람만이 도달 할 수 있다. 시간을 보내는 것은 쉽지만 성실하게 프로그래밍을 짜는 것은 어렵기 때문에 아무나 할 수 없는 일이다.

(성실하다는 것은 수동적으로 주어진 교재를 반복하는 일이 아니다. 스스로 창의적인 문제를 만들고 해결해야 하는 일이다.)

 

잡설이 길어졌다. 필자가 처음에 도형을 그리며 느낀 지루함과 막막함에 대하여 전달하려다 보니 좀 길어졌다. 어쨋든 대부분의 사람이 이 고비를 넘기기 어려울 거라 생각한다. 조금만 견디고 넘어가면 별세계가 있다는 정도는 이야기 해두려고 한다.

 

작년인가부터 초등교육에도 코딩교육이 의무화 되었다고 한다. 21세기를 살아가는 마당에 코딩을 할 줄 모른다면 일단 적성을 떠나서 여러가지 기회를 놓치는 것이라고 생각한다. 코딩을 직접 하는 사람만이 해야하는게 아니라 코딩의 원리를 아는게 더 중요하다. 이 문서에서 잡설은 여기까지 하겠다;

 


다음의 게임은 단순한 클릭게임이다. 원을 클릭하면 점수가 올라가고 원의 위치가 랜덤으로 이동한다.

 

love 프레임워크의 기본 틀인 load, update, draw 를 이용해서 만들었다.

 

 

전체 소스코드는 아래와 같다. 세부 내용을 들여다 봐야하니까 대략 쓱 흝고 지나간다.

function love.load()
  love.window.setMode(500, 300)
  button = {}
  button.x = 200
  button.y = 200
  button.radius = 30

  score = 0
  timer = 0
  gameFont = love.graphics.newFont(35)
end

function love.update(dt)

end

function love.draw()
  love.graphics.setBackgroundColor(179/255, 217/255, 255/255)

  love.graphics.setColor(77/255, 77/255, 255/255)
  love.graphics.circle("fill", button.x, button.y, button.radius)

  love.graphics.setFont(gameFont)
  love.graphics.setColor(0, 0, 0)
  love.graphics.print("score: " .. score, 50, 50)
end

function love.mousepressed(x, y, leftClick, isTouch)
  if leftClick == 1 then
    if getDistance(button.x, button.y, love.mouse.getX(), love.mouse.getY()) < button.radius then
      score = score + 1

      button.x = math.random(button.radius, love.graphics.getWidth()-button.radius)
      button.y = math.random(button.radius, love.graphics.getHeight()-button.radius)

    end
  end
end

function getDistance(x1, y1, x2, y2)
  temp = (y2-y1)^2+(x2-x1)^2
  return math.sqrt(temp)
end

1. load 초기화 부분이다.

 

매끄럽게 읽기 위해 코드를 하나씩 repeat 하지 않고 흐름을 해석한다.

 

- 윈도우 창의 크기를 설정한다. (500, 300)

 

- 버튼 테이블을 만든다. 원을 그려서 이 버튼을 사용할 것인데 이것은 GUI 의 버튼 컴포넌트가 아니라 좌표와 크기(반지름)만 가지고 있다. button.x = 200 이 문법의 의미는 button["x"] = 200 과 같다. 루아 문법에서 배우는 내용인데 루아는 테이블 자료형에 묘미가 있다. 마치 테이블의 모습이 객체를 사용하는 것 같다. (루아의 자료형이 객체긴 하다)

 

- 점수를 위한 변수 score 다

 

- love2D에는 기본 폰트가 지정되어 있다. 사이즈만 35로 생성하여 사용하려고 한다.

 

love.load는 초기화 블록이다. 여기서 선언하면 update와 draw에서 전역변수처럼 사용할 수 있다.

 

2. update 부분이다.

 

update 함수에서 게임 상태를 조절할 수 있다. 그런데 love의 다른 함수를 오버라이드해도 같은 결과가 나올 수 있다. 여기서는 간단한 클릭 게임이라 update를 사용하지 않는다.

 

3. draw 그리는 함수다.

 

이 함수에서는 화면에 그리는 일을 보여준다.

 

- 배경화면 색을 설정한다.

 

- 도형의 색상을 설정한다.

 

- 원을 그린다. 초기화 블록의 table의 값을 매개변수로 사용하는 것을 볼 수 있다. 

 

- 초기화 블록에 설정한 폰트를 설정한다. 그 다음에 폰트 색상을 설정(black RGB)해서 점수판을 게임창에 그린다.

 

4. 위의 세가지 기본 게임루프 외에 마우스 클릭시의 함수를 오버라이드 한다.

 

love. 이게 붙은 함수는 그냥 사용자 정의함수가 아니라 오버라이드 함수다. 오버라이드라는 것은 기존의 함수의 내용을 다시 쓴다는 것이다.

 

무슨말이냐면 프레임워크에서 처음에 마우스 버튼을 클릭하면 발생하는 일들을 정해놓았다. 오버라이드 하기 전에도 게임창을 열고 클릭하면 우리 눈에는 보이지 않지만 이벤트가 계속 발생하고 있다. 예를 들어서 게임 창 위로 마우스를 가져가면 프로그램은 커서의 위치에 대한 정보를 계속 업데이트한다. 테스트 환경의 FPS가 144Hz니까 1초에 144번 마우스 좌표가 업데이트되고 있는 것이다. 사람의 눈에 보이지 않지만.

 

mousepressed 메소드를 오버라이드하면 그 update된 정보들을 활용해서 사용자가 정의한 내용으로 이벤트를 처리할 수 있다. 게임루프만 그런게 아니라 대부분의 윈도우GUI 프로그램의 이벤트 처리방식에 오버라이드를 사용한다.

 

- 매개변수 leftClick은 마우스의 왼쪽 버튼 클릭을 의미하고 1은 누른 것이다. 즉 마우스 왼쪽 버튼을 클릭하고 getDistance 가 원보다 작을 때 랜덤함수를 써서 도형(원)의 좌표를 변경하는 것이다.

 

- 일종의 collide (충돌) 계산으로 볼 수 있다. 마우스 커서의 좌표와 원이 그려진 위치를 계산한다. 이 프로그램의 버튼이 곧 원이라고 했다. 버튼이란 뭐냐? 클릭하면 반응하는게 버튼이다. 즉 원 객체가 그려져 있고 마우스가 클릭한 좌표가 그 안에 있다면 반응을 하는 이벤트 처리다.

 

이것은 원이므로 원의 두점 사이의 공식을 통해서 알아낸다. 수학식과 구현한 함수는 아래와 같다. 중학수학의 공식을 응용하면 된다.

 

원이 좌표 어디에 있더라도 이 공식을 사용하면 원의 안에 있는지 바깥에 있는지 구할 수 있다. 이 공식은 피타고라스의 원리를 사용한다. a^2 + b^2 = c^2

 

다행히 루아에는 ^ 제곱연산자가 있어서 그나마 코딩이 수월하다. 제곱연산자가 없는 언어에서는 함수를 따로 만들거나 연산자 오버로딩을 해야한다.

 

 

여기까지 구현하면 완성이다. 도형이 아니라 이미지로 바꾸면 더 근사할 것 같다.(바나나나 사과 같은 것으로 - 몽키 게임 같은 이름을 지어서)

 

이미지로 바꾸기 전에 도형부터 다루는 것은 좋은 생각이다. 도형을 다룰 수 있으면 이미지는 훨씬 쉽다. 도형은 원도 있고 삼각형 타원형같이 모양이 있지만 이미지는 너비와 높이가 있는 단순한 사각형이기 때문이다.

 

 

다양한 주제가 남아있으니 다음 포스팅에 루아 Love 2D 엔진에 대하여 더 다뤄볼 것이다.

공유하기

facebook twitter kakaoTalk kakaostory naver band