releasethekraken.entity.seacreature.kraken.EntityKraken.java Source code

Java tutorial

Introduction

Here is the source code for releasethekraken.entity.seacreature.kraken.EntityKraken.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 releasethekraken.entity.seacreature.kraken;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import releasethekraken.GameAssets;
import releasethekraken.GameWorld;
import releasethekraken.ReleaseTheKraken;
import releasethekraken.entity.Entity;
import releasethekraken.entity.pirate.EntityPirate;
import releasethekraken.entity.seacreature.EntitySeaCreature;
import static releasethekraken.physics.CollisionFilter.*; //Import the collision bit constants

/**
 * THE KRAKEN!
 * @author Dalton
 */
public class EntityKraken extends EntitySeaCreature {
    /** The array of Kraken tenticles */
    private EntityKrakenTenticle[] tenticles;
    /** If the kraken has a target */
    private boolean hasTarget = false;

    public EntityKraken(GameWorld world, float xLocation, float yLocation) {
        super(world, xLocation, yLocation);

        this.health = 500;
        this.maxHealth = 500;
        this.defaultMoveForce = 50000F;
        this.moveForce = this.defaultMoveForce;
        this.spawnInWorld(xLocation, yLocation, 0, 0);

        //The spawn points of the tenticles
        Vector2[] tenticleSpawns = { new Vector2(2.0F, 2.0F), new Vector2(3.0F, 1.0F), new Vector2(3.0F, -1.0F),
                new Vector2(2.0F, -2.0F) };

        //Spawn the tenticles
        this.tenticles = new EntityKrakenTenticle[4];
        for (int i = 0; i < this.tenticles.length; i++)
            this.tenticles[i] = new EntityKrakenTenticle(world, xLocation + tenticleSpawns[i].x,
                    yLocation + tenticleSpawns[i].y, this, 3);
    }

    @Override
    protected void spawnInWorld(float x, float y, float xVel, float yVel) {
        //Set up hitbox shape - Defines the hitbox
        PolygonShape hitbox = new PolygonShape();
        //hitbox.setAsBox(3.0F, 2.0F, new Vector2(-0.5F, 0), 0);

        float xOffset = -0.5F;

        hitbox.set(new float[] { -3.0F + xOffset, 0.0F, //Left middle
                -2.0F + xOffset, 1.5F, //Top left
                0.0F + xOffset, 2.0F, //Top middle
                2.0F + xOffset, 1.5F, //Top right
                3.0F + xOffset, 0.0F, //Right middle
                2.0F + xOffset, -1.5F, //Bottom right
                0.0F + xOffset, -2.0F, //Bottom middle
                -2.0F + xOffset, -1.5F //Bottom left
        });

        //Set up body definition - Defines the type of physics body that this is
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(x, y);

        //Set up physics body - Defines the actual physics body
        this.physBody = this.world.getPhysWorld().createBody(bodyDef);
        this.physBody.setUserData(this); //Store this object into the body so that it isn't lost

        //Set up physics fixture - Defines physical properties
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = hitbox;
        fixtureDef.density = 200.0F;
        fixtureDef.friction = 0.05F; //friction with other objects
        fixtureDef.restitution = 0.0F; //Bouncyness

        //Set which collision type this object is
        fixtureDef.filter.categoryBits = COL_SEA_CREATURE;
        //Set which collision types this object collides with
        fixtureDef.filter.maskBits = COL_ALL ^ COL_SEA_PROJECTILE; //Collide with everything except sea creature projectiles

        this.physBody.createFixture(fixtureDef);

        //Set the linear damping
        this.physBody.setLinearDamping(5F);

        //Set the angular damping
        this.physBody.setAngularDamping(2.5F);

        //Apply impulse
        this.physBody.applyLinearImpulse(xVel, yVel, x, y, true);

        //Dispose of the hitbox shape, which is no longer needed
        hitbox.dispose();
    }

    @Override
    public void update() {
        super.update();

        this.hasTarget = false;

        //Find out if any of the tenticles are targeting stuff
        for (EntityKrakenTenticle tenticle : this.tenticles) {
            EntitySeaCreature tenticlePart = tenticle;

            while (tenticlePart != null) {
                if (tenticlePart instanceof EntityKrakenTenticle) {
                    //If any of the tenticles has a target, remember it and break out of the loop
                    if (((EntityKrakenTenticle) tenticlePart).getTarget() != null) {
                        this.hasTarget = true;
                        break;
                    }
                    tenticlePart = ((EntityKrakenTenticle) tenticlePart).getChild(); //Go to next segment
                } else if (tenticlePart instanceof EntityKrakenGripper) {
                    //If any of the tenticles has a target, remember it and break out of the loop
                    if (((EntityKrakenGripper) tenticlePart).getTarget() != null) {
                        this.hasTarget = true;
                        break;
                    }
                    tenticlePart = null; //The gripper should be the last segment
                }
            }
        }

        if (!this.hasTarget) //Only follow the path if there is no target
        {
            Vector2 targetPos = this.world.getPathTargetPos(this);
            Vector2 difference = targetPos.sub(this.getPos());
            difference.nor().scl(this.moveForce);
            this.physBody.applyForce(difference, this.getPos(), true);
        } else //Move towards the target
        {
            Entity target = this.world.getClosestTarget(this, EntityPirate.class, 40, true);

            if (target != null) {
                Vector2 targetPos = target.getPos();
                Vector2 difference = targetPos.sub(this.getPos());
                difference.nor().scl(this.moveForce);
                this.physBody.applyForce(difference, this.getPos(), true);
            }
        }

        //Get the angle difference
        float angle = this.getVel().angle() - (this.physBody.getAngle() * MathUtils.radiansToDegrees);

        //Convert to -180 to 180
        while (angle > 180)
            angle -= 180;
        while (angle < -180)
            angle += 180;

        //Calculate torque to apply
        float torque = (angle > 0 ? 500F : -500F);

        //Rotate towards velocity
        this.physBody.applyTorque(torque, true);
    }

    @Override
    public void renderSprites(SpriteBatch batch, float delta, float runTime) {
        super.renderSprites(batch, delta, runTime);

        float spriteUnitWidth = 7.0F;
        float spriteUnitHeight = 4.0F;

        //if (this.hasTarget) //Debug target code
        //    batch.setColor(Color.RED);

        batch.draw(GameAssets.entityKrakenBodyTexture, this.physBody.getPosition().x - spriteUnitWidth / 2,
                this.physBody.getPosition().y - spriteUnitHeight / 2, 3.5F, //X point to rotate around
                2F, //Y point to rotate around
                spriteUnitWidth, spriteUnitHeight, 1.0F, //X scale
                1.0F, //Y scale
                (float) Math.toDegrees(this.physBody.getAngle()));

        //if (this.hasTarget) //Debug target code
        //    batch.setColor(Color.WHITE);

    }

    @Override
    public void attack(int damage) {
        EntityPirate target = this.world.getClosestTarget(this, EntityPirate.class);
    }

    @Override
    public void dispose() {
        for (EntityKrakenTenticle tenticle : this.tenticles)
            tenticle.setParent(null);
        super.dispose();
    }
}