de.dakror.villagedefense.game.entity.Entity.java Source code

Java tutorial

Introduction

Here is the source code for de.dakror.villagedefense.game.entity.Entity.java

Source

/*******************************************************************************
 * Copyright 2015 Maximilian Stark | Dakror <mail@dakror.de>
 * 
 * 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 de.dakror.villagedefense.game.entity;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.concurrent.CopyOnWriteArrayList;

import org.json.JSONObject;

import de.dakror.villagedefense.game.Game;
import de.dakror.villagedefense.game.entity.creature.Creature;
import de.dakror.villagedefense.game.entity.struct.Struct;
import de.dakror.villagedefense.game.projectile.Projectile;
import de.dakror.villagedefense.game.world.Tile;
import de.dakror.villagedefense.settings.Attributes;
import de.dakror.villagedefense.settings.Attributes.Attribute;
import de.dakror.villagedefense.settings.Resources;
import de.dakror.villagedefense.settings.Resources.Resource;
import de.dakror.villagedefense.util.Drawable;
import de.dakror.villagedefense.util.Vector;

/**
 * @author Dakror
 */
public abstract class Entity implements Drawable {
    protected float x, y;
    protected int width, height;
    protected boolean hovered, clicked, dead, massive;
    protected String name;
    protected Rectangle bump;
    protected boolean canHunger;
    protected Attributes attributes;
    protected Resources resources;
    public String description;
    private int tick; // for cosine in drawEntity

    protected int randomOffset = (int) (Math.random() * 100);

    public CopyOnWriteArrayList<Projectile> targetedProjectiles = new CopyOnWriteArrayList<>();

    public float alpha;

    public Entity(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        bump = new Rectangle();
        attributes = new Attributes();
        resources = new Resources();
        massive = true;

        alpha = 1;
    }

    public void drawBump(Graphics2D g, boolean above) {
        if (bump == null || (!hovered && !clicked))
            return;

        Color oldColor = g.getColor();
        g.setColor(clicked ? Color.black : Color.darkGray);
        if (above) {
            g.drawLine((int) x + bump.x, (int) y + bump.y, (int) x + bump.x, (int) y + bump.y + bump.height); // left
            g.drawLine((int) x + bump.x, (int) y + bump.y + bump.height, (int) x + bump.x + bump.width,
                    (int) y + bump.y + bump.height); // bottom
            g.drawLine((int) x + bump.x + bump.width, (int) y + bump.y, (int) x + bump.x + bump.width,
                    (int) y + bump.y + bump.height); // right
        } else {
            g.drawLine((int) x + bump.x, (int) y + bump.y, (int) x + bump.x + bump.width, (int) y + bump.y); // top
        }
        g.setColor(oldColor);
    }

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    @Override
    public void update(int tick) {
        this.tick = tick;

        if (alpha > 0) {
            alpha = 1;

            for (Entity e : Game.world.entities) {
                if (e.equals(this))
                    continue;

                if (intersects(e) && e.alpha == 1 && e.y + e.height < y + height) {
                    alpha = 0.6f;
                    break;
                }
            }
        }

        if (new Double(x).isNaN()) // glitched
        {
            if ((this instanceof Creature) && ((Creature) this).isHostile())
                kill();
            return;
        }

        if (attributes.get(Attribute.HEALTH) < 1)
            kill();

        if (!isHungry())
            tick(tick);
    }

    public void drawEntity(Graphics2D g) {
        if (alpha == 0)
            return;

        drawBump(g, false);
        Composite c = g.getComposite();
        if (this instanceof Struct)
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        draw(g);
        g.setComposite(c);

        if (isHungry()) {
            g.drawImage(Game.getImage("icon/hunger.png"), (int) x,
                    (int) (y - Tile.SIZE - Math.cos(tick / 10f) * Tile.SIZE / 4), 32, 32, Game.w);
        } else if (this instanceof Struct && !((Struct) this).isWorking()) {
            g.drawImage(Game.getImage("icon/sleep.png"), (int) (x + width * 0.75f),
                    (int) (y - Tile.SIZE - Math.cos(tick / 10f) * Tile.SIZE / 4), 32, 32, Game.w);
        }

        drawBump(g, true);
    }

    protected abstract void tick(int tick);

    @Override
    public abstract Entity clone();

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void translate(int x, int y) {
        this.x += x;
        this.y += y;
    }

    public Rectangle getBump(boolean includePos) {
        if (!includePos)
            return bump;
        else {
            Rectangle rect = (Rectangle) bump.clone();
            rect.translate((int) x, (int) y);
            return rect;
        }
    }

    public void setBump(Rectangle r) {
        bump = r;
    }

    public boolean contains(float x, float y) {
        return x >= this.x && y >= this.y && x <= this.x + width && y <= this.y + height;
    }

    public boolean mouseMoved(MouseEvent e) {
        if (alpha == 0)
            return false;

        return hovered = contains(e.getX(), e.getY());
    }

    public boolean mousePressed(MouseEvent e) {
        if (alpha == 0)
            return false;

        if (alpha != 1 && this instanceof Struct)
            return clicked = getBump(true).contains(e.getPoint());

        return clicked = contains(e.getX(), e.getY());
    }

    public void mouseReleased(MouseEvent e) {
    }

    public boolean intersects(Entity o) {
        return getArea(false).intersects(o.getArea(false));
    }

    public Rectangle getArea(boolean world) {
        return new Rectangle((int) x + (world ? Game.world.x : 0), (int) y + (world ? Game.world.y : 0), width,
                height);
    }

    public void setClicked(boolean b) {
        clicked = b;
    }

    public boolean isClicked() {
        return clicked;
    }

    public void setHovered(boolean b) {
        hovered = b;
    }

    public Vector getPos() {
        return new Vector(x, y);
    }

    public Vector getCenter() {
        Vector v = getPos();
        v.add(new Vector((float) bump.getCenterX(), (float) bump.getCenterY()));
        return v;
    }

    public Vector getCenter2() {
        Vector v = getPos();
        v.add(new Vector(width / 2, height / 2));
        return v;
    }

    public void setPos(Vector v) {
        x = v.x;
        y = v.y;
    }

    public Attributes getAttributes() {
        return attributes;
    }

    public void setAttributes(Attributes attributes) {
        this.attributes = attributes;
    }

    public Resources getResources() {
        return resources;
    }

    public void setResources(Resources resources) {
        this.resources = resources;
    }

    public void dealDamage(int amount, Object source) {
        int newVal = (int) (attributes.get(Attribute.HEALTH) - amount);

        if (newVal < 0)
            newVal = 0;
        if (newVal > attributes.get(Attribute.HEALTH_MAX))
            newVal = (int) attributes.get(Attribute.HEALTH_MAX);

        attributes.set(Attribute.HEALTH, newVal);
    }

    public boolean isDead() {
        return dead;
    }

    public String getName() {
        return name;
    }

    public void addTargetedProjectile(Projectile p) {
        targetedProjectiles.add(p);
    }

    public void kill() {
        dead = true;
        onDeath();
    }

    public abstract JSONObject getData();

    public boolean isHungry() {
        if (!canHunger)
            return false;

        return Game.currentGame.resources.get(Resource.BREAD) == 0;
    }

    public Vector getTile() {
        return Game.world.getTile(new Vector(x + (float) bump.getCenterX(), y + (float) bump.getCenterY()));
    }

    public boolean isMassive() {
        return massive;
    }

    public byte getTileIdBelow() {
        Vector t = getTile();
        return Game.world.getTileId((int) t.x, (int) t.y);
    }

    // -- abstract event methods -- //
    public abstract void onSpawn(boolean initial);

    protected abstract void onDeath();
}