貝塞爾曲線實(shí)踐--拖拽氣泡

貝塞爾曲線掃盲

大家不明白貝塞爾的可以來這里逛逛~~ 淺顯易懂

貝塞爾曲線主要由于三個(gè)部分控制:起點(diǎn),終點(diǎn),中間的輔助控制點(diǎn)。在android自帶的Path類中自帶了方法参滴,可以幫助我們實(shí)現(xiàn)貝塞爾曲線:

二階貝塞爾

/** 
 * Add a quadratic bezier from the last point, approaching control point 
 * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for 
 * this contour, the first point is automatically set to (0,0). 
 * 
 * @param x1 The x-coordinate of the control point on a quadratic curve 
 * @param y1 The y-coordinate of the control point on a quadratic curve 
 * @param x2 The x-coordinate of the end point on a quadratic curve 
 * @param y2 The y-coordinate of the end point on a quadratic curve 
 */  
public void quadTo(float x1, float y1, float x2, float y2) {  
    isSimplePath = false;  
    native_quadTo(mNativePath, x1, y1, x2, y2);  
} 

quadTo()方法從上一個(gè)點(diǎn)為起點(diǎn)開始繪制貝塞爾曲線,其中(x1锻弓,y1)為輔助控制點(diǎn)砾赔,(x2,y2)為終點(diǎn)青灼。

Path mPath = new Path();
mPath.moveTo(x0,y0);
mPath.quadTo(x1,y1,x2,y2);

如調(diào)用以上代碼暴心,即繪制起點(diǎn)(x0,y0)聚至,終點(diǎn)(x2酷勺,y2)本橙,輔助控制點(diǎn)(x1扳躬,y1)的貝塞爾曲線。因此甚亭,通過不斷改變這三個(gè)點(diǎn)的位置贷币,我們可以繪制出各種各樣的曲線

三階貝塞爾

/** 
 * Add a cubic bezier from the last point, approaching control points 
 * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been 
 * made for this contour, the first point is automatically set to (0,0). 
 * 
 * @param x1 The x-coordinate of the 1st control point on a cubic curve 
 * @param y1 The y-coordinate of the 1st control point on a cubic curve 
 * @param x2 The x-coordinate of the 2nd control point on a cubic curve 
 * @param y2 The y-coordinate of the 2nd control point on a cubic curve 
 * @param x3 The x-coordinate of the end point on a cubic curve 
 * @param y3 The y-coordinate of the end point on a cubic curve 
 */  
public void cubicTo(float x1, float y1, float x2, float y2,  
                    float x3, float y3) {  
    isSimplePath = false;  
    native_cubicTo(mNativePath, x1, y1, x2, y2, x3, y3);  
}  

cubicTo()方法從上一個(gè)點(diǎn)為起點(diǎn)開始繪制三階貝塞爾曲線,其中(x1亏狰,y1),( x2, y2 )為輔助控制點(diǎn)役纹,(x3,y3)為終點(diǎn)暇唾。

拖拽氣泡實(shí)踐

思路

拖拽氣泡,其實(shí) 就是這樣的幾個(gè)狀態(tài)

  • 1.氣泡靜止?fàn)顟B(tài) --氣泡小球和數(shù)字
  • 2.氣泡相連 -- 兩個(gè)相連的氣泡小球(帶黏連效果),和數(shù)字
  • 3.氣泡分離 -- 單個(gè)氣泡小球的拖動(dòng)
  • 4.氣泡消失 -- 爆炸

我們需要在這幾個(gè)狀態(tài)分別,做出處理.

這里寫圖片描述

1.兩個(gè)圓和一個(gè)角度

  • 一個(gè)靜止的圓O1
  • 一個(gè)動(dòng)的圓O2
  • 互補(bǔ)角和內(nèi)錯(cuò)角<@

根據(jù)圓的關(guān)系,和Anchor點(diǎn),計(jì)算出角度<@,用來求貝塞爾曲線的ABCD點(diǎn)坐標(biāo).

2.兩條貝塞爾二階曲線

  • 上半邊: A---Ar---B, 以Ar為錨點(diǎn),A和B重點(diǎn)的二階曲線

  • 下半邊: C---Ar---D,以Ar為錨點(diǎn),C和D重點(diǎn)的二階曲線

具體坐標(biāo)的求法,在上圖中可見.

根據(jù)貝塞爾曲線的要求:
起點(diǎn)促脉,終點(diǎn)辰斋,中間的輔助控制點(diǎn)。用在android自帶的Path類中自帶了方法.

舉個(gè)例子,就可以這么做

上邊線:

            //畫上半弧 B-->A---------------

            //A點(diǎn)靜坐標(biāo)計(jì)算
            float mBubStillAX = mBubStillCenter.x -mBubStillRadius*sinTheta;
            float mBubStillAY = mBubStillCenter.y +mBubStillRadius*cosTheta;

            //B點(diǎn)動(dòng)坐標(biāo)計(jì)算
            float mBubMoveBX = mBubMoveableCenter.x -mBubMoveableRadius*sinTheta;
            float mBubMoveBY = mBubMoveableCenter.y +mBubMoveableRadius*cosTheta;

            mBezierPath.moveTo(mBubStillAX,mBubStillAY);
            mBezierPath.quadTo(iAnchorX,iAnchorY,mBubMoveBX,mBubMoveBY);

3.狀態(tài)判斷OnTouch

onTouchEvent()中,對(duì)touch事件進(jìn)行自己處理,即return true進(jìn)行以下幾個(gè)狀態(tài)切換.

  • 按下, 如果 當(dāng)前狀態(tài) 沒有消失, 則計(jì)算 當(dāng)前氣泡距離,和 最大允許偏移量 作比較 ,進(jìn)行狀態(tài)切換
  • 移動(dòng) ,改變動(dòng)點(diǎn)的位置, 計(jì)算兩點(diǎn)距離, 改變 靜止點(diǎn)的半徑,切換狀態(tài),并重繪制,調(diào)用ondraw
  • 抬起手, 根據(jù) 鏈接 狀態(tài), 開始進(jìn)行 動(dòng)畫

4.繪制不同 OnDraw

根據(jù)上述不同的狀態(tài),繪制不同的view.

  • 1當(dāng) 當(dāng)前狀態(tài) != 消失, 則, 畫 移動(dòng)的氣泡 和文字
  • 2.相連的氣泡狀態(tài),繪制貝塞爾曲線
  • 3.boom,爆炸狀態(tài), 爆炸效果動(dòng)畫

最終效果

這里寫圖片描述

實(shí)現(xiàn)源碼


/**
 * 仿QQ拖拽氣泡
 * Created by chenchangjun on 17/5/25.
 *
 */

public class DragBuubbleView extends View {

    public Context mContext;

    /**
     * state  根據(jù) ontouch事件進(jìn)行判斷,
     */
    private final int STATE_DEFAULT = 0;//  1.氣泡靜止?fàn)顟B(tài) --氣泡小球和數(shù)字
    private final int STATE_CONECTED = 1;//2.氣泡相連 -- 兩個(gè)相連的氣泡小球(帶黏連效果),和數(shù)字

    private final int STATE_APART = 2;//3.氣泡分離 -- 單個(gè)氣泡小球的拖動(dòng)

    private final int STATE_DISMISS = 3;//4.氣泡消失 -- 爆炸



    //default values;
    private float default_radius;
    private int default_bubble_color;
    private String default_bubble_text;
    private int default_bubble_textColor;
    private float default_bubble_textSize;
    private float default_bubble_radius;


    private float bubble_radius;//小球半徑
    private int bubble_color;//小球顏色
    private String bubble_text;//小球顯示字
    private int bubble_textColor; //字體顏色
    private float bubble_textSize;//字體大小

    /**
     * 靜止氣泡和動(dòng)態(tài)氣泡相關(guān)
     */
    private float mBubStillRadius;//不動(dòng)氣泡的半徑
    private float mBubMoveableRadius;//可動(dòng)氣泡的半徑
    private PointF mBubStillCenter;//不動(dòng)氣泡的圓心
    private PointF mBubMoveableCenter;//可動(dòng)氣泡的圓心
    private Paint mBubblePaint;//氣泡的畫筆


    /**
     * 貝塞爾曲線path相關(guān)
     */
    private Path mBezierPath;

    private Paint mTextPaint;

    private Rect mTextRect;

    private Paint mBurstPaint;

    private Rect mBurstRect;


    private int current_state = STATE_DEFAULT;//當(dāng)前狀態(tài)
    private float bubbleDistance; //氣泡間距
    private float maxDistance; //氣泡最大間距

    private float MOVE_OFFSET = 0;//允許你的 手指觸摸偏移量
    private Bitmap[] burstBitmapsArray;//氣泡爆炸bitmap數(shù)組
    private boolean isBurstAnimStart = false; //是否執(zhí)行 氣泡爆炸

    private int curDrawableIndex; //當(dāng)前氣泡爆炸圖片index

    //氣泡爆炸的圖片id數(shù)組
    private int[] burstDrawablesArray = {R.drawable.burst_1, R.drawable.burst_2
            , R.drawable.burst_3, R.drawable.burst_4, R.drawable.burst_5};


    private void init(Context context, AttributeSet attrs) {
        this.mContext = context;
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DragBubbleView);

            bubble_radius = typedArray.getDimension(R.styleable.DragBubbleView_bubble_radius, default_bubble_radius);
            bubble_color = typedArray.getColor(R.styleable.DragBubbleView_bubble_color, default_bubble_color);

            bubble_textSize = typedArray.getDimension(R.styleable.DragBubbleView_bubble_textSize, default_bubble_textSize);
            bubble_textColor = typedArray.getColor(R.styleable.DragBubbleView_bubble_textColor, default_bubble_textColor);
            bubble_text = typedArray.getString(R.styleable.DragBubbleView_bubble_text);
            typedArray.recycle();

        }
        mBubStillRadius = bubble_radius;
        mBubMoveableRadius = mBubStillRadius;
        maxDistance = 8 * bubble_radius;

        MOVE_OFFSET = maxDistance / 4;


        //氣泡畫筆
        mBubblePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBubblePaint.setColor(bubble_color);
        mBubblePaint.setStyle(Paint.Style.FILL);
        mBezierPath = new Path();
        //文字畫筆
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(bubble_textColor);
        mTextPaint.setTextSize(bubble_textSize);
        mTextRect = new Rect();
        //爆炸畫筆
        mBurstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBurstPaint.setFilterBitmap(true);
        mBurstRect = new Rect();
        burstBitmapsArray = new Bitmap[burstDrawablesArray.length];
        for (int i = 0; i < burstDrawablesArray.length; i++) {
            //將氣泡爆炸的drawable轉(zhuǎn)為bitmap
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), burstDrawablesArray[i]);
            burstBitmapsArray[i] = bitmap;
        }

    }

    private void initView(int w, int h) {

        //設(shè)置兩氣泡圓心初始坐標(biāo)
        if (mBubStillCenter == null) {
            mBubStillCenter = new PointF(w / 2, h / 2);
        } else {
            mBubStillCenter.set(w / 2, h / 2);
        }
        //設(shè)置動(dòng)點(diǎn)坐標(biāo)
        if (mBubMoveableCenter == null) {
            mBubMoveableCenter = new PointF(w / 2, h / 2);
        } else {
            mBubMoveableCenter.set(w / 2, h / 2);
        }
        current_state = STATE_DEFAULT;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //當(dāng) 當(dāng)前狀態(tài) != 消失, 則, 畫  移動(dòng)的氣泡 和文字
        if (current_state != STATE_DISMISS) {
            canvas.drawCircle(mBubMoveableCenter.x,mBubMoveableCenter.y,
                    mBubMoveableRadius,mBubblePaint);
            mTextPaint.getTextBounds(bubble_text, 0, bubble_text.length(), mTextRect);

            canvas.drawText(bubble_text, mBubMoveableCenter.x - mTextRect.width() / 2, mBubMoveableCenter.y + mTextRect.height() / 2, mTextPaint);
        }



        //2.相連的氣泡狀態(tài),繪制貝塞爾曲線
        if (current_state == STATE_CONECTED) {
            //1.靜止氣泡
            canvas.drawCircle(mBubStillCenter.x, mBubStillCenter.y, mBubStillRadius, mBubblePaint);
            //重置path狀態(tài)
            mBezierPath.reset();


            //2.相連曲線---貝塞爾曲線
            //計(jì)算控制點(diǎn)坐標(biāo)---兩個(gè)球圓心的中點(diǎn).
            int iAnchorX = (int) ((mBubStillCenter.x + mBubMoveableCenter.x) / 2);
            int iAnchorY = (int) ((mBubStillCenter.y + mBubMoveableCenter.y) / 2);
            //計(jì)算 三角函數(shù)
            float cosTheta = (mBubStillCenter.x - mBubMoveableCenter.x)/bubbleDistance;
            float sinTheta = (mBubStillCenter.y - mBubMoveableCenter.y)/bubbleDistance;


            //畫上半弧 B-->A---------------

            //A點(diǎn)靜坐標(biāo)計(jì)算
            float mBubStillAX = mBubStillCenter.x -mBubStillRadius*sinTheta;
            float mBubStillAY = mBubStillCenter.y +mBubStillRadius*cosTheta;

            //B點(diǎn)動(dòng)坐標(biāo)計(jì)算
            float mBubMoveBX = mBubMoveableCenter.x -mBubMoveableRadius*sinTheta;
            float mBubMoveBY = mBubMoveableCenter.y +mBubMoveableRadius*cosTheta;

            mBezierPath.moveTo(mBubStillAX,mBubStillAY);
            mBezierPath.quadTo(iAnchorX,iAnchorY,mBubMoveBX,mBubMoveBY);

            //畫下半弧 C-->D-------------

            //C點(diǎn)動(dòng)坐標(biāo)計(jì)算
            float mBubMoveCX = mBubMoveableCenter.x +mBubMoveableRadius*sinTheta;
            float mBubMoveCY = mBubMoveableCenter.y -mBubMoveableRadius*cosTheta;

            //D點(diǎn)靜坐標(biāo)計(jì)算
            float mBubStillDX = mBubStillCenter.x +mBubStillRadius*sinTheta;
            float mBubStillDY = mBubStillCenter.y -mBubStillRadius*cosTheta;

            mBezierPath.lineTo(mBubMoveCX,mBubMoveCY);
            mBezierPath.quadTo(iAnchorX,iAnchorY,mBubStillDX,mBubStillDY);

            //釋放資源,并畫----------
            mBezierPath.close();
            canvas.drawPath(mBezierPath,mBubblePaint);


        }

        //boom,爆炸狀態(tài), 爆炸效果動(dòng)畫
        if(isBurstAnimStart){
            mBurstRect.set((int)(mBubMoveableCenter.x - mBubMoveableRadius),
                    (int)(mBubMoveableCenter.y - mBubMoveableRadius),
                    (int)(mBubMoveableCenter.x + mBubMoveableRadius),
                    (int)(mBubMoveableCenter.y + mBubMoveableRadius));

            canvas.drawBitmap(burstBitmapsArray[curDrawableIndex],null,
                    mBurstRect,mBubblePaint); }


    }

    /**
     * 重置狀態(tài)
     */
    public void reset(){

        initView(getWidth(),getHeight());
        invalidate();
    }


    /**
     * 開始?xì)馀?重置狀態(tài) 的動(dòng)畫
     */
    private void startBubbleRestAnim() {
        ValueAnimator anim = ValueAnimator.ofObject(new PointFEvaluator(),
                new PointF(mBubMoveableCenter.x,mBubMoveableCenter.y),
                new PointF(mBubStillCenter.x,mBubStillCenter.y));

        anim.setDuration(200);
        anim.setInterpolator(new OvershootInterpolator(5f));
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mBubMoveableCenter = (PointF) animation.getAnimatedValue();
                invalidate();
            }
        });
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                current_state= STATE_DEFAULT;
            }
        });
        anim.start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initView(w, h);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            //按下, 如果 當(dāng)前狀態(tài) 沒有消失, 則計(jì)算 當(dāng)前氣泡距離,和 最大允許偏移量 作比較 ,進(jìn)行狀態(tài)切換
            case MotionEvent.ACTION_DOWN:
            if(current_state!=STATE_DISMISS){
                bubbleDistance=(float) Math.hypot(event.getX()-mBubStillCenter.x,event.getY()-mBubStillCenter.y);

                if (bubbleDistance<bubble_radius+MOVE_OFFSET){
                    current_state=STATE_CONECTED;
                }else {
                    current_state=STATE_DEFAULT;
                }
            }


                break;
            //移動(dòng) ,改變動(dòng)點(diǎn)的位置, 計(jì)算兩點(diǎn)距離, 改變 靜止點(diǎn)的半徑,切換狀態(tài),并重繪制,調(diào)用ondraw
            case MotionEvent.ACTION_MOVE:
            {
                if(current_state != STATE_DEFAULT){
                    mBubMoveableCenter.x = event.getX();
                    mBubMoveableCenter.y = event.getY();
                    bubbleDistance = (float) Math.hypot(event.getX() - mBubStillCenter.x,
                            event.getY() - mBubStillCenter.y);
                    if(current_state == STATE_CONECTED){
                        // 減去MOVE_OFFSET是為了讓不動(dòng)氣泡半徑到一個(gè)較小值時(shí)就直接消失
                        // 或者說是進(jìn)入分離狀態(tài)
                     if(bubbleDistance < maxDistance - MOVE_OFFSET){

                            mBubStillRadius = bubble_radius - bubbleDistance / 8;
                        }else{
                            current_state = STATE_APART;
                        }
                    }
                    invalidate();
                }
            }
            break;
            //抬起手, 根據(jù) 鏈接 狀態(tài), 開始進(jìn)行 動(dòng)畫
            case MotionEvent.ACTION_UP:
            {
                if(current_state == STATE_CONECTED){
                    startBubbleRestAnim();

                }else if(current_state == STATE_APART){
                    if(bubbleDistance < 2 * bubble_radius){
                        startBubbleRestAnim();
                    }else{
                        startBubbleBurstAnim();
                    }
                }
            }
            break;
        }

        return true;

    }

    /**
     * 氣泡消失動(dòng)畫
     */
    private void startBubbleBurstAnim() {
        //氣泡改為消失狀態(tài)
        current_state = STATE_DISMISS;
        isBurstAnimStart = true;
        //做一個(gè)int型屬性動(dòng)畫瘸味,從0~mBurstDrawablesArray.length結(jié)束
        ValueAnimator anim = ValueAnimator.ofInt(0, burstDrawablesArray.length);
        anim.setInterpolator(new LinearInterpolator());
        anim.setDuration(500);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //設(shè)置當(dāng)前繪制的爆炸圖片index
                curDrawableIndex = (int) animation.getAnimatedValue();
                invalidate();
            }
        });
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                //修改動(dòng)畫執(zhí)行標(biāo)志
                isBurstAnimStart = false;
            }
        });
        anim.start();

    }





    public DragBuubbleView(Context context) {
        super(context);
        init(context, null);

    }


    public DragBuubbleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }


    public DragBuubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public DragBuubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);

    }


}




代碼下載:

https://github.com/ccj659/UI/

參考

1.一篇很好的貝塞爾掃盲文章-----送給你

2.一篇貝塞爾,代碼繪制文章---送給你

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宫仗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子旁仿,更是在濱河造成了極大的恐慌藕夫,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枯冈,死亡現(xiàn)場離奇詭異毅贮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)尘奏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門滩褥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炫加,你說我怎么就攤上這事铸题。” “怎么了琢感?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵丢间,是天一觀的道長。 經(jīng)常有香客問我驹针,道長烘挫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任柬甥,我火速辦了婚禮饮六,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苛蒲。我一直安慰自己卤橄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布臂外。 她就那樣靜靜地躺著窟扑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漏健。 梳的紋絲不亂的頭發(fā)上嚎货,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音蔫浆,去河邊找鬼殖属。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瓦盛,可吹牛的內(nèi)容都是我干的洗显。 我是一名探鬼主播外潜,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼挠唆!你這毒婦竟也來了橡卤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤损搬,失蹤者是張志新(化名)和其女友劉穎碧库,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巧勤,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嵌灰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颅悉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沽瞭。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剩瓶,靈堂內(nèi)的尸體忽然破棺而出驹溃,到底是詐尸還是另有隱情,我是刑警寧澤延曙,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布豌鹤,位于F島的核電站,受9級(jí)特大地震影響枝缔,放射性物質(zhì)發(fā)生泄漏布疙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一愿卸、第九天 我趴在偏房一處隱蔽的房頂上張望灵临。 院中可真熱鬧,春花似錦趴荸、人聲如沸儒溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顿涣。三九已至,卻和暖如春笼平,著一層夾襖步出監(jiān)牢的瞬間园骆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工寓调, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锄码。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓夺英,卻偏偏與公主長得像晌涕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痛悯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容