dk.gruppeseks.bodtrd.engine.Game.java Source code

Java tutorial

Introduction

Here is the source code for dk.gruppeseks.bodtrd.engine.Game.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dk.gruppeseks.bodtrd.engine;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.PolygonRegion;
import com.badlogic.gdx.graphics.g2d.PolygonSprite;
import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.EarClippingTriangulator;
import com.badlogic.gdx.utils.ShortArray;
import dk.gruppeseks.bodtrd.common.data.Audio;
import dk.gruppeseks.bodtrd.common.data.AudioAction;
import dk.gruppeseks.bodtrd.common.data.AudioManager;
import dk.gruppeseks.bodtrd.common.data.AudioType;
import dk.gruppeseks.bodtrd.common.data.Entity;
import dk.gruppeseks.bodtrd.common.data.GameData;
import dk.gruppeseks.bodtrd.common.data.ViewManager;
import dk.gruppeseks.bodtrd.common.data.World;
import dk.gruppeseks.bodtrd.common.data.entityelements.AIData;
import dk.gruppeseks.bodtrd.common.data.entityelements.Body;
import dk.gruppeseks.bodtrd.common.data.entityelements.Health.Health;
import dk.gruppeseks.bodtrd.common.data.entityelements.Position;
import dk.gruppeseks.bodtrd.common.data.entityelements.Velocity;
import dk.gruppeseks.bodtrd.common.data.entityelements.View;
import dk.gruppeseks.bodtrd.common.data.entityelements.Weapon;
import dk.gruppeseks.bodtrd.common.services.GamePluginSPI;
import dk.gruppeseks.bodtrd.common.services.MapSPI;
import dk.gruppeseks.bodtrd.managers.AssetsJarFileResolver;
import dk.gruppeseks.bodtrd.managers.AudioPlayer;
import dk.gruppeseks.bodtrd.managers.GameInputManager;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;

/**
 *
 * @author lucas
 */
public class Game implements ApplicationListener {
    private static final String BACKGROUND_MUSIC_FILE_PATH = "assets/ambientmusic.mp3";
    private static String BACKGROUND_MUSIC_TOTAL_FILE_PATH = "";
    private OrthographicCamera _gameCamera;
    private OrthographicCamera _hudCamera;
    private final Lookup _lookup = Lookup.getDefault();
    public World _world;
    public Set<GamePluginSPI> _gamePlugins = ConcurrentHashMap.newKeySet(); // public so it can be tested
    private Lookup.Result<GamePluginSPI> _result;
    private Lookup.Result<MapSPI> _mapResult;
    private SpriteBatch _batch;
    private ShapeRenderer _shapeRenderer;
    private AssetManager _assetManager;
    private AudioPlayer _audioPlayer = new AudioPlayer();
    private Texture background;
    private BitmapFont _font;
    public MapSPI _map; // Public so it can be tested.

    private PolygonSpriteBatch _polyBatch;
    private Texture _textureSolid;
    private TextureRegion _textureRegion;
    private Pixmap _pix;

    @Override
    public void create() {

        _pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888); // Creates a pixel map with height and width of 1 pixel. RGBA8888 = 8 bit per color and alpha (32bit color system).
        _pix.setColor(1, 0.3f, 0.1f, 0.3f); // Red Green Blue Alpha. 1,1,1,1 would be white. 0,0,0,1 would be black.
        _pix.fill();
        _textureSolid = new Texture(_pix); // A texture of one pixel (With a specific color)
        _textureRegion = new TextureRegion(_textureSolid); // A texture region keeps repeating a texture.
        _polyBatch = new PolygonSpriteBatch();
        _font = new BitmapFont();
        _shapeRenderer = new ShapeRenderer();
        _batch = new SpriteBatch();
        AssetsJarFileResolver jfhr = new AssetsJarFileResolver();
        _assetManager = new AssetManager(jfhr);

        GameData gameData = new GameData();
        _world = new World(gameData);

        gameData.setDisplayWidth(Gdx.graphics.getWidth());
        gameData.setDisplayHeight(Gdx.graphics.getHeight());
        _gameCamera = new OrthographicCamera(gameData.getDisplayWidth(), gameData.getDisplayHeight());
        _hudCamera = new OrthographicCamera(gameData.getDisplayWidth(), gameData.getDisplayHeight());
        _hudCamera.translate(gameData.getDisplayWidth() / 2, gameData.getDisplayHeight() / 2);
        _hudCamera.update();

        _mapResult = _lookup.lookupResult(MapSPI.class);
        _mapResult.addLookupListener(mapLookupListener);

        _map = _lookup.lookup(MapSPI.class);
        _map.generateMap(_world);

        Gdx.input.setInputProcessor(new GameInputManager());

        _result = _lookup.lookupResult(GamePluginSPI.class);
        _result.addLookupListener(lookupListener);

        _gamePlugins.addAll(_result.allInstances());

        for (GamePluginSPI plugin : _gamePlugins) {
            plugin.start(_world);
        }
        BACKGROUND_MUSIC_TOTAL_FILE_PATH = Game.class.getResource(BACKGROUND_MUSIC_FILE_PATH).getPath()
                .replace("file:", "");

        AudioManager.createSound(BACKGROUND_MUSIC_TOTAL_FILE_PATH, AudioType.MUSIC);
        loadViews();
        loadAudio();
        _assetManager.finishLoading();

        AudioManager.playSound(BACKGROUND_MUSIC_TOTAL_FILE_PATH, AudioAction.LOOP);
    }

    private final LookupListener mapLookupListener = new LookupListener() {
        @Override
        public void resultChanged(LookupEvent le) {
            MapSPI newMap = _lookup.lookup(MapSPI.class);

            if (newMap != null && _map != newMap) {
                _map = newMap;
                _map.generateMap(_world);
            }
        }
    };
    private final LookupListener lookupListener = new LookupListener() {
        @Override
        public void resultChanged(LookupEvent le) {
            Collection<? extends GamePluginSPI> updatedPlugins = _result.allInstances();
            for (GamePluginSPI updatedPlugin : updatedPlugins) {
                if (!_gamePlugins.contains(updatedPlugin)) {
                    updatedPlugin.start(_world);
                    _gamePlugins.add(updatedPlugin);
                }
            }

            for (GamePluginSPI oldPlugin : _gamePlugins) {
                if (!updatedPlugins.contains(oldPlugin)) {
                    _gamePlugins.remove(oldPlugin);
                }
            }

            loadViews();
            loadAudio();
        }
    };

    @Override
    public void resize(int i, int i1) {
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0, (float) 0.6, (float) 0.2, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        _world.getGameData().setDeltaTime(Gdx.graphics.getDeltaTime());

        update();
        draw();
    }

    private void loadViews() {
        for (View view : ViewManager.views()) {
            String imagePath = view.getImageFilePath();

            if (!_assetManager.isLoaded(imagePath, Texture.class)) {
                _assetManager.load(imagePath, Texture.class);
            }
        }
    }

    private void loadAudio() {
        for (Audio audio : AudioManager.audios()) {
            String audioPath = audio.getFilePath();
            Class c = Music.class;

            if (audio.getType() == AudioType.SOUND) {
                c = Sound.class;
            }

            if (!_assetManager.isLoaded(audioPath, c)) {
                _assetManager.load(audioPath, c);
            }
        }
    }

    private void tryInitiliazeBackground() {
        if (background != null) {
            return;
        }
        View backgroundTextureView = _world.getMap().getMapTextureView();
        if (backgroundTextureView != null) {
            if (_assetManager.isLoaded(backgroundTextureView.getImageFilePath())) {
                background = _assetManager.get(backgroundTextureView.getImageFilePath(), Texture.class);
                if (backgroundTextureView.isRepeat()) {
                    background.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
                }
            }
        }
    }

    private void update() {
        _world.getGameData().setMousePosition(
                Gdx.input.getX() + (int) (_gameCamera.position.x - _gameCamera.viewportWidth / 2),
                -Gdx.input.getY() + Gdx.graphics.getHeight()
                        + (int) (_gameCamera.position.y - _gameCamera.viewportHeight / 2));
        _world.update();
        _assetManager.update();
        _audioPlayer.handleAudioTasks(_assetManager);
    }

    private void draw() {
        Entity p = _world.getGameData().getPlayer();
        if (p != null) {
            Position pPosition = p.get(Position.class);
            Body pBody = p.get(Body.class);
            _gameCamera.position.x = (float) (pPosition.getX() + pBody.getWidth() / 2);
            _gameCamera.position.y = (float) (pPosition.getY() + pBody.getHeight() / 2);
        }

        _gameCamera.update();
        _polyBatch.setProjectionMatrix(_gameCamera.combined);
        _batch.setProjectionMatrix(_gameCamera.combined);
        _shapeRenderer.setProjectionMatrix(_gameCamera.combined);
        _batch.begin();
        tryInitiliazeBackground();
        if (background != null) {
            int backgroundWidth = background.getWidth();
            int backgroundHeight = background.getHeight();
            int backgroundRepeatWidth = _world.getMap().getWidth() / backgroundWidth;
            int backgroundRepeatHeight = _world.getMap().getHeight() / backgroundHeight;
            _batch.draw(background, 0, 0, backgroundWidth * backgroundRepeatWidth,
                    backgroundHeight * backgroundRepeatHeight, 0, backgroundRepeatHeight, backgroundRepeatWidth, 0);
        }

        _batch.end();
        for (Entity e : _world.entities()) {
            View view = e.get(View.class);
            Velocity vel = e.get(Velocity.class);
            Body body = e.get(Body.class);
            Position pos = e.get(Position.class);
            Health health = e.get(Health.class);

            if (body == null || pos == null || view == null) {
                continue;
            }
            if (_assetManager.isLoaded(view.getImageFilePath())) {
                _batch.begin();
                Texture texture = _assetManager.get(view.getImageFilePath(), Texture.class);
                if (view.isRepeat()) {
                    texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);

                    int textureWidth = texture.getWidth();
                    int textureHeight = texture.getHeight();
                    int textureRepeatWidth = body.getWidth() / textureWidth;
                    int textureRepeatHeight = body.getHeight() / textureWidth;

                    _batch.draw(texture, (float) pos.getX(), (float) pos.getY(), textureWidth * textureRepeatWidth,
                            textureHeight * textureRepeatHeight, 0, textureRepeatHeight, textureRepeatWidth, 0);

                } else {
                    _batch.draw(texture, (float) pos.getX(), (float) pos.getY(), (float) body.getWidth(),
                            (float) body.getHeight());
                }
                _batch.end();
                if (health != null) {
                    _batch.begin();
                    _shapeRenderer.begin(ShapeType.Filled);
                    double centerX = pos.getX() + (body.getWidth() / 2);
                    double upperY = pos.getY() + (body.getHeight());

                    float healthPerc = (float) health.getHp() / (float) health.getMaxHp() * 100;

                    _shapeRenderer.setColor(Color.RED);
                    _shapeRenderer.rect((float) centerX - 25, (float) upperY + 10, 50, 10);
                    _shapeRenderer.setColor(Color.GREEN);
                    _shapeRenderer.rect((float) centerX - 25, (float) upperY + 10, healthPerc / 2, 10);

                    _shapeRenderer.end();

                    _batch.end();
                }
            }
            AIData aiData = e.get(AIData.class);
            if (aiData != null) {
                if (aiData.getFoVShape() != null) {
                    drawFoV(aiData.getFoVShape());
                }
                if (aiData.getLastKnownPosition() != null && vel.getVector().getMagnitude() > 0) {
                    drawLastKnown(aiData.getLastKnownPosition());
                }

            }
        }
        if (p != null) {
            drawHUD(p);
        }
    }

    private void drawLastKnown(Position lastKnown) {
        _shapeRenderer.setProjectionMatrix(_gameCamera.combined);
        _shapeRenderer.begin(ShapeType.Filled);
        _shapeRenderer.setColor(Color.CYAN);
        _shapeRenderer.circle((float) lastKnown.getX(), (float) lastKnown.getY(), 10);
        _shapeRenderer.end();
    }

    private void drawFoV(float[] shape) {
        EarClippingTriangulator triangulator = new EarClippingTriangulator();
        ShortArray triangleIndices = triangulator.computeTriangles(shape);
        PolygonRegion polyReg = new PolygonRegion(_textureRegion, shape, triangleIndices.toArray());
        PolygonSprite polySprite = new PolygonSprite(polyReg);

        _polyBatch.begin();
        polySprite.draw(_polyBatch);
        _polyBatch.end();

        _shapeRenderer.setProjectionMatrix(_gameCamera.combined);
        _shapeRenderer.begin(ShapeType.Line);
        _shapeRenderer.setColor(Color.BROWN);
        _shapeRenderer.polygon(shape);
        _shapeRenderer.end();

    }

    private void drawMouse() {
        _shapeRenderer.setProjectionMatrix(_gameCamera.combined);
        _shapeRenderer.begin(ShapeType.Filled);
        _shapeRenderer.setColor(1, 1, 0, 1);
        _shapeRenderer.circle((float) _world.getGameData().getMousePosition().getX(),
                (float) _world.getGameData().getMousePosition().getY(), 7);
        _shapeRenderer.end();
    }

    private void drawHUD(Entity p) {

        _batch.setProjectionMatrix(_hudCamera.combined);
        _batch.begin();
        Health pHealth = p.get(Health.class);
        Weapon pWeapon = p.get(Weapon.class);

        _font.draw(_batch, "fps: " + Gdx.graphics.getFramesPerSecond(), (float) (10), (float) (700)); // Need to create HUD
        if (pHealth != null) {
            _font.draw(_batch, "Hp: " + (int) pHealth.getHp() + "/" + (int) pHealth.getMaxHp(), (float) (10),
                    (float) (680));
        }
        if (pWeapon != null) {
            _font.draw(_batch, "Ammo: " + pWeapon.getCurrentMagazineSize() + "/" + pWeapon.getCurrentAmmunition(),
                    (float) (10), (float) (660));

        }
        _batch.end();
        _batch.setProjectionMatrix(_gameCamera.combined);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {
    }
}