package org.codecranachan.asteroidpush.content.behaviors; import java.util.Collection; import java.util.LinkedList; import org.codecranachan.asteroidpush.base.input.ControlItem; import org.codecranachan.asteroidpush.base.input.Controller; import org.codecranachan.asteroidpush.base.simulation.InteractionHandler; import org.codecranachan.asteroidpush.base.simulation.RigidBody; import org.codecranachan.asteroidpush.base.simulation.command.Command; import org.codecranachan.asteroidpush.base.visuals.Representation; import org.codecranachan.asteroidpush.base.workshop.actor.Behavior; import org.codecranachan.asteroidpush.content.visuals.ExhaustRepresentation; import org.codecranachan.asteroidpush.utils.Force; import org.jbox2d.common.Vec2; public class ForceFeederBehavior implements Behavior, InteractionHandler { private Force force; private RigidBody currentBody; private Controller controller; private boolean isActive; public ForceFeederBehavior(Force force) { this.force = force; this.currentBody = null; this.isActive = false; } public Collection<Command> update(int frame) { if (controller != null && currentBody != null) { float factor = controlMagnitude(frame); currentBody.applyForce(force.scaleForce(factor)); isActive = (factor > 0.1f); } return new LinkedList<Command>(); } private float controlMagnitude(int frame) { Vec2 forward = new Vec2(1f, 0f); Vec2 backward = new Vec2(-1f, 0f); Vec2 left = new Vec2(0f, 1f); Vec2 right = new Vec2(0f, -1f); forward .mulLocal(controller.getControl(ControlItem.FORWARD_THRUST, frame)); backward.mulLocal(controller.getControl(ControlItem.BACKWARD_THRUST, frame)); left.mulLocal(controller.getControl(ControlItem.LEFT_THRUST, frame)); right.mulLocal(controller.getControl(ControlItem.RIGHT_THRUST, frame)); Vec2 norm = new Vec2(force.getForce()); norm.normalize(); float mag_fwd = Vec2.dot(forward, norm); if (mag_fwd < 0f) mag_fwd = 0f; float mag_bwd = Vec2.dot(backward, norm); if (mag_bwd < 0f) mag_bwd = 0f; float mag_lft = Vec2.dot(left, norm); if (mag_lft < 0f) mag_lft = 0f; float mag_rgt = Vec2.dot(right, norm); if (mag_rgt < 0f) mag_rgt = 0f; float mag = mag_fwd + mag_bwd + mag_lft + mag_rgt; return mag; } public void onDetach(RigidBody body, int index) { assert index == 0; assert body == currentBody; currentBody = null; } public void onAttach(RigidBody body, int index) { assert index == 0; assert currentBody == null; currentBody = body; } public Collection<Representation> getRepresentations() { Collection<Representation> reps = new LinkedList<Representation>(); if (currentBody != null && isActive) { Force transformed = currentBody.transformToWorld(force); reps.add(new ExhaustRepresentation(transformed.asArrow())); } return reps; } public void setController(Controller controller, int index) { assert index == 0; this.controller = controller; } }