Android, 기포 애니메이션.(충돌 알고리즘 반제품)

머리말
window 기포 장벽 과 같은 애니메이션 효 과 를 만 들 려 고 했 습 니 다.어떻게 작은 공 사이 의 비대 심 충돌 공식 을 연구 하지 못 했 는 지 저 에 게 는 정말 복잡 합 니 다. 등 공식 이 저 에 게 연구 차이 가 많 지 않 을 때 계산 각도 의 문제 도 복잡 하 다 는 것 을 알 게 되 었 습 니 다.블 로 거들 은 고등학교 때 물리 가 합격 하지 못 했 고 대학 물리학 과정 이 었 다 고 말 했다. 그러나 나 는 대학 에서 물 리 를 배우 지 않 았 다.현재 만들어 진 효과 도 간단 하 다. 경계 충돌 만 검 측 했 을 뿐 원 리 는 운동량 의 보존, 속도 교환 이다.실제 효 과 는 실 처럼 매 끄 러 워 gif 가 프레임 을 녹 화 했 습 니 다.
구현 코드
이번 에는 포장 하지 않 겠 습 니 다. 어차피 반제품 일 뿐 이 라 고 쓰 여 있 습 니 다.https://github.com/lzyzsd/AndroidRandomColor 아주 좋 은 라 이브 러 리 를 사 용 했 습 니 다. 무 작위 로 예 쁜 색 을 만 들 었 습 니 다. 국민 들 이 쓴 것 은 대단 합 니 다.
/** * Created by AItsuki on 2016/1/12. */
public class BallView extends View {

    private final Random mRandom;

    class Ball {
        int radius; //   
        float cx;   //   
        float cy;   //   
        float vx; // X   
        float vy; // Y   
        Paint paint;

        //   
        void move() {
            //        ,    
            cx += vx;
            cy += vy;
        }

        int left() {
            return (int) (cx - radius);
        }

        int right() {
            return (int) (cx +radius);
        }

        int bottom() {
            return (int) (cy + radius);
        }

        int top() {
            return (int) (cy - radius);
        }
    }

    private int mCount = 40;   //     
    private int maxRadius;  //       
    private int minRadius; //       
    private int minSpeed = 5; //         
    private int maxSpeed = 20; //         

    private int mWidth = 200;
    private int mHeight = 200;


    public Ball[] mBalls;   //            

    public BallView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //       (       ,         )
        mRandom = new Random();
        RandomColor randomColor = new RandomColor(); //          ,github   。
        mBalls = new Ball[mCount];

        for(int i=0; i< mCount; i++) {
            mBalls[i] = new Ball();
            //     
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(randomColor.randomColor());
            paint.setStyle(Paint.Style.FILL);
            paint.setAlpha(180);
            paint.setStrokeWidth(0);

            //     
            float speedX = (mRandom.nextInt(maxSpeed -minSpeed +1)+5)/10f;
            float speedY = (mRandom.nextInt(maxSpeed -minSpeed +1)+5)/10f;
            mBalls[i].paint = paint;
            mBalls[i].vx = mRandom.nextBoolean() ? speedX : -speedX;
            mBalls[i].vy = mRandom.nextBoolean() ? speedY : -speedY;
        }

        //              
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = resolveSize(mWidth, widthMeasureSpec);
        mHeight = resolveSize(mHeight, heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
        maxRadius = mWidth/12;
        minRadius = maxRadius/2;

        //           
        for (int i=0; i<mBalls.length; i++) {
            mBalls[i].radius = mRandom.nextInt(maxRadius+1 - minRadius) +minRadius;
// mBalls[i].mass = (int) (Math.PI * mBalls[i].radius * mBalls[i].radius);
            //         , x    radius,    mwidth- radius
            mBalls[i].cx = mRandom.nextInt(mWidth - mBalls[i].radius) + mBalls[i].radius;
            mBalls[i].cy = mRandom.nextInt(mHeight - mBalls[i].radius) + mBalls[i].radius;
        }
    }



    @Override
    protected void onDraw(Canvas canvas) {
        long startTime = System.currentTimeMillis();

        //       
        for (int i = 0; i < mCount; i++) {
            Ball ball = mBalls[i];
            canvas.drawCircle(ball.cx, ball.cy, ball.radius, ball.paint);
        }

        //      
        for (int i = 0; i < mCount; i++) {
            Ball ball = mBalls[i];
            collisionDetectingAndChangeSpeed(ball); //        
            ball.move(); //   
        }

        long stopTime = System.currentTimeMillis();
        long runTime = stopTime - startTime;
        // 16      
        postInvalidateDelayed(Math.abs(runTime -16));
    }



    //            
    public void collisionDetectingAndChangeSpeed(Ball ball) {
        int left = getLeft();
        int top = getTop();
        int right = getRight();
        int bottom = getBottom();

        float speedX = ball.vx;
        float speedY = ball.vy;

        //     ,X     。 speed            ,       =。=
        if(ball.left() <= left && speedX < 0) {
            ball.vx = -ball.vx;
        } else if(ball.top() <= top && speedY < 0) {
            ball.vy = -ball.vy;
        } else if(ball.right() >= right && speedX >0) {
            ball.vx = -ball.vx;
        } else if(ball.bottom() >= bottom && speedY >0) {
            ball.vy = -ball.vy;
        }
    }

}

코드 를 직접 복사 하면 사용 할 수 있 기 때문에 데모 다운 로드 를 제공 하지 않 습 니 다.
뒷말
더 이상 물리 알고리즘 을 연구 하지 않 겠 습 니 다.

좋은 웹페이지 즐겨찾기