рдПрдХ рдордирдорд╛рдирд╛ рд╡рдХреНрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЫрд╡рд┐ рдЪрд▓рддреА рд╣реИ


рдПрдХ рдПрдиреАрдореЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдп рдерд╛ - рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╡рдХреНрд░ рдХреЗ рд╕рд╛рде рдЪрд┐рддреНрд░ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред Googled рдФрд░ рдпрд╣ рдЬрд╛рдирдХрд░ рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ stackoverflow.com рдкрд░ рдПрдХ рд╕рдорд╛рди рдХрд╛рд░реНрдп рд╡рд╛рд▓реЗ рдХрдИ рдкреНрд░рд╢реНрди рдПрдХ рд╡рд░реНрд╖ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд╕реЗ рдЕрдиреБрддреНрддрд░рд┐рдд рд╣реИрдВред рдореБрдЭреЗ рдЕрдкрдиреА рдЖрд╕реНрддреАрди рдКрдкрд░ рд░реЛрд▓ рдХрд░рдиреА рдереА, рджрд╕реНрддрд╛рд╡реЗрдЬ рдореЗрдВ рддрд▓реНрд▓реАрди рдХрд░рдирд╛ рдФрд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬрдирд╛ рдерд╛ред
рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рд╡рдХреНрд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рд╕реЗ рдирд┐рд░реНрдорд┐рдд рдФрд░ рд╕реБрдВрджрд░рддрд╛ рдХреЗ рд▓рд┐рдП рдЪрд┐рдХрдиреАред
//  List<PointF> aPoints = new ArrayList<PointF>(); aPoints.add(new PointF(10f, 160f)); aPoints.add(new PointF(100f, 100f)); aPoints.add(new PointF(300f, 220f)); aPoints.add(new PointF(640f, 180f)); //   Path ptCurve = new Path(); PointF point = aPoints.get(0); ptCurve.moveTo(point.x, point.y); for(int i = 0; i < aPoints.size() - 1; i++){ point = aPoints.get(i); PointF next = aPoints.get(i+1); ptCurve.quadTo( point.x, point.y, (next.x + point.x) / 2, (point.y + next.y) / 2 ); } 


рдХрд╛рд░реНрдп рд╣рдорд╛рд░реА рддрд╕реНрд╡реАрд░ рдХреЛ рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд╡рдХреНрд░ рдкрд░ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, PathMeasure рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЗрд╕ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╡рдХреНрд░ рдХреА рд▓рдВрдмрд╛рдИ "рдорд╛рдк"ред рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рдмрд┐рдВрджреБ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрд┐рдВрджреБ рдХреЛ рд╢реБрд░реБрдЖрдд рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡рдХреНрд░ рдХреЗ рдмреАрдЪ рдореЗрдВ рдмрд┐рдВрджреБ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
  PathMeasure pm = new PathMeasure(ptCurve, false); float afP[] = {0f, 0f}; //   pm.getPosTan(pm.getLength() * 0.5f, afP, null); 


рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ (рдореИрдВрдиреЗ рд╡рд╣рд╛рдВ null рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛) рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реА рддрд░рд╣ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдореЗрдВ, рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╕реНрдкрд░реНрд╢рд░реЗрдЦрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ getMatrix рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдПрдХ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рджреЗрддреА рд╣реИ - рдСрдлрд╕реЗрдЯ рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рдШреБрдорд╛рд╡ред рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред
  Matrix mxTransform = new Matrix(); pm.getMatrix( pm.getLength() * 0.5f, mxTransform, PathMeasure.POSITION_MATRIX_FLAG + PathMeasure.TANGENT_MATRIX_FLAG ); mxTransform.preTranslate(-bmSprite.getWidth(), -bmSprite.getHeight()); canvas.drawBitmap(bmSprite, mxTransform, null); 


рдпрд╣ рд╡рд╣реА рдирд┐рдХрд▓рд╛ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рдерд╛:


рдкреВрд░рд╛ рдХреЛрдб рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдЖрдк рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рд╕реНрдкреНрд░рд╛рдЗрдЯрдЕрд▓реИрдВрдЧрдкрд╛рде рдпрд╛ рдорд░реНрдХреНрдпреВрд░рд┐рдпрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - hg clone bitbucket.org/TedBeer/spritealongpath hg clone bitbucket.org/TedBeer/spritealongpath

 /** * User: TedBeer * Date: 30/01/12 * Time: 12:32 */ package net.tedbeer; import android.app.Activity; import android.os.Bundle; import android.content.Context; import android.graphics.*; import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.Toast; import java.util.*; public class moveSprite extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SceneView(this)); } } public class SceneView extends View { private static Bitmap bmSprite; private static Bitmap bmBackground; private static Rect rSrc, rDest; //animation step private static int iMaxAnimationStep = 20; private int iCurStep = 0; //points defining our curve private List<PointF> aPoints = new ArrayList<PointF>(); private Paint paint; private Path ptCurve = new Path(); //curve private PathMeasure pm; //curve measure private float fSegmentLen; //curve segment length public SceneView(Context context) { super(context); //destination rectangle Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); rDest = new Rect(0, 0, display.getWidth(), display.getHeight()); //load background if (bmBackground == null) { bmBackground = BitmapFactory.decodeResource(getResources(), R.drawable.winter_mountains); rSrc = new Rect(0, 0, bmBackground.getWidth(), bmBackground.getHeight()); } //load sprite if (bmSprite == null) bmSprite = BitmapFactory.decodeResource(getResources(), R.drawable.sledge3); //init random set of points aPoints.add(new PointF(10f, 160f)); aPoints.add(new PointF(100f, 100f)); aPoints.add(new PointF(300f, 220f)); aPoints.add(new PointF(640f, 180f)); //init smooth curve PointF point = aPoints.get(0); ptCurve.moveTo(point.x, point.y); for(int i = 0; i < aPoints.size() - 1; i++){ point = aPoints.get(i); PointF next = aPoints.get(i+1); ptCurve.quadTo(point.x, point.y, (next.x + point.x) / 2, (point.y + next.y) / 2); } pm = new PathMeasure(ptCurve, false); fSegmentLen = pm.getLength() / iMaxAnimationStep;//20 animation steps //init paint object paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(3); paint.setColor(Color.rgb(0, 148, 255)); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bmBackground, rSrc, rDest, null); canvas.drawPath(ptCurve, paint); //animate the sprite Matrix mxTransform = new Matrix(); if (iCurStep <= iMaxAnimationStep) { pm.getMatrix(fSegmentLen * iCurStep, mxTransform, PathMeasure.POSITION_MATRIX_FLAG + PathMeasure.TANGENT_MATRIX_FLAG); mxTransform.preTranslate(-bmSprite.getWidth(), -bmSprite.getHeight()); canvas.drawBitmap(bmSprite, mxTransform, null); iCurStep++; //advance to the next step invalidate(); } else { iCurStep = 0; } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN ) { //run animation invalidate(); return true; } return false; } } 


рдЕрдкрдбреЗрдЯ: рд╡реАрдбрд┐рдпреЛ рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджрд┐рдпрд╛, рдЬрд╣рд╛рдВ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗ рд░рд╣рд╛ рд╣реИ рдХрд┐ рд╕реНрдкреНрд░рд╛рдЗрдЯ рднреА рдШреВрдорддрд╛ рд╣реИред
рдЯреНрд╡рд┐рди-рдПрдВрдЧ рд╢рд╛рдЦрд╛ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЬрд╛рд╡рд╛-рдпреВрдирд┐рд╡рд░реНрд╕рд▓-рдЯреНрд╡реАрди-рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдиреАрдореЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

Source: https://habr.com/ru/post/In137294/


All Articles