/** An example demonstrating the use of Path Actions. This role can produce different paths, depending on the [type] @Attribute value. */ class PathRole : ActionRole { @Attribute var type = PathType.LINE override fun createAction() : Action { // Create a path starting at (0,0). A big if..else it... else, val path = if ( type == PathType.BOX ) { // A box made up of straight lines Path().apply { // Note, we are using *absolute* positions for each section of the path lineTo( 200, 0 ) lineTo( 200, 100 ) lineTo( 0, 100 ) lineTo( 0, 0 ) } } else if ( type == PathType.SAUSSAGE ) { // Two paralledl lines joined by semi-circles. val r = 50 Path().apply { // Note, we are using *relative* values for each section of the path. lineBy( 300, 0 ) circularArcBy( Vector2(0, r*2), r, true, true ) // Semicircle lineBy( -300, 0 ) circularArcBy( Vector2(0, r*-2), r, true, true ) // Semicircle } } else if (type == PathType.BEZIER ) { Path().apply { bezierBy( Vector2(400, 100), Vector2( 200, 0 ), Vector2( -200, 0 ) ) } } else if (type == PathType.BEZIER_LOOP ) { Path().apply { bezierBy( Vector2(400, 100), Vector2( 200, 0 ), Vector2( 0, -20 ) ) bezierBy( Vector2(-400,-100), Vector2( 200, 0 ) ) } } else { // Not a Path, just a straight line. // NOTE, because this isn't a closed loop, it will JUMP back to the start, // when forever() restarts the follow action. Line( Vector2(0,0), Vector2(400, 0) ) } // So that all movements has the same speed val seconds = path.length() / 100 // If we wanted a fixed time, rather than a fixed speed, just replace it by : //val seconds = 1 // I've chosen easeInOut, to demonstrate that the easing function is applied to the whole // path, not to individual sections of the path. // If you omit ease, the balls will move with constant speed. val ease = Eases.easeInOut // Now return an Action which follows the path. Updating the actor's position. // We use 'relativeTo' because the paths all start at (0,0), and we want them to start // at the Actor's current position. return path.relativeTo( actor.position ).follow( actor.position, seconds /*, ease*/ ).forever() } } enum class PathType { LINE, BOX, SAUSSAGE, BEZIER, BEZIER_LOOP }