com.andgate.pokeadot.Pokable.java Source code

Java tutorial

Introduction

Here is the source code for com.andgate.pokeadot.Pokable.java

Source

/*
This file is part of Poke.
    
Poke is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License.
    
Poke is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Poke.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.andgate.pokeadot;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Circle;

public class Pokable {
    final PokeADot game;

    static enum PokableState {
        ACTIVE, HIT, DESTRUCT, EXPIRED
    }

    private PokableState pokableState = PokableState.ACTIVE;

    public void setState(PokableState newPokableState) {
        pokableState = newPokableState;
    }

    public PokableState getState() {
        return pokableState;
    }

    private Circle initialCircle;
    private Circle hittableCircle;
    private Circle visualCircle;
    private Color color;

    private float timeLimit;
    private float timeElapsed;

    private float activeSpeed;
    private float implodeSpeed;
    private float explodeSpeed;

    private final static float NO_TIME = 0.0f;

    private static final float MAX_POP_TIME = 0.25f;
    private static final float MAX_IMPLODE_TIME = MAX_POP_TIME * (2.0f / 3.0f);
    private static final float MAX_EXPLODE_TIME = MAX_POP_TIME * (1.0f / 3.0f);
    private final static float EXPLODE_FACTOR = 0.2f;

    public Pokable(final PokeADot game, Circle circle, Color color, float timeLimit) {
        this.game = game;
        this.color = new Color(color);
        this.initialCircle = new Circle(circle);
        this.hittableCircle = new Circle(circle);
        this.visualCircle = new Circle(circle);

        this.timeLimit = timeLimit;
        timeElapsed = NO_TIME;

        activeSpeed = -(initialCircle.radius / timeLimit);
        implodeSpeed = -(initialCircle.radius / MAX_IMPLODE_TIME);
        explodeSpeed = initialCircle.radius * EXPLODE_FACTOR / MAX_EXPLODE_TIME;
    }

    public void update(float delta) {
        switch (pokableState) {
        case ACTIVE:
            updateActive(delta);
            break;
        case HIT:
            // play the hit sequence
            updateHit(delta);
            break;
        case DESTRUCT:
            break;
        case EXPIRED:
            break;
        }
    }

    private void updateActive(float delta) {
        grow(activeSpeed * delta, PokableState.EXPIRED);
    }

    private float explodeAccumulator = 0.0f;

    private void updateHit(float delta) {
        float distance = implodeSpeed * delta;

        explodeAccumulator += delta;
        if (explodeAccumulator < MAX_EXPLODE_TIME) {
            distance = explodeSpeed * delta;
        }

        grow(distance, PokableState.DESTRUCT);
    }

    private void grow(final float distance, final PokableState endState) {
        if (visualCircle.radius <= 0.0f) {
            pokableState = endState;
            visualCircle.radius = 0.0f;
        } else {
            visualCircle.radius += distance;
            if (endState == PokableState.EXPIRED) {
                hittableCircle.radius = visualCircle.radius >= Constants.MINIMUM_CIRCLE_RADIUS ? visualCircle.radius
                        : Constants.MINIMUM_CIRCLE_RADIUS;
            } else {
                hittableCircle.radius = 0.0f;
            }
        }
    }

    public void render() {
        switch (pokableState) {
        case ACTIVE:
            renderActiveCircle();
            break;
        case HIT:
            // render hit sequence
            renderActiveCircle();
            break;
        case DESTRUCT:
            break;
        }
    }

    public void renderActiveCircle() {
        float outerRadius = visualCircle.radius;
        float innerRadius = outerRadius - Constants.CIRCLE_BORDER_THICKNESS;
        if (innerRadius < 0.0f) {
            innerRadius = 0.0f;
        }

        game.shape.setColor(color.r - 0.3f, color.g - 0.3f, color.b - 0.3f, color.a);
        game.shape.circle(visualCircle.x * game.ppm, visualCircle.y * game.ppm, outerRadius * game.ppm,
                Constants.CIRCLE_SEGMENTS);

        game.shape.setColor(color);
        game.shape.circle(visualCircle.x * game.ppm, visualCircle.y * game.ppm, innerRadius * game.ppm,
                Constants.CIRCLE_SEGMENTS);
    }

    public boolean collidesWith(Pokable otherPokable) {
        return otherPokable.getVisualCircle().overlaps(visualCircle);
    }

    public float getVisualRadius() {
        return visualCircle.radius;
    }

    public Circle getHittableCircle() {
        return hittableCircle;
    }

    public Circle getVisualCircle() {
        return hittableCircle;
    }
}