好库网
/*
 * Copyright (C) 2013 Chen Hui <calmer91@链接已屏蔽>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package master.flame.danmaku.danmaku.model;

public class SpecialDanmaku extends BaseDanmaku {
    
    private class Point {
        float x, y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getDistance(Point p) {
            float _x = Math.abs(this.x - p.x);
            float _y = Math.abs(this.y - p.y);
            return (float) Math.sqrt(_x * _x + _y * _y);
        }
    }

    public class LinePath {
        Point pBegin, pEnd;
        public long duration,beginTime,endTime;
        float delatX, deltaY;        

        public void setPoints(Point pBegin, Point pEnd) {
            this.pBegin = pBegin;
            this.pEnd = pEnd;
            this.delatX = pEnd.x - pBegin.x;
            this.deltaY = pEnd.y - pBegin.y;
        }

        public float getDistance() {
            return pEnd.getDistance(pBegin);
        }

        public float[] getBeginPoint() {
            return new float[] {
                    pBegin.x, pBegin.y
            };
        }

        public float[] getEndPoint() {
            return new float[] {
                    pEnd.x, pEnd.y
            };
        }
        
    }

    public float beginX, beginY;

    public float endX, endY;

    public float deltaX, deltaY;

    public long translationDuration;

    public long translationStartDelay;

    public int beginAlpha;

    public int endAlpha;

    public int deltaAlpha;

    public long alphaDuration;

    public float rotateX, rotateZ;

    public float pivotX, pivotY;

    private float[] currStateValues = new float[4];

    public LinePath[] linePaths;


    @Override
    public void layout(IDisplayer displayer, float x, float y) {
        getRectAtTime(displayer, mTimer.currMillisecond);
    }

    @Override
    public float[] getRectAtTime(IDisplayer displayer, long currTime) {

        if (!isMeasured())
            return null;

        long deltaTime = currTime - time;

        // caculate alpha
        if (alphaDuration > 0 && deltaAlpha != 0) {
            if(deltaTime >= alphaDuration){
                alpha = endAlpha;
            }else{
                float alphaProgress = deltaTime / (float) alphaDuration;
                int vectorAlpha = (int) (deltaAlpha * alphaProgress);
                alpha = beginAlpha + vectorAlpha;
            }
        }

        // caculate x y
        float currX = beginX;
        float currY = beginY;
        long dtime = deltaTime - translationStartDelay;
        if (translationDuration > 0 && dtime >= 0 && dtime <= translationDuration) {
            float tranalationProgress = dtime / (float) translationDuration;
            if (linePaths != null) {
                LinePath currentLinePath = null;
                for (LinePath line : linePaths) {
                    if (dtime >= line.beginTime && dtime < line.endTime) {
                        currentLinePath = line;
                        break;
                    } else {
                        currX = line.pEnd.x;
                        currY = line.pEnd.y;
                    }
                }
                if (currentLinePath != null) {
                    float deltaX = currentLinePath.delatX;
                    float deltaY = currentLinePath.deltaY;
                    tranalationProgress = (deltaTime - currentLinePath.beginTime)
                            / (float) currentLinePath.duration;
                    float beginX = currentLinePath.pBegin.x;
                    float beginY = currentLinePath.pBegin.y;
                    if (deltaX != 0) {
                        float vectorX = deltaX * tranalationProgress;
                        currX = beginX + vectorX;
                    }
                    if (deltaY != 0) {
                        float vectorY = deltaY * tranalationProgress;
                        currY = beginY + vectorY;
                    }
                }
            } else {
                if (deltaX != 0) {
                    float vectorX = deltaX * tranalationProgress;
                    currX = beginX + vectorX;
                }
                if (deltaY != 0) {
                    float vectorY = deltaY * tranalationProgress;
                    currY = beginY + vectorY;
                }
            }
        } else if(dtime > translationDuration){
            currX = endX;
            currY = endY;
        }

        currStateValues[0] = currX;
        currStateValues[1] = currY;
        currStateValues[2] = currX + paintWidth;
        currStateValues[3] = currY + paintHeight;

        this.setVisibility(!isOutside());

        return currStateValues;
    }

    @Override
    public float getLeft() {
        return currStateValues[0];
    }

    @Override
    public float getTop() {
        return currStateValues[1];
    }

    @Override
    public float getRight() {
        return currStateValues[2];
    }

    @Override
    public float getBottom() {
        return currStateValues[3];
    }

    @Override
    public int getType() {
        return TYPE_SPECIAL;
    }

    public void setTranslationData(float beginX, float beginY, float endX, float endY,
            long translationDuration, long translationStartDelay) {
        this.beginX = beginX;
        this.beginY = beginY;
        this.endX = endX;
        this.endY = endY;
        this.deltaX = endX - beginX;
        this.deltaY = endY - beginY;
        this.translationDuration = translationDuration;
        this.translationStartDelay = translationStartDelay;
    }

    public void setAlphaData(int beginAlpha, int endAlpha, long alphaDuration) {
        this.beginAlpha = beginAlpha;
        this.endAlpha = endAlpha;
        this.deltaAlpha = endAlpha - beginAlpha;
        this.alphaDuration = alphaDuration;
        if(deltaAlpha != 0 && beginAlpha != AlphaValue.MAX){
            alpha = beginAlpha;
        }
    }

    public void setLinePathData(float[][] points) {
        if (points != null) {
            int length = points.length;
            this.beginX = points[0][0];
            this.beginY = points[0][1];
            this.endX = points[length - 1][0];
            this.endY = points[length - 1][1];
            if (points.length > 1) {
                linePaths = new LinePath[points.length - 1];
                for (int i = 0; i < linePaths.length; i++) {
                    linePaths[i] = new LinePath();
                    linePaths[i].setPoints(new Point(points[i][0], points[i][1]), new Point(
                            points[i + 1][0], points[i + 1][1]));
                }
                float totalDistance = 0;
                for (LinePath line : linePaths) {
                    totalDistance += line.getDistance();
                }
                LinePath lastLine = null;
                for (LinePath line : linePaths) {
                    line.duration = (long) ((line.getDistance() / totalDistance) * translationDuration);
                    line.beginTime = (lastLine == null ? 0 : lastLine.endTime);
                    line.endTime = line.beginTime + line.duration;
                    lastLine = line;
                }
                
            }
        }
    }
    
    public void updateData(float scale) {

    }
    
}