org.destinationsol.game.screens.BorderDrawer.java Source code

Java tutorial

Introduction

Here is the source code for org.destinationsol.game.screens.BorderDrawer.java

Source

/*
 * Copyright 2015 MovingBlocks
 *
 * 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 org.destinationsol.game.screens;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Vector2;
import org.destinationsol.Const;
import org.destinationsol.SolApplication;
import org.destinationsol.common.SolColor;
import org.destinationsol.common.SolMath;
import org.destinationsol.game.*;
import org.destinationsol.game.planet.Planet;
import org.destinationsol.game.planet.PlanetManager;
import org.destinationsol.game.planet.SolSystem;
import org.destinationsol.game.planet.SunSingleton;
import org.destinationsol.game.ship.FarShip;
import org.destinationsol.game.ship.SolShip;
import org.destinationsol.ui.UiDrawer;

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

public class BorderDrawer {

    private static final float MAX_DRAW_DIST = (Const.MAX_GROUND_HEIGHT + Const.ATM_HEIGHT) * 2;
    public static final float TISHCH_SZ = .02f;
    public static final float BORDER_ICON_SZ = .12f;
    public static final float MAX_ICON_DIST = Const.ATM_HEIGHT;
    private final ArrayList<Tishch> myTishches;
    private final Vector2 myTmpVec = new Vector2();

    public BorderDrawer(float r, SolApplication cmp) {
        TextureAtlas.AtlasRegion tex = cmp.getTexMan().getTex("ui/tishch", null);
        int hCellCount = (int) (r / TISHCH_SZ);
        int vCellCount = (int) (1 / TISHCH_SZ);
        float hStep = r / hCellCount;
        float vStep = 1f / vCellCount;
        float x = hStep / 2;
        float y = vStep / 2;
        myTishches = new ArrayList<Tishch>();
        for (int i = 0; i < vCellCount; i++) {
            Tishch t = new Tishch(x, y, r, TISHCH_SZ, tex);
            myTishches.add(t);
            Tishch t2 = new Tishch(r - x, y, r, TISHCH_SZ, tex);
            myTishches.add(t2);
            y += vStep;
        }
        x = 1.5f * TISHCH_SZ;
        y = TISHCH_SZ / 2;
        for (int i = 1; i < hCellCount - 1; i++) {
            Tishch t = new Tishch(x, y, r, TISHCH_SZ, tex);
            myTishches.add(t);
            Tishch t2 = new Tishch(x, 1 - y, r, TISHCH_SZ, tex);
            myTishches.add(t2);
            x += hStep;
        }
    }

    public void draw(UiDrawer drawer, SolApplication cmp) {
        SolGame g = cmp.getGame();
        SolCam cam = g.getCam();
        Vector2 camPos = cam.getPos();
        SolShip hero = g.getHero();
        drawTishches(drawer, g, cam, camPos);
        MapDrawer mapDrawer = g.getMapDrawer();
        FactionManager factionManager = g.getFactionMan();
        float heroDmgCap = hero == null ? Float.MAX_VALUE : HardnessCalc.getShipDmgCap(hero);

        List<SolObject> objs = g.getObjMan().getObjs();
        for (int i = 0, objsSize = objs.size(); i < objsSize; i++) {
            SolObject o = objs.get(i);
            if ((o instanceof SolShip)) {
                SolShip ship = (SolShip) o;
                Vector2 shipPos = ship.getPosition();
                Faction shipFaction = ship.getPilot().getFaction();
                float shipSize = ship.getHull().config.getSize();
                float shipAngle = ship.getAngle();
                maybeDrawIcon(drawer, shipPos, cam, shipSize, shipAngle, mapDrawer, factionManager, hero,
                        shipFaction, o, heroDmgCap, ship.getHull().config.getIcon());
            }
            if ((o instanceof StarPort)) {
                StarPort sp = (StarPort) o;
                maybeDrawIcon(drawer, sp.getPosition(), cam, StarPort.SIZE, sp.getAngle(), mapDrawer, null, null,
                        null, null, -1, mapDrawer.getStarPortTex());
            }
        }

        List<FarShip> farShips = g.getObjMan().getFarShips();
        for (int i = 0, farObjsSize = farShips.size(); i < farObjsSize; i++) {
            FarShip ship = farShips.get(i);
            Vector2 shipPos = ship.getPos();
            Faction shipFaction = ship.getPilot().getFaction();
            float shipSize = ship.getHullConfig().getSize();
            float shipAngle = ship.getAngle();
            maybeDrawIcon(drawer, shipPos, cam, shipSize, shipAngle, mapDrawer, factionManager, hero, shipFaction,
                    ship, heroDmgCap, ship.getHullConfig().getIcon());
        }
        List<StarPort.MyFar> farPorts = g.getObjMan().getFarPorts();
        for (int i = 0, sz = farPorts.size(); i < sz; i++) {
            StarPort.MyFar sp = farPorts.get(i);
            maybeDrawIcon(drawer, sp.getPos(), cam, StarPort.SIZE, sp.getAngle(), mapDrawer, null, null, null, null,
                    -1, mapDrawer.getStarPortTex());
        }
    }

    private void maybeDrawIcon(UiDrawer drawer, Vector2 pos, SolCam cam, float objSize, float objAngle,
            MapDrawer mapDrawer, FactionManager factionManager, SolShip hero, Faction objFac, Object shipHack,
            float heroDmgCap, TextureAtlas.AtlasRegion icon) {
        Vector2 camPos = cam.getPos();
        float closeness = 1 - pos.dst(camPos) / MAX_ICON_DIST;
        if (closeness < 0)
            return;
        float camAngle = cam.getAngle();
        SolMath.toRel(pos, myTmpVec, camAngle, camPos);
        float len = myTmpVec.len();
        float newLen = len - .25f * objSize;
        myTmpVec.scl(newLen / len);

        if (cam.isRelVisible(myTmpVec))
            return;

        float sz = BORDER_ICON_SZ * closeness;
        float prefX = drawer.r / 2 - sz / 2;
        float prefY = .5f - sz / 2;
        float r = prefX / prefY;
        boolean prefXAxis = myTmpVec.y == 0 || r < SolMath.abs(myTmpVec.x / myTmpVec.y);
        float mul = SolMath.abs(prefXAxis ? (prefX / myTmpVec.x) : (prefY / myTmpVec.y));
        myTmpVec.scl(mul);
        myTmpVec.add(drawer.r / 2, .5f);

        mapDrawer.drawObjIcon(sz, myTmpVec, objAngle - camAngle, factionManager, hero, objFac, heroDmgCap, shipHack,
                icon, drawer);
    }

    private void drawTishches(UiDrawer drawer, SolGame g, SolCam cam, Vector2 camPos) {
        PlanetManager pMan = g.getPlanetMan();
        Planet np = pMan.getNearestPlanet();
        if (np != null && np.getPos().dst(camPos) < np.getFullHeight())
            return;
        for (int i = 0, myTishchesSize = myTishches.size(); i < myTishchesSize; i++) {
            Tishch t = myTishches.get(i);
            t.reset();
        }

        float camAngle = cam.getAngle();
        ArrayList<Planet> planets = pMan.getPlanets();
        for (int i = 0, planetsSize = planets.size(); i < planetsSize; i++) {
            Planet p = planets.get(i);
            Vector2 objPos = p.getPos();
            float objRad = p.getFullHeight();
            apply0(camPos, camAngle, objPos, objRad);
        }
        SolSystem sys = pMan.getNearestSystem(camPos);
        apply0(camPos, camAngle, sys.getPos(), SunSingleton.SUN_HOT_RAD);
        for (int i = 0, myTishchesSize = myTishches.size(); i < myTishchesSize; i++) {
            Tishch t = myTishches.get(i);
            t.draw(drawer);
        }
    }

    private void apply0(Vector2 camPos, float camAngle, Vector2 objPos, float objRad) {
        float dst = objPos.dst(camPos);
        float distPerc = (dst - objRad) / MAX_DRAW_DIST;
        if (distPerc < 1) {
            float relAngle = SolMath.angle(camPos, objPos) - camAngle;
            float angularWHalf = SolMath.angularWidthOfSphere(objRad, dst);
            apply(distPerc, angularWHalf, relAngle);
        }
    }

    private void apply(float distPerc, float angularWHalf, float relAngle) {
        for (int i = 0, myTishchesSize = myTishches.size(); i < myTishchesSize; i++) {
            Tishch t = myTishches.get(i);
            if (SolMath.angleDiff(t.myAngle, relAngle) < angularWHalf) {
                t.setDistPerc(distPerc);
            }
        }
    }

    private static class Tishch {
        private final float myX;
        private final float myY;
        private final TextureAtlas.AtlasRegion myTex;
        private final float myMaxSz;
        private final Color myCol;
        private float myPerc;
        private final float myAngle;

        public Tishch(float x, float y, float r, float maxSz, TextureAtlas.AtlasRegion tex) {
            myX = x;
            myY = y;
            myTex = tex;
            myMaxSz = maxSz * .9f;
            Vector2 pos = new Vector2(x, y);
            Vector2 centah = new Vector2(r / 2, .5f);
            myAngle = SolMath.angle(centah, pos, true);
            myCol = new Color(SolColor.UI_DARK);
        }

        public void draw(UiDrawer drawer) {
            float sz = myPerc * myMaxSz;
            myCol.a = myPerc;
            drawer.draw(myTex, sz, sz, sz / 2, sz / 2, myX, myY, 0, myCol);
        }

        public void setDistPerc(float distPerc) {
            float closeness = 1 - distPerc;
            if (closeness < myPerc)
                return;
            myPerc = closeness;
        }

        public void reset() {
            myPerc = 0;
        }
    }
}