Well, I played around a bit with APE again tonight. My idea didn't work. I think it's a limitation of the engine. What you really want to do is create a solid object with a moment of inertia spread out along its entire area. APE doesn't let you do that, and treats all particles as points, pretty much.
So, instead, I realized that your projectile is always going to be parallel to the line tangent to its trajectory. And the instantaneous tangent at any given time is given by the difference between the projectile's location and it's immediate prior location. So I whipped this up:
PHP Code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.utils.Timer;
import org.cove.ape.APEngine;
import org.cove.ape.Group;
import org.cove.ape.RectangleParticle;
import org.cove.ape.Vector;
public class Main extends Sprite
{
private var frontPart:RectangleParticle;
private var btn:TextField;
private var timer:Timer;
private var lastPos:Vector;
private static var conversion:Number = 180 / Math.PI; //radian to degree conversion
public function Main():void
{
lastPos = new Vector(0, 0);
frontPart = new RectangleParticle(50, 500, 50, 10, 0, false, 1);
APEngine.container = this;
APEngine.init();
var g:Group = new Group();
g.addParticle(frontPart);
APEngine.addGroup(g);
var g2:Group = new Group();
g2.addParticle(new RectangleParticle(300, 600, 1000, 50, 0, true));
g2.addCollidable(g);
APEngine.addGroup(g2);
APEngine.addForce(new Vector(0, 1));
btn = new TextField();
btn.text = "go";
btn.x = 0;
btn.y = 0;
btn.addEventListener(MouseEvent.CLICK, go);
addChild(btn);
timer = new Timer(20);
timer.addEventListener(TimerEvent.TIMER, step);
}
private function go(event:Event):void
{
btn.text = "stop";
btn.removeEventListener(MouseEvent.CLICK, go);
frontPart.addForce(new Vector(50, -80)); //change this vector to adjust firing angle/strength
timer.start();
btn.addEventListener(MouseEvent.CLICK, stopGoing);
}
private function step(event:Event):void
{
lastPos.copy(frontPart.center);
APEngine.step();
var angle:Number = Math.atan2((frontPart.center.y - lastPos.y), (frontPart.center.x - lastPos.x));
frontPart.angle = angle * conversion;
APEngine.paint();
}
private function stopGoing(event:Event):void
{
btn.text = "go";
btn.removeEventListener(MouseEvent.CLICK, stopGoing);
frontPart.position = new Vector(50, 500);
timer.reset();
btn.addEventListener(MouseEvent.CLICK, go);
}
}
}
Just an example to show you how it can be done for an arbitrary angle/strength combo.