com.turbogerm.helljump.game.platforms.features.FlamePlatformFeature.java Source code

Java tutorial

Introduction

Here is the source code for com.turbogerm.helljump.game.platforms.features.FlamePlatformFeature.java

Source

/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2013 Goran Mrzljak
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.turbogerm.helljump.game.platforms.features;

import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.turbogerm.germlibrary.util.ColorInterpolator;
import com.turbogerm.helljump.dataaccess.PlatformData;
import com.turbogerm.helljump.dataaccess.PlatformFeatureData;
import com.turbogerm.helljump.game.CollisionEffects;
import com.turbogerm.helljump.resources.ResourceNames;

final class FlamePlatformFeature extends PlatformFeatureBase {

    private static final float RENDER_PRECEDENCE = 2.0f;
    private static final float CONTACT_PRECEDENCE = 2.0f;

    private static final float FIRE_FRAME_DURATION = 0.15f;
    private static final float FIRE_SPRITE_WIDTH = 2.0f;
    private static final float FIRE_SPRITE_HEIGHT = 0.6f;

    private static final Color FLAME_COLOR;
    private static final Color DORMANT_COLOR;

    private final Animation mFireAnimation;
    private float mFireAnimationTime = 0.0f;

    private final FlameStateMachine mFlameStateMachine;
    private boolean mIsFlameActive;
    private float mFirstCycleCountdown;

    private final ColorInterpolator mColorInterpolator;

    static {
        FLAME_COLOR = new Color(1.0f, 0.5f, 0.0f, 1.0f);
        DORMANT_COLOR = new Color(FLAME_COLOR);
        DORMANT_COLOR.mul(0.4f);
        DORMANT_COLOR.a = 1.0f;
    }

    public FlamePlatformFeature(PlatformFeatureData featureData, AssetManager assetManager) {

        mFirstCycleCountdown = Float
                .valueOf(featureData.getProperty(PlatformFeatureData.FLAME_CYCLE_OFFSET_PROPERTY));
        float flameDuration = Float
                .valueOf(featureData.getProperty(PlatformFeatureData.FLAME_FLAME_DURATION_PROPERTY));
        float dormantDuration = Float
                .valueOf(featureData.getProperty(PlatformFeatureData.FLAME_DORMANT_DURATION_PROPERTY));
        float transitionDuration = Float
                .valueOf(featureData.getProperty(PlatformFeatureData.FLAME_TRANSITION_DURATION_PROPERTY));

        mFlameStateMachine = new FlameStateMachine(flameDuration, dormantDuration, transitionDuration);
        mIsFlameActive = false;

        TextureAtlas platformsAtlas = assetManager.get(ResourceNames.PLATFORMS_ATLAS);
        Array<AtlasRegion> fireAtlasRegions = platformsAtlas.findRegions(ResourceNames.PLATFORM_FIRE_IMAGE_NAME);
        mFireAnimation = new Animation(FIRE_FRAME_DURATION, fireAtlasRegions, Animation.LOOP);
        mFireAnimationTime = 0.0f;

        mRenderPrecedence = RENDER_PRECEDENCE;
        mContactPrecendence = CONTACT_PRECEDENCE;

        mColorInterpolator = new ColorInterpolator();
    }

    @Override
    public void update(float delta) {
        if (mFirstCycleCountdown > 0.0f) {
            mFirstCycleCountdown -= delta;
            if (mFirstCycleCountdown >= 0.0f) {
                delta = 0.0f;
            } else {
                delta = -mFirstCycleCountdown;
                mFirstCycleCountdown = 0.0f;
            }
        }

        mFlameStateMachine.update(delta);

        if (mFlameStateMachine.getCurrentState() == FlameStateMachine.FLAME) {
            if (!mIsFlameActive) {
                mIsFlameActive = true;
                mFireAnimationTime = 0.0f;
            } else {
                mFireAnimationTime += delta;
            }
        } else {
            mIsFlameActive = false;
        }
    }

    @Override
    public void render(SpriteBatch batch, Vector2 platformPosition, Color color) {
        if (mIsFlameActive) {
            TextureRegion fireAnimationFrame = mFireAnimation.getKeyFrame(mFireAnimationTime);
            batch.draw(fireAnimationFrame, platformPosition.x, platformPosition.y + PlatformData.PLATFORM_HEIGHT,
                    FIRE_SPRITE_WIDTH, FIRE_SPRITE_HEIGHT);
        }
    }

    @Override
    public void applyModifier(PlatformModifier modifier) {
        Color color = modifier.spriteColor;
        float oldAplha = color.a;

        switch (mFlameStateMachine.getCurrentState()) {
        case FlameStateMachine.DORMANT:
            color.set(DORMANT_COLOR);
            break;

        case FlameStateMachine.TRANSITION1:
            color.set(mColorInterpolator.interpolateColor(DORMANT_COLOR, FLAME_COLOR,
                    mFlameStateMachine.getStateElapsedFraction()));
            break;

        case FlameStateMachine.FLAME:
            color.set(FLAME_COLOR);
            break;

        case FlameStateMachine.TRANSITION2:
            color.set(mColorInterpolator.interpolateColor(FLAME_COLOR, DORMANT_COLOR,
                    mFlameStateMachine.getStateElapsedFraction()));
            break;
        }

        color.a = oldAplha;
    }

    @Override
    public boolean isContact(float relativeCollisionPointX) {
        return mIsFlameActive;
    }

    @Override
    public void applyContact(CollisionEffects collisionEffects) {
        collisionEffects.set(CollisionEffects.BURN);
    }

    private static class FlameStateMachine {

        public static final int DORMANT = 0;
        public static final int TRANSITION1 = 1;
        public static final int FLAME = 2;
        public static final int TRANSITION2 = 3;
        private static final int STATE_COUNT = 4;

        private final float[] mStateDurations;

        private int mCurrentState;
        private float mCurrentStateElapsed;

        public FlameStateMachine(float flameDuration, float dormantDuration, float transitionDuration) {
            mCurrentState = DORMANT;
            mCurrentStateElapsed = 0.0f;

            mStateDurations = new float[STATE_COUNT];
            mStateDurations[FLAME] = flameDuration;
            mStateDurations[DORMANT] = dormantDuration;
            mStateDurations[TRANSITION1] = transitionDuration;
            mStateDurations[TRANSITION2] = transitionDuration;
        }

        public void update(float delta) {
            mCurrentStateElapsed += delta;

            if (mCurrentStateElapsed >= mStateDurations[mCurrentState]) {
                mCurrentStateElapsed -= mStateDurations[mCurrentState];
                mCurrentState = (mCurrentState + 1) % STATE_COUNT;
            }
        }

        public int getCurrentState() {
            return mCurrentState;
        }

        public float getStateElapsedFraction() {
            return mCurrentStateElapsed / mStateDurations[mCurrentState];
        }
    }
}