본문 바로가기

프로그래밍/libGDX 엔진

libGDX #4 스플래쉬 화면 완성

지난번에 스플래쉬 화면에 쓸 이미지를 가공하여 텍스쳐로 만드는데까지 성공하였다. 이제 이 텍스쳐를 이용하여 멋진 로딩화면을 만들어보자. 일단, SplashScreen의 소스를 보자.

package com.dpug.puggame.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Scaling;
import com.dpug.puggame.PugGame;

public class SplashScreen extends AbstractScreen {

	private Image splashImage;

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

	@Override
	public void show() {
		super.show();
		Gdx.app.log(PugGame.LOG, "스플래쉬 화면 show 실행: " + getName());

		// atlas로부터 스플래쉬 이미지 region 가져오기
		AtlasRegion splashRegion = getAtlas()
				.findRegion("splash-screen/splash");
		Drawable splashDrawable = new TextureRegionDrawable(splashRegion);

		// 이미지 actor 생성하기, 이것의 사이즈는 resize()가 콜할때마다 셋팅됨.
		splashImage = new Image(splashDrawable, Scaling.stretch);
		splashImage.setFillParent(true);

		// fade-in 효과를 사용하기 위해 이미지를 투명하게 만든다.
		splashImage.getColor().a = 0f;

		// splash image 에 action 추가
		splashImage.addAction(Actions.sequence(Actions.fadeIn(0.75f),
				Actions.delay(1.75f), Actions.fadeOut(0.75f), new Action() {

					@Override
					public boolean act(float delta) {
						// fade-in 효과가 끝난 후, 하게 될 액션
						Gdx.app.log(PugGame.LOG, "게임 메뉴로 이동하도록 구현하자!");
						return false;
					}
				}));

		// stage에 actor 추가
		stage.addActor(splashImage);
	}

}

우리가 하고싶은것만 딱 구현하였다. Image 타입의 splashImage를 선언하고, 우리가 만들어놓은 텍스쳐를 담는다. 텍스쳐를 가져올때는 atlas에서 원하는 부분만을 가져오는데, 이 정보는 우리가 저번에 생성했던 textures.atlas에 이 정보가 자동 생성되어 담겨있다. 우리는 그저 getAtlas().findRegion("가져올이름") 만 선언하면 알아서 해당 texture의 영역을 가져와 사용이 가능한것이다.


이제 splashImage를 화면의 크게에 맞게 쭉 늘어나도록 Scaling.stretch를 선언해주고, 보통의 게임 인트로화면이 자연스럽게 나타났다 사라지는것처럼 fade-in 효과를 주었다. 이 부분은 주석에 잘 적어놨으니 참조하면된다. 기본적으로 libgdx는 Stage - Actor -Action 의 구조로 이루어졌있다. 이는 연극에서의 역할과 같다고 보면된다. 따라서 Image는 여기서 Actor가 되고, fade-in 효과는 Action이 된다. Stage는 SplashScreen이 되는데, 모든 Screen을 Stage라고 봐도 무방함으로 Stage의 선언은 AbstractScreen에서 선언하여 상속받아 사용한다. 이제 SplashScreen에서 구현하는건 끝났다. Image를 만들고, Stage에 추가하고 Action을 설정해줬으니말이다.


이제 Stage에서 큐싸인만 올려 진짜로 연극을 진행하면 된다. 이 정보는 당연하게도 render 메소드 안에 구현되야하는데, 모든 Stage는 큐싸인을 하기때문에 AbstractScreen에 구현을 하였다. 아래 AbstractScreen 소스를 보자. 중요한 부분은 render에서 stage.draw()를 한다는 것이다. 이 작업을 안하면 무대 다 만들고 연극 시작을 안하는것과 같아 검은화면만 나올 것이다.

package com.dpug.puggame.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.dpug.puggame.PugGame;

public class AbstractScreen implements Screen {

	protected final PugGame game;
	protected final Stage stage;

	private TextureAtlas atlas;

	public AbstractScreen(PugGame game) {
		this.game = game;
		this.stage = new Stage();
	}

	/**
	 * 해당 클래스 이름 스트링으로 반환하는 함수
	 */
	protected String getName() {
		return getClass().getSimpleName();
	}

	/**
	 * atlas 가져오기
	 */
	TextureAtlas getAtlas() {
		if (atlas == null) {
			atlas = new TextureAtlas(
					Gdx.files.internal("textures/textures.atlas"));
		}
		return atlas;
	}

	@Override
	public void render(float delta) {
		// RGB 검은색으로 화면을 클리어함
		Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		// actor 업데이트
		stage.act(delta);
		
		// actor들 그리기
		stage.draw();
	}

	@Override
	public void resize(int width, int height) {
		Gdx.app.log(PugGame.LOG, "화면 크기 변경: " + getName() + " 이 " + width
				+ " x " + height);
	}

	@Override
	public void show() {
		Gdx.app.log(PugGame.LOG, "화면을 보여줌: " + getName());
	}

	@Override
	public void hide() {
		Gdx.app.log(PugGame.LOG, "화면을 숨김: " + getName());
	}

	@Override
	public void pause() {
		Gdx.app.log(PugGame.LOG, "화면을 멈춤: " + getName());
	}

	@Override
	public void resume() {
		Gdx.app.log(PugGame.LOG, "화면을 재개: " + getName());
	}

	@Override
	public void dispose() {
		Gdx.app.log(PugGame.LOG, "화면을 반환: " + getName());
		if (atlas != null) {
			atlas.dispose();
		}
	}

}

이로써, 스플래쉬 화면이 자연스럽게 나올것이다. 스르륵 나타나서 스르륵 사라지게 될 것이다. 그리고, 나는 좀 더 큼직한 화면을 원하기 때문에 Main.java 클래스에서 width, height를 800, 500으로 변경하였다. 아래는 실행시 화면중 일부이다. fade-in효과는 동영상이 아니면 보여주기 힘드니 각자 알아서 확인하자.