de.hasait.tanks.util.common.Abstract2DScreen.java Source code

Java tutorial

Introduction

Here is the source code for de.hasait.tanks.util.common.Abstract2DScreen.java

Source

/*
 * Copyright (C) 2017 by Sebastian Hasait (sebastian at hasait dot de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.hasait.tanks.util.common;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.viewport.ScalingViewport;

/**
 *
 */
public abstract class Abstract2DScreen<C extends AbstractScreenContext> implements Screen {

    private final C _context;

    private final int _viewportW, _viewportH;
    private final Rectangle _viewportR;

    private final List<Disposable> _disposables = new ArrayList<>();

    private final OrthographicCamera _camera;

    private final InputMultiplexer _inputMultiplexer = new InputMultiplexer();

    private final Stage _stage;

    private boolean _visible;
    private Color _backgroundColor;
    private Music _backgroundMusic;
    private boolean _backgroundMusicPlaying = true;
    private float _textMargin;
    private int _textLine;
    private Skin _skin;
    private long _timeMillis;

    protected Abstract2DScreen(final C pContext, final int pViewportW, final int pViewportH) {
        super();

        _context = pContext;

        _viewportW = pViewportW;
        _viewportH = pViewportH;
        _viewportR = new Rectangle(0, 0, _viewportW, _viewportH);

        _camera = new OrthographicCamera();
        _backgroundColor = Color.BLACK;
        _stage = new Stage(new ScalingViewport(Scaling.fit, _viewportW, _viewportH, _camera), _context.getBatch());
        _inputMultiplexer.addProcessor(_stage);
    }

    @Override
    public void dispose() {
        _disposables.forEach(Disposable::dispose);
        _disposables.clear();
    }

    public final C getContext() {
        return _context;
    }

    public final int getViewportH() {
        return _viewportH;
    }

    public final int getViewportW() {
        return _viewportW;
    }

    @Override
    public final void hide() {
        _visible = false;
        Gdx.input.setInputProcessor(null);
        if (_backgroundMusic != null) {
            _backgroundMusic.stop();
        }
    }

    public final boolean isVisible() {
        return _visible;
    }

    @Override
    public final void pause() {

    }

    @Override
    public final void render(final float pDelta) {
        _timeMillis = TimeUtils.millis();
        Gdx.gl.glClearColor(_backgroundColor.r, _backgroundColor.g, _backgroundColor.b, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        _stage.act(pDelta);
        _stage.draw();
        _camera.update();
        final SpriteBatch batch = _context.getBatch();
        batch.setProjectionMatrix(_camera.combined);
        batch.begin();
        _textLine = 0;
        renderInternal(pDelta);
        batch.end();
    }

    @Override
    public final void resize(final int pWidth, final int pHeight) {
        _stage.getViewport().update(pWidth, pHeight, true);
    }

    @Override
    public final void resume() {

    }

    @Override
    public final void show() {
        _visible = true;
        Gdx.input.setInputProcessor(_inputMultiplexer);
        if (_backgroundMusic != null) {
            _backgroundMusic.play();
        }
    }

    public final boolean viewportContains(final float pX, final float pY) {
        return _viewportR.contains(pX, pY);
    }

    final InputMultiplexer getInputMultiplexer() {
        return _inputMultiplexer;
    }

    protected final void addDisposable(final Disposable pDisposable) {
        _disposables.add(pDisposable);
    }

    protected final void addInputProcessor(final InputProcessor pInputProcessor) {
        _inputMultiplexer.addProcessor(pInputProcessor);
    }

    protected final Table addLayout() {
        final Table layout = new Table(getSkin());
        _stage.addActor(layout);
        return layout;
    }

    protected final Label createLabel(final String pText) {
        return createLabel(pText, 1.0f);
    }

    protected final Label createLabel(final String pText, final float pScale) {
        final Label label = new Label(pText, getSkin());
        label.setFontScale(pScale);
        return label;
    }

    protected final TextButton createTextButton(final String pText) {
        final TextButton textButton = new TextButton(pText, getSkin());
        return textButton;
    }

    protected final TextField createTextField() {
        return createTextField(Util.EMPTY);
    }

    protected final TextField createTextField(final String pText) {
        final TextField textField = new TextField(pText, getSkin());
        return textField;
    }

    protected final void drawText(final CharSequence pText) {
        drawText(_textLine--, pText, AlignH.LEFT, AlignV.TOP);
    }

    protected final void drawText(final int pLine, final CharSequence pText) {
        drawText(pLine, pText, AlignH.CENTER);
    }

    protected final void drawText(final int pLine, final CharSequence pText, final AlignH pAlignH) {
        drawText(pLine, pText, pAlignH, AlignV.CENTER);
    }

    protected final void drawText(final int pLine, final CharSequence pText, final AlignH pAlignH,
            final AlignV pAlignV) {
        final BitmapFont font = _context.getFont();
        final float y = pAlignV.getY(_viewportH, font.getLineHeight(), _textMargin) + pLine * font.getLineHeight();
        final int alignH = pAlignH.getAlign();
        font.draw(_context.getBatch(), pText, _textMargin, y, _viewportW - 2 * _textMargin, alignH, false);
    }

    protected final void drawTexture(final Texture pTexture, final float pCX, final float pCY, final int pW,
            final int pH, final float pR) {
        _context.getBatch().draw(pTexture, pCX - pW / 2, pCY - pH / 2, pW / 2, pH / 2, pW, pH, 1, 1, pR, 0, 0,
                pTexture.getWidth(), pTexture.getHeight(), false, false);
    }

    protected final Color getBackgroundColor() {
        return _backgroundColor;
    }

    protected final Music getBackgroundMusic() {
        return _backgroundMusic;
    }

    protected final float getTextMargin() {
        return _textMargin;
    }

    protected final long getTimeMillis() {
        return _timeMillis;
    }

    protected final Vector2 getTouchPosition() {
        if (Gdx.input.isTouched()) {
            final Vector3 touchPos = new Vector3();
            touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
            _camera.unproject(touchPos);
            return new Vector2(touchPos.x, touchPos.y);
        }
        return null;
    }

    protected final boolean isBackgroundMusicPlaying() {
        return _backgroundMusicPlaying;
    }

    protected final Texture loadTexture(final String pPath) {
        final Texture texture = new Texture(Gdx.files.internal(pPath), true);
        texture.setFilter(Texture.TextureFilter.MipMapLinearNearest, Texture.TextureFilter.Linear);
        addDisposable(texture);
        return texture;
    }

    protected abstract void renderInternal(final float pDelta);

    protected final void setBackgroundColor(final Color pBackgroundColor) {
        _backgroundColor = pBackgroundColor;
    }

    protected final void setBackgroundMusic(final String pBackgroundMusicFile) {
        final Music music = Gdx.audio.newMusic(Gdx.files.internal(pBackgroundMusicFile));
        addDisposable(music);
        setBackgroundMusic(music);
    }

    protected final void setBackgroundMusic(final Music pBackgroundMusic) {
        if (_backgroundMusic == pBackgroundMusic) {
            return;
        }
        if (_backgroundMusic != null) {
            _backgroundMusic.stop();
        }
        _backgroundMusic = pBackgroundMusic;
        if (_backgroundMusic != null) {
            _backgroundMusic.setLooping(true);
            if (_visible && _backgroundMusicPlaying) {
                _backgroundMusic.play();
            }
        }
    }

    protected final void setScreen(final Screen pScreen) {
        Objects.requireNonNull(pScreen);

        _context.getGame().setScreen(pScreen);
    }

    protected final void setTextMargin(final float pTextMargin) {
        _textMargin = pTextMargin;
    }

    protected final void toggleBackgroundMusic() {
        _backgroundMusicPlaying = !_backgroundMusicPlaying;
        if (_backgroundMusic != null) {
            if (_backgroundMusicPlaying) {
                _backgroundMusic.play();
            } else {
                _backgroundMusic.stop();
            }
        }
    }

    private Skin getSkin() {
        if (_skin == null) {
            _skin = new Skin(Gdx.files.classpath("uiskin.json"));
            addDisposable(_skin);
        }
        return _skin;
    }

    public enum AlignH {
        LEFT(Align.left), CENTER(Align.center), RIGHT(Align.right);

        private final int _align;

        AlignH(final int pAlign) {
            _align = pAlign;
        }

        public int getAlign() {
            return _align;
        }
    }

    public enum AlignV {
        TOP(1, 0, -1), CENTER(0.5f, 0, 0), BOTTOM(0, 1, 1);

        private final float _vhFac, _lhFac, _mFac;

        AlignV(final float pVhFac, final float pLhFac, final float pMFac) {
            _vhFac = pVhFac;
            _lhFac = pLhFac;
            _mFac = pMFac;
        }

        public float getY(final float pViewportH, final float pLineH, final float pMargin) {
            return pViewportH * _vhFac + pLineH * _lhFac + pMargin * _mFac;
        }
    }

}