All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.mostlyoriginal.api.system.physics.AttachmentSystem Maven / Gradle / Ivy

package net.mostlyoriginal.api.system.physics;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Wire;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.systems.IteratingSystem;
import com.badlogic.gdx.math.Vector2;
import net.mostlyoriginal.api.component.basic.Pos;
import net.mostlyoriginal.api.component.physics.Attached;

/**
 * Move entities in line with attachments.
 *
 * @todo consider if we need to change what parent origin this works with.
 * @author Daan van Yperen
 * @see net.mostlyoriginal.api.component.physics.Attached
 */
@Wire
public class AttachmentSystem extends IteratingSystem {

    private ComponentMapper pm;
    private ComponentMapper am;

    public AttachmentSystem() {
        super(Aspect.all(Pos.class, Attached.class));
    }

    Vector2 vTmp = new Vector2();

    @Override
    protected void process(int e) {
        final Attached attached = am.get(e);

	    final int parent = attached.parent;
	    if (parent != -1) {

            // move attachment to absolute position, adjusted with slack.
            Pos pos = pm.get(e);
            Pos parPos = pm.get(parent);
            pos.xy.x = parPos.xy.x + attached.xo + attached.slackX;
            pos.xy.y = parPos.xy.y + attached.yo + attached.slackY;

            updateSlack(attached);
        } else {
            // parent gone? we gone!
            world.delete(e);
        }
    }

    /**
     * Apply force on joint, pushing the attached entity out of place.
     *
     * @param entity Entity to push
     * @param rotation Direction of force
     * @param force strength of force (don't factor in delta).
     */
    public void push(final Entity entity, float rotation, float force) {
        if (am.has(entity)) {
            push(am.get(entity), rotation, force);
        }
    }

    /**
     * Apply force on joint, pushing the attached entity out of place.
     *
     * @param attached Attached component of entity to push
     * @param rotation Direction of force
     * @param force strength of force (don't factor in delta).
     */
    public void push(final Attached attached, float rotation, float force) {
        vTmp.set(force, 0).rotate(rotation).add(attached.slackX, attached.slackY).clamp(0f, attached.maxSlack);
        attached.slackX = vTmp.x;
        attached.slackY = vTmp.y;
    }

    /**
     * Slack, like weapon recoil on the joint.
     *
     * @param attached
     */
    protected void updateSlack(final Attached attached) {

        float len = vTmp.set(attached.slackX, attached.slackY).len() - world.delta * attached.tension;
        if (len > 0) {
            vTmp.nor().scl(len);
        } else {
            vTmp.set(0, 0);
        }

        attached.slackX = vTmp.x;
        attached.slackY = vTmp.y;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy