How do I make a path and then drag object over that path?

0 favourites
  • 13 posts
From the Asset Store
Use inertion of your movements to throw, rotate your objects and etc. Objects can interact with others while dragging.g
  • is there a way to make a path on layout then drag sprite over that path in runtime?

    is it possible if I make a path using timeline then drag object over that path?

    Tagged:

  • Assuming the path is a polyline and you can get the xy of all the points the you could just loop over all the pairs of points and find the closest xy on that line segment closest to the mouse, then use the closest of all of those.

    If ax,ay and bx,by are two points then the closest point to the mouse (mx,my) would be:

    t=clamp(((mx-ax)*(bx-ax)+(my-ay)*(by-ay))/((bx-ax)^2+(by-ay)^2),0,1)
    x=lerp(ax,bx,t)
    y=lerp(ay,by,t)

    That’s the math part at least.

    So roughly you’d loop over each pair of points on the path, calculate and create an object on the closest point on that line segment to the mouse, and the pick the new object closest to the mouse and position the player there. The only drawback is you can jump to any point on the path.

    An improvement would be to keep track of what line segment the player is on and when you calculate t you can then check if it’s 0 or 1. If it is then you could also check the neighboring line segments for the closest points. You can do that repeatedly but doing it once per tick should be enough unless you’re using very curved paths with short distances between points.

    Anyways that’s the general idea. The path can be anything and come from anywhere but you’d need it to be a list of points that make up a polyline. You’d find the point on the current segment closest to the mouse, and if the point is on one of the ends of the segment you’d move to the next or previous pairs of points for the next iteration.

  • R0J0hound I used below method.

    | Global number ax‎ = 0
    | Global number ay‎ = 0
    | Global number bx‎ = 0
    | Global number by‎ = 0
    | Global number a‎ = 0
    | Global number d‎ = 0
    + System: On start of layout
    -> System: Set ax to point1.X
    -> System: Set ay to point1.Y
    -> System: Set bx to point2.X
    -> System: Set by to point2.Y
    -> System: Set a to angle(ax,ay,bx,by)
    
    + Touch: Is in touch
    -> System: Set d to clamp(distance(ax,ay,Touch.X,Touch.Y),0,distance(ax,ay,bx,by))
    -> star: Set position to (ax+cos(a)×d, ay+sin(a)×d)
    

    I place 2 points in layout. point1 poisition (681, 268), point2 position (426, 459).

    above code is working except one issue. when mouse is touching ahead of point1 then it still moving star towards point2

  • I fixed above issue by adding min,max

    -> System: Set d to clamp(distance(ax,ay,clamp(Touch.X,min(bx,ax),max(ax,bx)),clamp(Touch.Y,min(ay,by),max(ay,by))),0,distance(ax,ay,bx,by))

  • Try dragging from the first point away from the second. I'm not sure if that's the behavior you were after.

    Anyways here's what I posted about in example form. Most of it is just drawing and loading paths, but the last event is what limits the motion to the path. The path is defined by the p instances, and the position on the path is updated in two instance variables of the sprite object. There is also one action you can toggle to consider the path as looping or not.

    dropbox.com/scl/fi/hoj7vjcz24ufemt894uqd/drag_along_path2.capx

  • R0J0hound

    yes, that what I was trying to do, my method was not working at the end. in your example.

    clamp(((self.X-p(self.n).x)*(p(self.n+1).x-p(self.n).x)+(self.y-p(self.n).y)*(p(self.n+1).y-p(self.n).y))/((p(self.n+1).x-p(self.n).x)^2+(p(self.n+1).y-p(self.n).y)^2),0,1)

    I have multiple path and all those paths are already created on runtime. by default it picks object 'p' which was first created.

    I have set variable on 'p' by comparing which I want to choose which path to be picked.

    How can I pick a spesific path to use?

  • As is the p(n).x expression doesn’t deal with picking at all.

    You could do an object type per path and duplicate the event. Or just have one type with all the paths where you’d pick the path you want and create p sprites on them. Or you could store the points in an array and do array lookups instead of accessing the nth instance.

    You could stick with one type and consider a range of iids for each path. That would require some logic to loop the indexes in the range.

    You could also break the formula apart to be longer and more verbose using variables. Then you could mark the p instances with a path id. You’d pick the instances with a certain id then use pick nth instance for the two points and set variables from each.

    Anyways just some ideas.

  • R0J0hound I used a new object for this purpose. So instead of creating all path I'm creating only specific path which will be used. Now one issue comes here.

    clamp(((self.X-p(self.n).x)*(p(self.n+1).x-p(self.n).x)+(self.y-p(self.n).y)*(p(self.n+1).y-p(self.n).y))/((p(self.n+1).x-p(self.n).x)^2+(p(self.n+1).y-p(self.n).y)^2),0,1)
    

    this returns NaN to me, I did copy exact code from example file.

    instead of creating object start of the layout, I'm creating on triggered once.

    I did debug this code and here is the screenshot

  • Basically if two adjacent points of the path are at the same location then the formula will become 0/0 which equals NaN.

    So make sure the path has at least two points and there are no two adjacent points that are at the same location. That should prevent it.

    But say there are cases when the path has less than two points temporarily. You’d fix it by setting the sprite you’re dragging’s position after creating all the points or just don’t update the position if t is nan or if p.count<2.

  • R0J0hound there are more than 2 p.counts. its 15. I did check debug with breakpoint and I come to know that when I create all p objects. all objects were created but when I select any p object in debeug then it doesn't show its property. it showing current running loop. when all p objects are created then action for Sprite (t) and its position is set to NaN after that I can see p's property.

    and somehow if things work fine then Sprite's default position is not the first p's position.

    first time n sets -1

    Edit:

    I noticed why this issue occure. I put entire code under a variable comparision. and trigger once instead of start of layout.

    Why it causing issue putting under a variable camparision. do you know?

  • When it’s under a sub-event you run into how newly created objects aren’t available for general picking till the end of the current event tree. Search the forum about “toplevel events” to find many explanations about it.

    Anyways what’s happening is the p sprites are created but aren’t pickable the first time the every tick is run. At that point there is likely 0 pickable instances so you get a nan.

    Quick fix? Don’t make the every tick a sub-event, and instead just add the variable compare condition to it.

  • R0J0hound I got 1 issue. in your example file. set viewport to 1260 x 720 and set variable path value to 841,141,812,171,783,202,754,232,725,263,696,293,668,324,639,354,610,385,581,415,552,446,523,476,494,507,465,537,436,568

    and preview it. that blue sprite should be positioned to first p but its on the 13th.

    just change path value to default value you set. and then start set position to first p object.

    what's wrong here?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Can’t test but you can look at it in the debugger. If you position the sprite at instance 0 and set the instance variable n to 0 then it should be there.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)