본문 바로가기

프로그래밍/libGDX 엔진

libGDX #6 메인메뉴 버튼과 이벤트 리스너

메인 메뉴화면에 글자 띄우기에 이어, 오늘은 버튼을 추가, 배치하고 이벤트까지 달아보도록 하죠. 오늘 작업은 비교적 간단합니다. 여러가지 버튼에 대해 전부 다룬다면야 분량이 많아지겠지만 저는 레퍼런스형 강의글을 쓰는것이 아니기에 당장 필요한 하루살이족 스타일로 텍스트버튼만 추가해 보겠습니다.


MenuScreen에서 글자 출력하던곳 밑에 table.row()를 추가하여 새로운 행을 만들고, 그곳에 버튼을 추가하는 형식입니다.

package com.dpug.puggame.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
import com.dpug.puggame.PugGame;

public class MenuScreen extends AbstractScreen {

	public MenuScreen(PugGame game) {
		super(game);
	}

	@Override
	public void show() {
		super.show();
		// 테이블 가져오기
		Table table = super.getTable();
		table.add("Welcome to Pug GAME").spaceBottom(50);

		// start game 버튼 추가
		table.row();
		TextButton startGameButton = new TextButton("Start Game", getSkin());
		startGameButton.addListener(new ActorGestureListener() {
			@Override
			public void touchUp(InputEvent event, float x, float y,
					int pointer, int button) {
				super.touchUp(event, x, y, pointer, button);
				// 실제 게임화면으로 이동하자~
				Gdx.app.log(PugGame.LOG, "실제 게임화면으로 이동 구현!");
			}
		});
		table.add(startGameButton).size(300, 60).uniform().spaceBottom(10);

		// options 버튼 추가
		table.row();
		TextButton optionsButton = new TextButton("Options", getSkin());
		optionsButton.addListener(new ActorGestureListener() {
			@Override
			public void touchUp(InputEvent event, float x, float y,
					int pointer, int button) {
				super.touchUp(event, x, y, pointer, button);
				// 옵션 화면으로 이동하자~
				Gdx.app.log(PugGame.LOG, "옵션 화면으로 이동 구현!");
			}
		});
		table.add(optionsButton).uniform().fill().spaceBottom(10);

		// exit 버튼 추가
		table.row();
		TextButton exitButton = new TextButton("Exit", getSkin());
		exitButton.addListener(new ActorGestureListener() {
			@Override
			public void touchUp(InputEvent event, float x, float y,
					int pointer, int button) {
				super.touchUp(event, x, y, pointer, button);
				// 게임 나가기를 구현하자
				Gdx.app.log(PugGame.LOG, "게임 나가기 구현!");
			}
		});
		table.add(exitButton).uniform().fill().spaceBottom(10);
	}
}

맨 처음 추가한 startGameButton의 경우 size를 300,60으로 직접 너비와 높이를 지정해주고, uniform을 입혔다. 이 유니폼은 흔히 알고있는 유니폼이라 생각하면 된다. 통일한다는 의미이다. 유니폼은 한 명만 입었을땐 그냥 티셔츠와 다름없듯이 이녀석도 start버튼에서만 사용하면 아무런 의미가 없다. 그러나 그 뒤로 추가되는 옵션이나 나가기 버튼에서도 uniform을 추가함으로써 맨 처음 선언된 uniform의 사이즈를 따라하게 된다. 대신 그만큼 버튼의 영역을 채워주는 fill()함수를 호출한 것이다. 궁금하다면 fill()이나 unifrom()을 빼고 실행하면 직접 감이 올 것이다. 이벤트는 버전에 따라서 리스너이름이 달라질 수 있다. 내가 쓰는 0.99 버전에서는 ActorGestureListenr()를 쓴다. 제스쳐에 따른 액션을 감지한다는 의미 같은데, 아마도 모바일 플랫폼과의 의미호환을 위해 이러한 네이밍을 지은것 같다. 여하튼, touchUp을 쓰면 모바일에서는 터치, 데스크탑에서는 마우스 왼쪽 클릭을 인식하게 된다. touchDown은 그 반대인 모바일에서 터치를 떼거나, 마우스 클릭이 끝나는 시점을 의미한다.


이제 이벤트를 추가하고 실행을 해보면, 에러는 없는데 이벤트는 전혀 실행되지 않을 것이다. 그 이유는 InputProcessor를 호출하지 않았기 때문이다. 이걸 입력하지 않으면 입력키 자체를 인식을 못해 이벤트가 실행되지 않는것이다. AbstractScreen.java 의 show() 에다가 아래와 같이 선언을 하도록 하자.

	@Override
	public void show() {
		// InputProcessor 선언
		Gdx.input.setInputProcessor(this.stage);
		Gdx.app.log(PugGame.LOG, "화면을 보여줌: " + getName());
	}

단순히 Gdx.input.setInputProcessor(this.stage); 한 줄이 추가되었다. show()에 선언하여 해당 스테이지가 살아있는 동안만 키 입력에 반응하도록 했다. 이제 다시 게임을 실행하여 버튼을 클릭하면 아래에 입력했던 이벤트 로그들이 출력될 것이다.