Moving platforms with advanced paths?


(John Andersson) #1

I got the basics of moving platforms down, but I can’t comprehend how to make platforms like in super mario world (platforms which follow a line). Any ideas?

Like in this example:


(Martí Angelats i Ribera) #2

What i immediatly thought:

Vector.<Point>. Then two variables (from and to) wich can be the Points itself or int with the position of it.


(John Andersson) #3

Can you elaborate a lot? xD I don’t understand


(Martí Angelats i Ribera) #4

OK. Here I go :stuck_out_tongue_winking_eye:

public class MovingPlatforms extends Entity
{
	private const SPEED:Number = 10; // px/second
	
	private var path:Vector.<Point>;
	private var from:int = 0;
	private var to:int = 1;
	private var t:Number = 0;
	
	public MovingPlatfors(/*your arguments*/, path:Vector.<Point>)
	{
		this.path = path;
	}
	
	override public function update():void
	{
		if (t <= 0)
		{
			t = FP.elapsed;
		}
		var d:Number = Point.distance(path[from], path[to]);
		var x:Number = this.x + (path[to].x - path[from].x) * t * SPEED / d * Math.atan2(path[to].x - path[from].x, path[to].y - path[from].y);
		var y:Number = this.y + (path[to].y - path[from].y) * t * SPEED / d Math.atan2(path[to].x - path[from].x, path[to].y - path[from].y);
		
		//check if you reached the next point
		if (pith(path[to].x - x, path[to].y - y) > pith(path[to].x - path[from].x, path[to].y - path[from].y))
		{
			from = to;
			
			if (from < to) //if going "down" 
			{
				to++;
				if (to >= path.length)
				{
					to = from - 2; //change the direction. This should be length - 2
				}
			}
			else
			{
				to--;
				if (to < 0)
				{
					to = from + 1; //this should be 1
				}
			}
			
			//we substract the time of the platfor to make the few part that's left (not necessary but it makes it more exact)
			t -= Point.distance(path[to], new Point(this.x, this.y));
			update(); //some recursivity 'couse it's OP
		}
		else
		{
			this.x = x;
			this.y = y;
			t = 0;
		}
	}
	
	//this is pithagoras^2 (you don't need to do sqrt to check distances)
	private function pith(n1:Number, n2:Number):Number
	{
		return n1*n1 + n2*n2;
	}
}

As always i feel tired after writting all this and i don’t want to check it. It may contain errors but you can get the idea.

PS: BTW, in Mario they used some convinient angles, this is a more general algorism.


(Jacob Albano) #5

Here’s an alternate implementation (using functionality from my OgmoLoader class) that allows you to set a path with nodes in Ogmo editor.

package
{
    import flash.geom.Point;
    import net.flashpunk.Entity;
    import net.flashpunk.FP;

    public class PathPlatform extends Entity implements IOgmoNodeHandler
    {
        private var nodes:Array;
        private var from:Point;
        private var to:Point;
        
        private var speed:Number = 10;
    
        public function PathPlatform()
        {
            nodes = [];
        }
        
        public function nodeHandler(node:XML):void
        {
            for each (var subNode:XML in node.node)
            {
                nodes.push(new Point(subNode.@x, subNode.@y));
            }
            
            if (nodes.length > 1)
            {
                from = nodes[0];
                to = nodes[1];
                
                x = from.x;
                y = from.y;
            }
        }
        
        override public function update():void
        {
            if (from == null || to == null)
                return;
                
            moveTowards(to.x, to.y, speed);
            if (distanceToPoint(to.x, to.y) < speed)
            {
                var temp:Point = to;
                to = FP.next(to, nodes, true);
                from = temp;
            }
        }
    }
}

(John Andersson) #6

I am using TILED instead of OGMO, so I guess I could use your code but instead of following nodes, I can apparently use something called polylines. How would I modify the code to follow polylines?


(Jacob Albano) #7

I’ve never used Tiled and have no idea what polylines are.