How do I constrain the angle of links in a chain?

Not favoritedFavorited Favorited 1 favourites
  • 4 posts
From the Asset Store
3D Car Pack 1
$2.99 USD
3D models + Rendered Low-Poly Cars in isometric, top-down, and side angles.
  • Hi guys, I have been trying to make a fish character like the one in this video:

    Subscribe to Construct videos now

    I have been using the pin chain style example from the example browser, the part i am having difficulty with is preventing the chain from being able to overlap or double back on itself like he talks about at 3:40. Thoughts?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • If you limit the fish’s turning angle so it can’t make sharp turns, and its body is shorter than the turning circle (i.e. the path it would take to complete a full turn), then it won’t be able to overlap itself.

  • Roughly you’d calculate the angle difference between the two edges, and if the angle difference exceeds the angle limits you specified then you’d rotate the end edge till the angle is within range.

    We can calculate the angle of the edges with the angle() expression. To get the angle difference we could use anglediff() but we need the signed angle diff where its negative when CCW. That can be calculated with angle(0,0,cos(a-b),sin(a-b)). Then you’d check if the angle diff is greater or less that an angle limit. And if it is rotate the endpoint so it’s back in range. The formula to do that is:

    Pos: ((x-cx)*cos(a)-(y-cy)*sin(a)+cx, (x-cx)*sin(a)+(y-cy)*cos(a)+cy)

    As an example (barring any typos) this will move multiple instances of a sprite in a chain. The first instance will be moved to the mouse position, then all the following instances will be moved to be 32 pixels from each other. Then from the third instance on it limits the angle to the range (-10,10)

    Var p0=0
    Var p1=0
    Var p2=0
    Var da=0
    
    For each sprite
    — set p2 to p1
    — set p1 to p0
    — set p0 to sprite.iid
    — compare: loopindex=0
    — — sprite: set position to (mouse.x,mouse.y)
    — compare: loopindex >0
    — — sprite: move distance(self.x,self.y,sprite(p1).x,sprite(p1).y)-32 pixels at angle angle(self.x,self.y,sprite(p1).x,sprite(p1).y)
    — compare: loopindex>1
    — — set da to angle(sprite(p1).x,sprite(p1).y,sprite(p0).x,sprite(p0).y)-angle(sprite(p2).x,sprite(p2).y,sprite(p1).x,sprite(p1).y)
    — — set da to angle(0,0,cos(da),sin(da))
    — — set da to da>10?(10-da):(da<-10?(-da-10):0)
    — sprite: set position to (self.x-sprite(p1).x)*cos(da)-(self.y-sprite(p1).y)*sin(da)+sprite(p1).x, self.x-sprite(p1).x)*sin(da)+(self.y-sprite(p1).y)*cos(da)+sprite(p1).y)
  • If you limit the fish’s turning angle so it can’t make sharp turns, and its body is shorter than the turning circle (i.e. the path it would take to complete a full turn), then it won’t be able to overlap itself.

    Thanks, Thats exactly what I needed! Works like a charm!

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