diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2015-07-19 13:20:33 +0200 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2015-07-19 13:20:33 +0200 | 
| commit | de0463bcf0f76ef8b07f2719679c9e0d72745c5d (patch) | |
| tree | 9a33df947ceeea16a3e20b400585b1d3c304e77e /core/src/ch/asynk/rustanddust/game/hud | |
| parent | e66f9f2a61d3dab4545e996046486de0d44e2901 (diff) | |
| download | RustAndDust-de0463bcf0f76ef8b07f2719679c9e0d72745c5d.zip RustAndDust-de0463bcf0f76ef8b07f2719679c9e0d72745c5d.tar.gz  | |
welcome RustAndDust
Diffstat (limited to 'core/src/ch/asynk/rustanddust/game/hud')
5 files changed, 988 insertions, 0 deletions
diff --git a/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java b/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java new file mode 100644 index 0000000..323767f --- /dev/null +++ b/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java @@ -0,0 +1,185 @@ +package ch.asynk.rustanddust.game.hud; + +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.rustanddust.game.Ctrl; +import ch.asynk.rustanddust.game.State.StateType; +import ch.asynk.rustanddust.ui.Widget; +import ch.asynk.rustanddust.ui.Bg; +import ch.asynk.rustanddust.ui.Position; + +public class ActionButtons extends Widget +{ +    public static int PADDING = 5; + +    private final Ctrl ctrl; + +    public enum Buttons { +        NONE(-1, 0), +        PROMOTE(0, 1), +        DONE(1, 2), +        ABORT(2, 4), +        LAST(3, 0); + +        Buttons(int i, int b) +        { +            this.i = i; +            this.b = b; +        } + +        public int i; +        public int b; +    } + +    private Sprite bg; +    private int idx; +    private Bg buttons []; +    private StateType states []; + +    public ActionButtons(Ctrl ctrl, TextureAtlas uiAtlas, TextureAtlas hudAtlas) +    { +        this.bg = new Sprite(uiAtlas.findRegion("disabled")); +        this.ctrl = ctrl; +        this.visible = false; +        this.position = Position.BOTTOM_RIGHT; +        this.idx = Buttons.NONE.i; + + +        this.buttons = new Bg[Buttons.LAST.i]; +        this.buttons[Buttons.DONE.i] = new Bg(uiAtlas.findRegion("ok")); +        this.buttons[Buttons.ABORT.i] = new Bg(uiAtlas.findRegion("cancel")); +        this.buttons[Buttons.PROMOTE.i] = new Bg(hudAtlas.findRegion("promote")); + +        this.states = new StateType[Buttons.LAST.i]; +        this.states[Buttons.DONE.i] = StateType.DONE; +        this.states[Buttons.ABORT.i] = StateType.ABORT; +        this.states[Buttons.PROMOTE.i] = StateType.PROMOTE; +    } + +    @Override +    public void dispose() +    { +        for (int i = 0; i < Buttons.LAST.i; i++) +            buttons[i].dispose(); +    } + +    public void update(Position position) +    { +        setPosition(position); +        updatePosition(); +    } + +    public void updatePosition() +    { +        if (!visible) return; +        float dx = (position.getX(rect.width) - rect.x); +        float dy = (position.getY(rect.height) - rect.y); +        translate(dx, dy); +        for (int i = 0; i < Buttons.LAST.i; i++) +            buttons[i].translate(dx, dy); +    } + +    public void hide() +    { +        for (int i = 0; i < Buttons.LAST.i; i++) +            buttons[i].visible = false; +        this.visible = false; +    } + +    private float setButton(Bg btn, float x, float y) +    { +        btn.visible = true; +        btn.setPosition(x, y); +        return (y + btn.getHeight() + PADDING); +    } + +    public void show(int bits) +    { +        int b = bits; +        int count = 0; +        while (b > 0) { +            if ((b & 0x01) == 1) +                count += 1; +            b /= 2; +        } + +        if (count == 0) { +            this.visible = false; +            return; +        } + +        rect.width = (buttons[0].getWidth() + (2 * PADDING)); +        rect.height = ((buttons[0].getHeight() * count) + ((count + 1) * PADDING)); +        rect.x =  position.getX(rect.width); +        rect.y =  position.getY(rect.height); + +        float x = (rect.x + PADDING); +        float y = (rect.y + PADDING); + +        b = 1; +        for (int i = 0; i < Buttons.LAST.i; i++) { +            if ((bits & b) == b) +                y = setButton(buttons[i], x, y); +            else +                buttons[i].visible = false; +            b *= 2; +        } + +        this.visible = true; +    } + +    public boolean touchDown(float x, float y) +    { +        idx = Buttons.NONE.i; + +        if (!super.hit(x,y)) +            return false; + +        for (int i = 0; i < Buttons.LAST.i; i++) { +            if (buttons[i].hit(x, y)) { +                idx = i; +                break; +            } +        } + +        return (idx != Buttons.NONE.i); +    } + +    public boolean touchUp(float x, float y) +    { +        if (idx == Buttons.NONE.i) +            return false; + +        boolean ret = false; + +        if (super.hit(x,y) && buttons[idx].hit(x, y)) { +            ctrl.setState(states[idx]); +            ret = true; +        } + +        idx = Buttons.NONE.i; + +        return ret; +    } + +    @Override +    public void draw(Batch batch) +    { +        if (!visible) return; +        batch.draw(bg, rect.x, rect.y, rect.width, rect.height); +        for (int i = 0; i < Buttons.LAST.i; i++) +            buttons[i].draw(batch); +    } + +    @Override +    public void drawDebug(ShapeRenderer shapes) +    { +        if (!visible) return; +        super.drawDebug(shapes); +        for (int i = 0; i < Buttons.LAST.i; i++) +            buttons[i].drawDebug(shapes); +    } +} diff --git a/core/src/ch/asynk/rustanddust/game/hud/EngagementPanel.java b/core/src/ch/asynk/rustanddust/game/hud/EngagementPanel.java new file mode 100644 index 0000000..790c8b5 --- /dev/null +++ b/core/src/ch/asynk/rustanddust/game/hud/EngagementPanel.java @@ -0,0 +1,255 @@ +package ch.asynk.rustanddust.game.hud; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.rustanddust.game.Engagement; +import ch.asynk.rustanddust.game.Army; +import ch.asynk.rustanddust.engine.gfx.Animation; +import ch.asynk.rustanddust.engine.gfx.animations.DiceAnimation; +import ch.asynk.rustanddust.ui.Bg; +import ch.asynk.rustanddust.ui.Label; +import ch.asynk.rustanddust.ui.Patch; +import ch.asynk.rustanddust.ui.Position; + +public class EngagementPanel extends Patch implements Animation +{ +    private enum State { ROLL1, MOVE, ROLL2, RESULT }; + +    public static int FLAG_HEIGHT = 24; +    public static int OK_OFFSET = 10; +    public static int PADDING = 20; +    public static int VSPACING = 10; +    public static int HSPACING = 5; +    public static float MOVE_STEP = 2f; + +    private State state; +    private boolean reroll; +    private float rerollY; +    private Sprite usFlag; +    private Sprite geFlag; +    private Sprite winner; +    private Sprite attackImg; +    private Sprite defenseImg; +    private Label attack; +    private Label defense; +    private Label attackR; +    private Label defenseR; +    private Bg okBtn; +    private DiceAnimation d1Animation; +    private DiceAnimation d2Animation; +    private DiceAnimation d3Animation; +    private DiceAnimation d4Animation; + +    public EngagementPanel(BitmapFont font, TextureAtlas uiAtlas, TextureAtlas hudAtlas) +    { +        super(uiAtlas.createPatch("typewriter")); +        usFlag = new Sprite(hudAtlas.findRegion("us-flag")); +        geFlag = new Sprite(hudAtlas.findRegion("ge-flag")); +        attackImg = new Sprite(hudAtlas.findRegion("attack")); +        defenseImg = new Sprite(hudAtlas.findRegion("defense")); +        this.attack = new Label(font); +        this.defense = new Label(font); +        this.attackR = new Label(font); +        this.defenseR = new Label(font); +        this.okBtn = new Bg(uiAtlas.findRegion("ok")); +        this.visible = false; +        this.d1Animation = new DiceAnimation(); +        this.d2Animation = new DiceAnimation(); +        this.d3Animation = new DiceAnimation(); +        this.d4Animation = new DiceAnimation(); +    } + +    public void updatePosition() +    { +        if (!visible) return; +        float dx = (position.getX(rect.width) - rect.x); +        float dy = (position.getY(rect.height) - rect.y); +        translate(dx, dy); +        winner.translate(dx, dy); +        attackImg.translate(dx, dy); +        defenseImg.translate(dx, dy); +        attack.translate(dx, dy); +        defense.translate(dx, dy); +        attackR.translate(dx, dy); +        defenseR.translate(dx, dy); +        okBtn.translate(dx, dy); +        d1Animation.translate(dx, dy); +        d2Animation.translate(dx, dy); +        d3Animation.translate(dx, dy); +        d4Animation.translate(dx, dy); +    } + +    public void show(Engagement e, Position position, float volume) +    { +        DiceAnimation.initSound(volume); +        attack.write(String.format(" + %d + %d =", e.unitCount, e.flankBonus)); +        if (e.weatherDefense == 0) +            defense.write(String.format("%d + %d =", e.unitDefense, e.terrainDefense)); +        else +            defense.write(String.format("%d + %d + %d =", e.unitDefense, e.terrainDefense, e.weatherDefense)); +        attackR.write(String.format(" %2d", e.attackSum)); +        defenseR.write(String.format(" %2d", e.defenseSum)); +        if (e.success) +            winner = ((e.attacker.getArmy() == Army.US) ? usFlag : geFlag); +        else +            winner = ((e.attacker.getArmy() == Army.US) ? geFlag : usFlag); + +        this.position = position; +        placeElements(); + +        state = State.ROLL1; +        reroll = (e.d3 != 0); + +        d1Animation.set(e.d1); +        d2Animation.set(e.d2); +        if (reroll) { +            d3Animation.set(e.d3); +            d4Animation.set(e.d4); +        } + +        visible = true; +    } + +    private void placeElements() +    { +        float w = attackR.getWidth(); +        float w2 = defenseR.getWidth(); +        if (w2 > w) +            w = w2; +        float height = (okBtn.getHeight() + attackImg.getHeight() + defenseImg.getHeight() + (2 * VSPACING) + (2 * PADDING)); +        float width = (attackImg.getWidth() + (2 * d1Animation.getWidth()) + attack.getWidth() + w + (4 * HSPACING) + (2 * PADDING)); +        float x = position.getX(width); +        float y = position.getY(height); +        setPosition(x, y, width, height); + +        okBtn.setPosition((x + width - okBtn.getWidth() + OK_OFFSET), (y - OK_OFFSET)); + +        x = getX() + PADDING; +        y = getY() + PADDING; +        winner.setPosition((getX() + (width / 2f) - (winner.getWidth() / 2f)), y); +        y += (winner.getHeight() + VSPACING); + +        defenseImg.setPosition(x, y); +        y = (y + (defenseImg.getHeight() / 2f) - (defense.getHeight() / 2f)); +        defenseR.setPosition((getX() + width - w - PADDING), y); +        // x += (defenseImg.getWidth() + HSPACING); +        defense.setPosition((defenseR.getX() - defense.getWidth() - HSPACING), y); + +        x = getX() + PADDING; +        y += defenseImg.getHeight() + VSPACING; +        attackImg.setPosition(x, y); +        x += (attackImg.getWidth() + HSPACING); +        d1Animation.setPosition(x, y); +        d3Animation.setPosition(x, y); +        x += (d1Animation.getWidth() + HSPACING); +        d2Animation.setPosition(x, (y)); +        d4Animation.setPosition(x, y); +        x += (d1Animation.getWidth() + HSPACING); +        y = (y + (attackImg.getHeight() / 2f) - (attack.getHeight() / 2f)); +        attack.setPosition(x, y); +        attackR.setPosition(defenseR.getX(), y); + +        rerollY = (d1Animation.getY() + d1Animation.getHeight() + VSPACING); +    } + +    @Override +    public boolean hit(float x, float y) +    { +        return rect.contains(x, y); +    } + +    @Override +    public boolean animate(float delta) +    { +        if (!visible) return true; +        if (state == State.ROLL1) { +            d1Animation.animate(delta); +            d2Animation.animate(delta); +            if (d1Animation.isDone() && d2Animation.isDone()) { +                if (reroll) +                    state = State.MOVE; +                else +                    state = State.RESULT; +            } +        } + +        if (state == State.MOVE) { +            float y = (d1Animation.getY() + MOVE_STEP); +            if (y >= rerollY) { +                y = rerollY; +                state = State.ROLL2; +            } +            setPosition(getX(), getY(), getWidth(), (y + d1Animation.getHeight() + VSPACING - getY())); +            d1Animation.setPosition(d1Animation.getX(), y); +            d2Animation.setPosition(d2Animation.getX(), y); +        } + +        if (state == State.ROLL2) { +            if (d1Animation.getY() < rerollY) { +                d1Animation.setPosition(d1Animation.getX(), (d1Animation.getY() + d1Animation.getHeight() + VSPACING)); +                d2Animation.setPosition(d2Animation.getX(), (d2Animation.getY() + d2Animation.getHeight() + VSPACING)); +            } else { +                d3Animation.animate(delta); +                d4Animation.animate(delta); +                if (d3Animation.isDone() && d4Animation.isDone()) +                    state = State.RESULT; +            } +        } + +        return false; +    } + +    @Override +    public void dispose() +    { +        super.dispose(); +        attack.dispose(); +        defense.dispose(); +        attackR.dispose(); +        defenseR.dispose(); +        d1Animation.dispose(); +        d2Animation.dispose(); +        d3Animation.dispose(); +        d4Animation.dispose(); +        okBtn.dispose(); +    } + +    @Override +    public void draw(Batch batch) +    { +        if (!visible) return; +        super.draw(batch); +        attackImg.draw(batch); +        d1Animation.draw(batch); +        d2Animation.draw(batch); +        if ((state == State.ROLL2) || (reroll && (state == State.RESULT))) { +            d3Animation.draw(batch); +            d4Animation.draw(batch); +        } +        attack.draw(batch); +        defenseImg.draw(batch); +        defense.draw(batch); +        defenseR.draw(batch); +        okBtn.draw(batch); +        if (state == State.RESULT) { +            attackR.draw(batch); +            winner.draw(batch); +        } +    } + +    @Override +    public void drawDebug(ShapeRenderer shapes) +    { +        if (!visible) return; +        super.drawDebug(shapes); +        attack.drawDebug(shapes); +        defense.drawDebug(shapes); +        attackR.drawDebug(shapes); +        defenseR.drawDebug(shapes); +        okBtn.drawDebug(shapes); +    } +} diff --git a/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java b/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java new file mode 100644 index 0000000..dd77c8e --- /dev/null +++ b/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java @@ -0,0 +1,202 @@ +package ch.asynk.rustanddust.game.hud; + +import com.badlogic.gdx.utils.Disposable; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.rustanddust.engine.gfx.Animation; +import ch.asynk.rustanddust.engine.gfx.Drawable; + +import ch.asynk.rustanddust.game.State.StateType; +import ch.asynk.rustanddust.game.Ctrl; +import ch.asynk.rustanddust.game.Hud; +import ch.asynk.rustanddust.game.Army; +import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Player; +import ch.asynk.rustanddust.ui.LabelImage; +import ch.asynk.rustanddust.ui.Position; + +public class PlayerInfo implements Disposable, Drawable, Animation +{ +    public static int PADDING = 5; + +    private final Ctrl ctrl; + +    private Object hit; + +    private Sprite flag; +    private Sprite usFlag; +    private Sprite geFlag; +    private LabelImage turns; +    private LabelImage aps; +    private LabelImage reinforcement; +    public UnitDock unitDock; +    private Position position; + +    public PlayerInfo(Ctrl ctrl, BitmapFont font, TextureAtlas uiAtlas, TextureAtlas hudAtlas) +    { +        this.ctrl = ctrl; +        this.position = Position.MIDDLE_CENTER; +        usFlag = new Sprite(hudAtlas.findRegion("us-flag")); +        geFlag = new Sprite(hudAtlas.findRegion("ge-flag")); +        turns = new LabelImage(hudAtlas.findRegion("turns"), font, 5f); +        aps = new LabelImage(hudAtlas.findRegion("aps"), font, 5f); +        reinforcement = new LabelImage(hudAtlas.findRegion("reinforcement"), font, 5f); +        unitDock = new UnitDock(ctrl, uiAtlas.findRegion("disabled"), hudAtlas.findRegion("reinforcement-selected"), 10f); +    } + +    @Override +    public void dispose() +    { +        turns.dispose(); +        aps.dispose(); +        reinforcement.dispose(); +        unitDock.dispose(); +    } + +    public void updatePosition() +    { +        float dx = (position.getX(usFlag.getWidth()) - usFlag.getX()); +        float dy = (position.getY(usFlag.getHeight()) - usFlag.getY()); +        usFlag.translate(dx, dy); +        geFlag.translate(dx, dy); +        turns.translate(dx, dy); +        aps.translate(dx, dy); +        reinforcement.translate(dx, dy); +        unitDock.translate(dx, dy); +    } + +    public void setPosition(Position position) +    { +        if (this.position == position) +            return; +        this.position = position; + +        float width = (usFlag.getWidth() + turns.getWidth() + aps.getWidth() + (2 * PADDING)); +        float height = (usFlag.getHeight() + reinforcement.getHeight() + (1 * PADDING)); +        float x = position.getX(width); +        float y = position.getY(height); + +        if (position.isLeft()) { +            reinforcement.setPosition(x, y); +            y += (reinforcement.getHeight() + PADDING); +            usFlag.setPosition(x, y); +            geFlag.setPosition(x, y); +            x += (usFlag.getWidth() + PADDING); +            turns.setPosition(x, y); +            x += (turns.getWidth() + PADDING); +            aps.setPosition(x, y); +        } else { +            x = (x + width); +            reinforcement.setPosition((x - reinforcement.getWidth()), y); +            y += (reinforcement.getHeight() + PADDING); +            x -= usFlag.getWidth(); +            usFlag.setPosition(x, y); +            geFlag.setPosition(x, y); +            x -= (turns.getWidth() + PADDING); +            turns.setPosition(x, y); +            x -= (aps.getWidth() + PADDING); +            aps.setPosition(x, y); +        } +        aps.setLabelPosition(Position.TOP_RIGHT); +        turns.setLabelPosition(Position.MIDDLE_CENTER); +        reinforcement.setLabelPosition(Position.TOP_LEFT); +        unitDock.setPosition(position, reinforcement.getY() - PADDING); +    } + +    public void update(Player player, Position position) +    { +        unitDock.hide(); +        turns.write(String.format("%d", player.getCurrentTurn())); +        aps.write(String.format("%d", player.getAp())); +        int r = player.reinforcement(); +        if (r == 0) { +            reinforcement.visible = false; +        } else { +            reinforcement.visible = true; +            reinforcement.write(String.format("%d",  r)); +        } + +        if (player.is(Army.GE)) +            flag = geFlag; +        else +            flag = usFlag; + +        setPosition(position); +    } + +    public void blockEndOfTurn(boolean blocked) +    { +        turns.blocked = blocked; +    } + +    public boolean touchDown(float x, float y) +    { +        hit = null; + +        if (reinforcement.hit(x, y)) +            hit = reinforcement; +        else if (unitDock.hit(x, y)) +            hit = unitDock; +        else if (turns.hit(x,y)) +            hit = turns; + +        return (hit != null); +    } + +    public boolean touchUp(float x, float y) +    { +        if (hit == null) +            return false; + +        if (hit == turns) { +            if (turns.hit(x, y)) +                ctrl.hud.askEndOfTurn(); +        } +        else if (hit == reinforcement) { +            if (reinforcement.hit(x, y)) +                ctrl.reinforcementHit(); +        } +        else if (hit == unitDock) { +            if (unitDock.hit(x, y)) { +                ctrl.hud.notify(unitDock.select(x, y).toString()); +                ctrl.stateTouchUp(); +            } +        } + +        hit = null; + +        return true; +    } + +    @Override +    public boolean animate(float delta) +    { +        unitDock.animate(delta); +        return false; +    } + +    @Override +    public void draw(Batch batch) +    { +        flag.draw(batch); +        turns.draw(batch); +        aps.draw(batch); +        reinforcement.draw(batch); +        unitDock.draw(batch); +    } + +    @Override +    public void drawDebug(ShapeRenderer debugShapes) +    { +        turns.drawDebug(debugShapes); +        aps.drawDebug(debugShapes); +        reinforcement.drawDebug(debugShapes); +        unitDock.drawDebug(debugShapes); +        debugShapes.rect(flag.getX(), flag.getY(), flag.getWidth(), flag.getHeight()); +    } +} diff --git a/core/src/ch/asynk/rustanddust/game/hud/StatisticsPanel.java b/core/src/ch/asynk/rustanddust/game/hud/StatisticsPanel.java new file mode 100644 index 0000000..2e6546b --- /dev/null +++ b/core/src/ch/asynk/rustanddust/game/hud/StatisticsPanel.java @@ -0,0 +1,120 @@ +package ch.asynk.rustanddust.game.hud; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.rustanddust.game.Player; +import ch.asynk.rustanddust.ui.Bg; +import ch.asynk.rustanddust.ui.Label; +import ch.asynk.rustanddust.ui.Patch; +import ch.asynk.rustanddust.ui.Position; + +public class StatisticsPanel extends Patch +{ +    public static int OK_OFFSET = 10; +    public static int PADDING = 20; +    public static int VSPACING = 10; +    public static int HSPACING = 10; + +    private Label title; +    private Label header; +    private Label stats1; +    private Label stats2; +    private Bg okBtn; + +    public StatisticsPanel(BitmapFont font, TextureAtlas atlas) +    { +        super(atlas.createPatch("typewriter")); +        this.title = new Label(font); +        this.header = new Label(font); +        this.stats1 = new Label(font); +        this.stats2 = new Label(font); +        this.okBtn = new Bg(atlas.findRegion("ok")); +        this.visible = false; +        this.header.write("\nActions\nUnits Left\nUnits Withrawed\nCasualties\nWon Attacks\nLost Attacks"); +    } + +    public void updatePosition() +    { +        if (!visible) return; +        float dx = (position.getX(rect.width) - rect.x); +        float dy = (position.getY(rect.height) - rect.y); +        translate(dx, dy); +        title.translate(dx, dy); +        header.translate(dx, dy); +        stats1.translate(dx, dy); +        stats2.translate(dx, dy); +        okBtn.translate(dx, dy); +    } + +    public void show(Player winner, Player loser, Position position) +    { +        title.write(winner.getName() + " player won the battle in " + winner.getTurnDone() + " turns."); +        stats1.write(winner.getStats()); +        stats2.write(loser.getStats()); + +        float height = (title.getHeight() + header.getHeight() + (2 * PADDING) + (1 * VSPACING)); +        float width = (header.getWidth() + stats1.getWidth() + stats2.getWidth() + (2 * PADDING) + (4 * HSPACING)); +        float w2 = (title.getWidth() + (2 * PADDING)); +        if (w2 > width) width = w2; +        float x = position.getX(width); +        float y = position.getY(height); +        setPosition(x, y, width, height); + +        okBtn.setPosition((x + width - okBtn.getWidth() + OK_OFFSET), (y - OK_OFFSET)); + +        y += PADDING; +        x += PADDING; +        header.setPosition(x, y); +        stats1.setPosition((x + header.getWidth() + (2 * HSPACING)), y); +        stats2.setPosition((stats1.getX() + stats1.getWidth() + (2 * HSPACING)), y); +        y += (header.getHeight() + VSPACING); +        title.setPosition(x, y); +        visible = true; +    } + +    @Override +    public boolean hit(float x, float y) +    { +        if (okBtn.hit(x, y)) +            return true; +        return false; +    } + +    @Override +    public void dispose() +    { +        super.dispose(); +        title.dispose(); +        header.dispose(); +        stats1.dispose(); +        stats2.dispose(); +        okBtn.dispose(); +    } + +    @Override +    public void draw(Batch batch) +    { +        if (!visible) return; +        super.draw(batch); +        title.draw(batch); +        header.draw(batch); +        stats1.draw(batch); +        stats2.draw(batch); +        okBtn.draw(batch); +    } + +    @Override +    public void drawDebug(ShapeRenderer shapes) +    { +        if (!visible) return; +        super.drawDebug(shapes); +        title.drawDebug(shapes); +        header.drawDebug(shapes); +        stats1.drawDebug(shapes); +        stats2.drawDebug(shapes); +        okBtn.drawDebug(shapes); +    } +} diff --git a/core/src/ch/asynk/rustanddust/game/hud/UnitDock.java b/core/src/ch/asynk/rustanddust/game/hud/UnitDock.java new file mode 100644 index 0000000..11895ba --- /dev/null +++ b/core/src/ch/asynk/rustanddust/game/hud/UnitDock.java @@ -0,0 +1,226 @@ +package ch.asynk.rustanddust.game.hud; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Rectangle; + +import ch.asynk.rustanddust.engine.gfx.Animation; +import ch.asynk.rustanddust.engine.Orientation; +import ch.asynk.rustanddust.game.Ctrl; +import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.UnitList; +import ch.asynk.rustanddust.ui.Bg; +import ch.asynk.rustanddust.ui.Position; + +public class UnitDock extends Bg implements Animation +{ +    private static final float SCALE = 0.4f; +    private static final float STEP = 5f; +    private final Ctrl ctrl; + +    private int n; +    private float y; +    private float to; +    private float dx; +    private float step; +    private boolean show; +    private boolean mvtDone; +    public Unit selectedUnit; +    private Sprite selected; +    private UnitList units; +    private Vector3 point; +    private Matrix4 saved; +    private Matrix4 transform; +    private Rectangle scaledRect; + +    public UnitDock(Ctrl ctrl, TextureRegion region, TextureRegion selected, float padding) +    { +        super(region); +        this.ctrl = ctrl; +        this.padding = padding; +        this.mvtDone = true; +        this.point = new Vector3(); +        this.saved = new Matrix4(); +        this.transform = new Matrix4(); +        this.scaledRect = new Rectangle(); +        this.selected = new Sprite(selected); +        this.visible = false; +        this.dx = 0f; +    } + +    @Override +    public void translate(float _dx, float _dy) +    { +        this.y += _dy; +        if (!visible) return; +        super.translate(_dx, _dy); +        for (Unit unit : units) +            unit.translate(_dx, _dy); +        to = position.getX(rect.width * SCALE); +        transform.idt(); +        transform.translate((rect.x + dx), (rect.y + rect.height), 0).scale(SCALE, SCALE, 0).translate(-rect.x, - (rect.y + rect.height), 0); +        point.set(rect.x, rect.y, 0).mul(transform); +        scaledRect.x = point.x; +        scaledRect.y = point.y; +        point.set((rect.x + rect.width), (rect.y + rect.height), 0).mul(transform); +        scaledRect.width = point.x - scaledRect.x; +        scaledRect.height = point.y - scaledRect.y; +    } + +    public void setPosition(Position position, float y) +    { +        if (this.position == position) +            return; +        this.position = position; +        this.y = y; +        this.step = (position.isLeft() ? STEP : -STEP); +        this.mvtDone = true; +        this.visible = false; +        this.dx = 0f; +    } + +    @Override +    public void dispose() +    { +        super.dispose(); +    } + +    @Override +    public boolean hit(float x, float y) +    { +        return (visible && scaledRect.contains(x, y)); +    } + +    public Unit select(float x, float y) +    { +        int i = (int) ((scaledRect.y + scaledRect.height - y) / (scaledRect.height / units.size())); +        selectedUnit = units.get(i); +        return selectedUnit; +    } + +    public void hide() +    { +        if (!visible) return; +        resize(); +        to = rect.x; + +        show = false; +        mvtDone = false; +        selectedUnit = null; +    } + +    public void show() +    { +        if (!resize()) +            return; +        to = position.getX(rect.width * SCALE); + +        show = true; +        mvtDone = false; +        selectedUnit = null; +        visible = true; +    } + +    private boolean resize() +    { +        int count = ctrl.player.reinforcement(); +        if (count == 0) { +            n = 0; +            return false; +        } +        if (count == n) return true; +        n = count; + +        units = ctrl.player.reinforcement; +        rect.width = units.get(0).getWidth() + (2 * padding); +        rect.height = ((units.get(0).getHeight() * n) + ((n + 1) * padding)); +        float scaledWidth = (rect.width * SCALE); +        to = position.getX(scaledWidth); +        rect.x = to + (position.isLeft() ? -scaledWidth : scaledWidth); +        rect.y = y - rect.height; + +        float px = rect.x; +        float py = rect.y + rect.height; +        float ph = units.get(0).getHeight(); +        for (Unit unit : units) { +            py -= (ph + padding); +            // unit.setPosition(px, py, Orientation.SOUTH.r()); +            unit.centerOn((px + (rect.width / 2)), py + (ph / 2)); +            unit.setRotation(position.isLeft() ? Orientation.NORTH.r() : Orientation.SOUTH.r()); +        } + +        return true; +    } + +    @Override +    public boolean animate(float delta) +    { +        if (!visible) return true; +        if (mvtDone) return true; + +        float x = (rect.x + dx); +        if (show) { +            if ((position.isLeft() && (x < to)) || (!position.isLeft() && x > to)) +                dx += step; +            else { +                dx = (to - rect.x); +                mvtDone = true; +            } +        } else { +            if ((position.isLeft() && (x > to)) || (!position.isLeft() && x < to)) +                dx -= step; +            else { +                dx = (to - rect.x); +                mvtDone = true; +                visible = false; +            } +        } + +        transform.idt(); +        transform.translate((rect.x + dx), (rect.y + rect.height), 0).scale(SCALE, SCALE, 0).translate(-rect.x, - (rect.y + rect.height), 0); +        point.set(rect.x, rect.y, 0).mul(transform); +        scaledRect.x = point.x; +        scaledRect.y = point.y; +        point.set((rect.x + rect.width), (rect.y + rect.height), 0).mul(transform); +        scaledRect.width = point.x - scaledRect.x; +        scaledRect.height = point.y - scaledRect.y; +        return false; +    } + +    @Override +    public void draw(Batch batch) +    { +        if (!visible) return; + +        saved.set(batch.getTransformMatrix()); +        batch.setTransformMatrix(transform); + +        super.draw(batch); +        for (Unit unit : units) { +            unit.draw(batch); +            if (unit == selectedUnit) { +                selected.setCenter((unit.getX() + (unit.getWidth() / 2)), (unit.getY() + (unit.getHeight() / 2))); +                selected.draw(batch); +            } +        } + +        batch.setTransformMatrix(saved); +    } + +    @Override +    public void drawDebug(ShapeRenderer shapes) +    { +        if (!visible) return; + +        saved.set(shapes.getTransformMatrix()); +        shapes.setTransformMatrix(transform); + +        shapes.rect(rect.x, rect.y, rect.width, rect.height); + +        shapes.setTransformMatrix(saved); +    } +}  | 
