Skip to content

Commit

Permalink
Merge pull request #89 from acatinon/feature-force-action
Browse files Browse the repository at this point in the history
Add action to allow to apply forces on physics objects
  • Loading branch information
azakhary committed May 4, 2016
2 parents 0fff05a + 037c9ff commit 73c7345
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/com/uwsoft/editor/renderer/systems/action/Actions.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.uwsoft.editor.renderer.systems.action;

import com.badlogic.ashley.core.Component;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import com.uwsoft.editor.renderer.components.ActionComponent;
import com.uwsoft.editor.renderer.systems.action.data.*;
import com.uwsoft.editor.renderer.systems.action.logic.*;
Expand Down Expand Up @@ -40,7 +43,9 @@ private static void initialize() throws InstantiationException, IllegalAccessExc
}

public static <T extends ActionLogic> void registerActionClass(Class<T> type) throws IllegalAccessException, InstantiationException {
actionLogicMap.put(type.getName(), type.newInstance());
if (!actionLogicMap.containsKey(type.getName())) {
actionLogicMap.put(type.getName(), type.newInstance());
}
}

private static void checkInit() {
Expand Down Expand Up @@ -234,6 +239,7 @@ public static DelayData delay (float duration) {
return delayData;
}


static public ParallelData parallel(ActionData... actionDatas) {
ParallelData actionData = new ParallelData(actionDatas);
actionData.logicClassName = ParallelAction.class.getName();
Expand Down
69 changes: 69 additions & 0 deletions src/com/uwsoft/editor/renderer/systems/action/PhysicsActions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.uwsoft.editor.renderer.systems.action;

import com.badlogic.ashley.core.Component;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.gdx.math.Vector2;
import com.uwsoft.editor.renderer.systems.action.data.ForceData;
import com.uwsoft.editor.renderer.systems.action.logic.ActionLogic;
import com.uwsoft.editor.renderer.systems.action.logic.ForceAction;

/**
* Created by aurel on 02/04/16.
*/
public class PhysicsActions {


private static void initialize(Class<? extends ActionLogic> type) {
try {
Actions.registerActionClass(type);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

/**
* Apply a force to an entity with physics component. The force is applied as long as
* the corresponding entity as a physics component.
* @param force The world force vector, usually in Newtons (N)
* @return The com.uwsoft.editor.renderer.systems.action.data.ForceData object
*/
public static ForceData force(Vector2 force) {
initialize(ForceAction.class);
ForceData forceData = new ForceData(force);

forceData.logicClassName = ForceAction.class.getName();
return forceData;
}

/**
* Apply a force to an entity with physics component. The force is applied as long as
* the corresponding entity as a physics component.
* @param force The world force vector, usually in Newtons (N)
* @param relativePoint The point where the force is applied relative to the body origin
* @return The com.uwsoft.editor.renderer.systems.action.data.ForceData object
*/
public static ForceData force(Vector2 force, Vector2 relativePoint) {
initialize(ForceAction.class);
ForceData forceData = new ForceData(force, relativePoint);

forceData.logicClassName = ForceAction.class.getName();
return forceData;
}

/**
* Apply a force to an entity with physics component.
* @param force The world force vector, usually in Newtons (N)
* @param relativePoint The point where the force is applied relative to the body origin
* @param linkedComponent The force is applied as long as the corresponding entity
* has this component
* @return The com.uwsoft.editor.renderer.systems.action.data.ForceData object
*/
public static ForceData force(Vector2 force, Vector2 relativePoint, Class<? extends Component> linkedComponent) {
ForceData forceData = force(force, relativePoint);

forceData.linkedComponentMapper = ComponentMapper.getFor(linkedComponent);
return forceData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.uwsoft.editor.renderer.systems.action.data;

import com.badlogic.ashley.core.ComponentMapper;

/**
* Created by aurel on 19/02/16.
*/
public class ComponentData extends DelegateData {
public ComponentMapper linkedComponentMapper;
}
21 changes: 21 additions & 0 deletions src/com/uwsoft/editor/renderer/systems/action/data/ForceData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.uwsoft.editor.renderer.systems.action.data;

import com.badlogic.gdx.math.Vector2;

/**
* Created by aurel on 19/02/16.
*/
public class ForceData extends ComponentData {
public Vector2 force;
public Vector2 relativePoint;

public ForceData(Vector2 force) {
this(force, new Vector2(0, 0));
}

public ForceData(Vector2 force, Vector2 relativePoint) {
super();
this.force = force;
this.relativePoint = relativePoint;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.uwsoft.editor.renderer.systems.action.logic;

import com.badlogic.ashley.core.Entity;
import com.uwsoft.editor.renderer.systems.action.data.ComponentData;

/**
* Created by aurel on 19/02/16.
*/
public abstract class ComponentAction<T extends ComponentData> extends DelegateAction<T> {

@Override
public boolean act(float delta, Entity entity, T actionData) {
if (actionData.linkedComponentMapper == null || actionData.linkedComponentMapper.has(entity)) {
return delegate(delta, entity, actionData);
}
else {
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.uwsoft.editor.renderer.systems.action.logic;

import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.math.Vector2;
import com.uwsoft.editor.renderer.components.physics.PhysicsBodyComponent;
import com.uwsoft.editor.renderer.systems.action.data.ForceData;
import com.uwsoft.editor.renderer.utils.ComponentRetriever;
import com.uwsoft.editor.renderer.utils.ForceUtils;

/**
* Created by aurel on 19/02/16.
*/
public class ForceAction extends ComponentAction<ForceData> {

private ComponentMapper<PhysicsBodyComponent> physicsBodyComponentMapper;

public ForceAction() {
this.physicsBodyComponentMapper = ComponentMapper.getFor(PhysicsBodyComponent.class);
}

@Override
protected boolean delegate(float delta, Entity entity, ForceData actionData) {
if (physicsBodyComponentMapper.has(entity)) {
PhysicsBodyComponent physicsBodyComponent = physicsBodyComponentMapper.get(entity);

ForceUtils.applyForce(actionData.force, physicsBodyComponent.body, actionData.relativePoint);
return false;
}

return true;
}
}
39 changes: 39 additions & 0 deletions src/com/uwsoft/editor/renderer/utils/ForceUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.uwsoft.editor.renderer.utils;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;

/**
* Created by aurel on 19/02/16.
*/
public class ForceUtils {



public static void applyImpulse(Vector2 impulsePosition, float strength, float influenceArea, Body body) {
Vector2 v = body.getPosition().cpy().sub(impulsePosition);

float length = MathUtils.clamp(v.len(), 0, influenceArea);
v.nor().scl(influenceArea - length).scl(strength);

applyForce(v, body, false, false, new Vector2(0, 0));
}

public static void applyForce(Vector2 force, Body body) {
applyForce(force, body, false, false, new Vector2(0, 0));
}

public static void applyForce(Vector2 force, Body body, Vector2 relativePoint) {
applyForce(force, body, false, false, relativePoint);
}

public static void applyForce(Vector2 force, Body body, boolean relativeToVelocity, boolean relativeToMass, Vector2 relativePoint) {
Vector2 forceToApply = force.cpy();

if (relativeToVelocity) forceToApply.sub(body.getLinearVelocity());
if (relativeToMass) forceToApply.scl(body.getMass());

body.applyForce(forceToApply, relativePoint.cpy().add(body.getPosition()), true);
}
}

0 comments on commit 73c7345

Please sign in to comment.