android仿摩拜貼紙碰撞|氣泡碰撞

轉(zhuǎn)載請(qǐng)注明出處

準(zhǔn)備

氣泡碰撞最重要的就是邊緣檢測(cè),氣泡的運(yùn)動(dòng)涉及到重力,方向,重心,線速度,角速度,,等等一系列因素,想要在android 用view描述現(xiàn)實(shí)世界中的氣泡實(shí)在是難度很大.網(wǎng)上查找資料后,找到了一個(gè)正好能滿足我們需求的庫(kù):jbox2d是一個(gè)2D物理引擎,原版是Box2D,采用c++編寫(xiě),jbox2d是原版的java版.在github下載項(xiàng)目編譯生成jar包,生成過(guò)程可以參考SyncAny-JBox2D運(yùn)用-打造摩拜單車(chē)貼紙動(dòng)畫(huà)效果,感謝SyncAny提供的思路,不過(guò)使用gradle打包時(shí)報(bào)錯(cuò),通過(guò)mvn install成功生成jar包.不想麻煩可以點(diǎn)此 鏈接 下載,密碼:oqwo

JBox2D初步了解點(diǎn)擊查看詳細(xì)介紹
  1. World類(lèi)(世界) 用于創(chuàng)建物理世界
  2. Body類(lèi)(剛體)理解為生活中的物體
  3. BodyDef類(lèi)(剛體描述)位置,狀態(tài)等
  4. Vec2類(lèi)(二維向量)可以用來(lái)描述運(yùn)動(dòng)的方向,力的方向,位置,速度等
  5. FixtureDef類(lèi)( 夾具,我的理解是物體是屬性,包括,shape形狀,density密度,friction摩擦系數(shù)[0,1],restitution恢復(fù)系數(shù)[0,1]等)
  6. Shape的子類(lèi)(描述剛體的形狀,有PolygonShape,CircleShape)

有了上面的準(zhǔn)備工作,和對(duì)JBox2D初步了解,我們就可以開(kāi)始擼代碼啦...
還是先看效果演示: demo.APK預(yù)覽

ball.gif

實(shí)現(xiàn)原理:

通過(guò)JBox2D提供的類(lèi)和方法描述物體的運(yùn)動(dòng)狀態(tài)然后改變android中view狀態(tài)
android中改變view的位置可以通過(guò)實(shí)時(shí)改變view的坐標(biāo)位置實(shí)現(xiàn),而這個(gè)不停變化的坐標(biāo)值,我們可以通過(guò)Body類(lèi)獲取.可以這樣理解,body就是生活中的一個(gè)物體,而view則是這個(gè)物體的影子,物體向左移動(dòng),影子也會(huì)跟著向左移動(dòng),前提是有光照,而我們要做的就是讓這個(gè)物體和影子建立聯(lián)系 綁定起來(lái) ,如何找到 "光"?

就是綁定起來(lái),使用view.setTag()把body綁定起來(lái)
實(shí)現(xiàn)步驟:
  1. 創(chuàng)建物理世界
if (world == null) {
            world = new World(new Vec2(0f, 10f));//創(chuàng)建世界,設(shè)置重力方向,y向量為正數(shù)重力方向向下,為負(fù)數(shù)則向上
        }
  1. 設(shè)置世界的邊界
    可以采用AABB類(lèi)設(shè)置邊界,這里我們通過(guò)Body剛體的屬性(BodyType類(lèi))來(lái)框定一個(gè)邊界.
    BodyType類(lèi)源碼:
/**
 * The body type.
 * static: zero mass, zero velocity, may be manually moved
 * kinematic: zero mass, non-zero velocity set by user, moved by solver
 * dynamic: positive mass, non-zero velocity determined by forces, moved by solver
 * 
 * @author daniel
 */
public enum BodyType {
    STATIC, KINEMATIC, DYNAMIC
}

定義了一個(gè)枚舉,STATIC:0重量,0速度;KINEMATIC:零質(zhì)量,非零速度由用戶設(shè)定;DYNAMIC:非零速度,正質(zhì)量鸟整,非零速度由力決定
所有我們可以通過(guò)STATIC設(shè)置一個(gè)沒(méi)有重量,沒(méi)有速度的邊界


2108-5-19.png

由上圖可以看見(jiàn),因?yàn)榧t色區(qū)域沒(méi)有重量,沒(méi)有速度,當(dāng)物體運(yùn)動(dòng)到邊界時(shí),無(wú)法繼續(xù)進(jìn)入紅色區(qū)域,只能在白色區(qū)域運(yùn)動(dòng),由于重力方向向下,最終物體會(huì)靜止在白色區(qū)域底部.
下面看一下如何設(shè)置零重力邊界:

 BodyDef bodyDef = new BodyDef();
 bodyDef.type = BodyType.STATIC;//設(shè)置零重力,零速度
PolygonShape polygonShape1 = new PolygonShape();//創(chuàng)建多邊形實(shí)例
polygonShape1.setAsBox(bodyWidth, bodyRatio);//多邊形設(shè)置成為盒型也就是矩形,傳入的參數(shù)為寬高
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = polygonShape1;//形狀設(shè)置為上面的多邊形(盒型)
fixtureDef.density = 1f;//物質(zhì)密度隨意
fixtureDef.friction = 0.3f;//摩擦系數(shù)[0,1]
fixtureDef.restitution = 0.5f;//恢復(fù)系數(shù)[0,1]
bodyDef.position.set(0, -bodyRatio);//邊界的位置
Body bodyTop = world.createBody(bodyDef);//世界中創(chuàng)建剛體
bodyTop.createFixture(fixtureDef);//剛體添加夾具

對(duì)于恢復(fù)系數(shù)restitution 等于1時(shí),為完全彈性碰撞,在(0,1)之間為非完全彈性碰撞,等于0時(shí),會(huì)融入其中.
上面就是一個(gè)矩形邊界,創(chuàng)建四個(gè)圍成一個(gè)封閉的邊界,

  1. 創(chuàng)建圓形剛體
    上面我們已經(jīng)創(chuàng)建了一個(gè)多邊形剛體,圓形剛體的創(chuàng)建方式和上面相同
CircleShape circleShape = new CircleShape();
circleShape.setRadius(radius);//設(shè)置半徑
FixtureDef fixture = new FixtureDef();
fixture.setShape(shape);
fixture.density = density;
fixture.friction = friction;
fixture.restitution = restitution;
Body body = world.createBody(bodyDef);//用世界創(chuàng)建出剛體
body.createFixture(fixture);
  1. 讓body剛體動(dòng)起來(lái)
    查看Body的源碼可以知道,提供了一些運(yùn)動(dòng)的方法
  /**
   * Set the linear velocity of the center of mass.
   * 
   * @param v the new linear velocity of the center of mass.
   */
  public final void setLinearVelocity(Vec2 v) {
    if (m_type == BodyType.STATIC) {
      return;
    }
    if (Vec2.dot(v, v) > 0.0f) {
      setAwake(true);
    }
    m_linearVelocity.set(v);
  }

通過(guò)調(diào)用setLinearVelocity(Vec2 v)給body的重心設(shè)置一個(gè)線性速度

  /**
   * Apply an impulse at a point. This immediately modifies the velocity. It also modifies the
   * angular velocity if the point of application is not at the center of mass. This wakes up the
   * body if 'wake' is set to true. If the body is sleeping and 'wake' is false, then there is no
   * effect.
   * 
   * @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
   * @param point the world position of the point of application.
   * @param wake also wake up the body
   */
  public final void applyLinearImpulse(Vec2 impulse, Vec2 point, boolean wake) {
    if (m_type != BodyType.DYNAMIC) {
      return;
    }
    if (!isAwake()) {
      if (wake) {
        setAwake(true);
      } else {
        return;
      }
    }
    m_linearVelocity.x += impulse.x * m_invMass;
    m_linearVelocity.y += impulse.y * m_invMass;
    m_angularVelocity +=
        m_invI * ((point.x - m_sweep.c.x) * impulse.y - (point.y - m_sweep.c.y) * impulse.x);
  }

調(diào)用applyLinearImpulse(Vec2 impulse, Vec2 point, boolean wake) 給某一點(diǎn)施加一個(gè)脈沖,會(huì)立刻修改速度,如果作用點(diǎn)不在重心就會(huì)修改角速度.Vec2可以傳入隨機(jī)數(shù),產(chǎn)生隨機(jī)的速度

  1. 綁定view
    我們獲取viewGroup的子控件view的個(gè)數(shù),創(chuàng)建對(duì)用數(shù)量的body,并且給view設(shè)置tag為body
...
   int childCount = mViewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childAt = mViewGroup.getChildAt(i);
            Body body = (Body) childAt.getTag(R.id.body_tag);
            if (body == null || haveDifferent) {
                createBody(world, childAt);
            }
        }
...
 /**
     * 創(chuàng)建剛體
     */
    private void createBody(World world, View view) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DYNAMIC;//有重量,有速度
        bodyDef.position.set(view.getX() + view.getWidth() / 2 ,view.getY() + view.getHeight() / 2);
        Shape shape = null;
        Boolean isCircle = (Boolean) view.getTag(R.id.circle_tag);
        if (isCircle != null && isCircle) {
            shape = createCircle(view);
        }
        FixtureDef fixture = new FixtureDef();
        fixture.setShape(shape);
        fixture.friction = friction;
        fixture.restitution = restitution;
        fixture.density = density;
        Body body = world.createBody(bodyDef);
        body.createFixture(fixture);
        view.setTag(R.id.body_tag, body);//給view綁定body
        body.setLinearVelocity(new Vec2(random.nextFloat(), random.nextFloat()));//線性運(yùn)動(dòng)
    }
  1. 實(shí)時(shí)繪制view的位置
    實(shí)時(shí)獲取body剛體的位置,然后設(shè)置給view,調(diào)用invalidate()重繪
    public void onDraw(Canvas canvas) {
        if (!startEnable)
            return;
        world.step(dt,velocityIterations,positionIterations);
        int childCount = mViewGroup.getChildCount();
        for(int i = 0; i < childCount; i++){
            View view = mViewGroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.body_tag); //從view中獲取綁定的剛體
            if(body != null){
                view.setX(body.getPosition().x - view.getWidth() / 2);//獲取剛體的位置信息
                view.setY(body.getPosition().y - view.getHeight() / 2);
                view.setRotation(radiansToDegrees(body.getAngle() % 360));//設(shè)置旋轉(zhuǎn)角度
            }
        }
        mViewGroup.invalidate();//更新view的位置
    }

這個(gè)方法在重寫(xiě)的自定義父控件的onDraw()方法中調(diào)用,后面回帖出源碼

  1. 自定義ViewGroup
    代碼很簡(jiǎn)單,需要注意的是,我們需要重寫(xiě)onDraw()方法,所以要清除WillNotDraw標(biāo)記,這樣onDraw(0方法才會(huì)執(zhí)行.
public class PoolBallView extends FrameLayout {
    private BallView ballView;
    public PoolBallView(Context context) {
        this(context,null);
    }
    public PoolBallView(Context context, AttributeSet attrs) {
        this(context, attrs,-1);
    }
    public PoolBallView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);//重寫(xiě)ondraw需要
        ballView = new BallView(context, this);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        ballView.onLayout(changed);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ballView.onDraw(canvas);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        ballView.onSizeChanged(w,h);
    }
    public BallView getBallView(){
        return this.ballView;
    }
}
使用

xml布局中添加此ViewGroup容器
java操作代碼

FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        for (int i = 0; i < imgs.length; i++) {
            ImageView imageView = new ImageView(this);//創(chuàng)建imageView控件
            imageView.setImageResource(imgs[i]);//設(shè)置資源圖片
            imageView.setTag(R.id.circle_tag, true);//設(shè)置tag
            poolBall.addView(imageView, layoutParams);//把imageView添加到父控件
            imageView.setOnClickListener(new View.OnClickListener() {//設(shè)置點(diǎn)擊事件
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "點(diǎn)擊了氣泡", Toast.LENGTH_SHORT).show();
                }
            });

ok至此,小球就會(huì)自由落體運(yùn)動(dòng)了,后面可以再加入陀螺儀方向感應(yīng),等控制操作,下面貼出小球創(chuàng)建控制類(lèi)代碼:

public class BallView {

    private Context   context;
    private World     world;//世界
    private int       pWidth;//父控件的寬度
    private int       pHeight;//父控件的高度
    private ViewGroup mViewGroup;//父控件
    private float density     = 0.5f;//物質(zhì)密度
    private float friction    = 0.5f;//摩擦系數(shù)
    private float restitution = 0.5f;//恢復(fù)系數(shù)
    private final Random random;
    private boolean startEnable        = true;//是否開(kāi)始繪制
    private int     velocityIterations = 3;//迭代速度
    private int     positionIterations = 10;//位置迭代
    private float   dt                 = 1f / 60;//刷新時(shí)間
    private int     ratio              = 50;//物理世界與手機(jī)虛擬比例

    public BallView(Context context, ViewGroup viewGroup) {
        this.context = context;
        this.mViewGroup = viewGroup;
        random = new Random();
    }
    public void onDraw(Canvas canvas) {
        if (!startEnable)
            return;
        world.step(dt, velocityIterations, positionIterations);
        int childCount = mViewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = mViewGroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.body_tag); //從view中獲取綁定的剛體
            if (body != null) {
                //獲取剛體的位置信息
                view.setX(metersToPixels(body.getPosition().x) - view.getWidth() / 2);
                view.setY(metersToPixels(body.getPosition().y) - view.getHeight() / 2);
                view.setRotation(radiansToDegrees(body.getAngle() % 360));
            }
        }
        mViewGroup.invalidate();//更新view的位置
    }

    /**
     * @param b
     */
    public void onLayout(boolean b) {
        createWorld(b);
    }

    /**
     * 創(chuàng)建物理世界
     */
    private void createWorld(boolean haveDifferent) {

        if (world == null) {
            world = new World(new Vec2(0f, 10f));//創(chuàng)建世界,設(shè)置重力方向
            initWorldBounds();//設(shè)置邊界
        }
        int childCount = mViewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childAt = mViewGroup.getChildAt(i);
            Body body = (Body) childAt.getTag(R.id.body_tag);
            if (body == null || haveDifferent) {
                createBody(world, childAt);
            }
        }
    }

    /**
     * 創(chuàng)建剛體
     */
    private void createBody(World world, View view) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DYNAMIC;

        //設(shè)置初始參數(shù),為view的中心點(diǎn)
        bodyDef.position.set(pixelsToMeters(view.getX() + view.getWidth() / 2),
                pixelsToMeters(view.getY() + view.getHeight() / 2));
        Shape shape = null;
        Boolean isCircle = (Boolean) view.getTag(R.id.circle_tag);
        if (isCircle != null && isCircle) {
            shape = createCircle(view);
        }
        FixtureDef fixture = new FixtureDef();
        fixture.setShape(shape);
        fixture.friction = friction;
        fixture.restitution = restitution;
        fixture.density = density;

        //用世界創(chuàng)建出剛體
        Body body = world.createBody(bodyDef);
        body.createFixture(fixture);
        view.setTag(R.id.body_tag, body);
        //初始化物體的運(yùn)動(dòng)行為
        body.setLinearVelocity(new Vec2(random.nextFloat(), random.nextFloat()));

    }

    /**
     * 設(shè)置世界邊界
     */
    private void initWorldBounds() {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.STATIC;//設(shè)置零重力,零速度
        float bodyWidth = pixelsToMeters(pWidth);
        float bodyHeight = pixelsToMeters(pHeight);
        float bodyRatio = pixelsToMeters(ratio);
        PolygonShape polygonShape1 = new PolygonShape();
        polygonShape1.setAsBox(bodyWidth, bodyRatio);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = polygonShape1;
        fixtureDef.density = 1f;//物質(zhì)密度
        fixtureDef.friction = 0.3f;//摩擦系數(shù)
        fixtureDef.restitution = 0.5f;//恢復(fù)系數(shù)

        bodyDef.position.set(0, -bodyRatio);
        Body bodyTop = world.createBody(bodyDef);//世界中創(chuàng)建剛體
        bodyTop.createFixture(fixtureDef);//剛體添加夾具

        bodyDef.position.set(0, bodyHeight + bodyRatio);
        Body bodyBottom = world.createBody(bodyDef);//世界中創(chuàng)建剛體
        bodyBottom.createFixture(fixtureDef);

        PolygonShape polygonShape2 = new PolygonShape();
        polygonShape2.setAsBox(bodyRatio, bodyHeight);
        FixtureDef fixtureDef2 = new FixtureDef();
        fixtureDef2.shape = polygonShape2;
        fixtureDef2.density = 0.5f;//物質(zhì)密度
        fixtureDef2.friction = 0.3f;//摩擦系數(shù)
        fixtureDef2.restitution = 0.5f;//恢復(fù)系數(shù)

        bodyDef.position.set(-bodyRatio, bodyHeight);
        Body bodyLeft = world.createBody(bodyDef);//世界中創(chuàng)建剛體
        bodyLeft.createFixture(fixtureDef2);//剛體添加物理屬性

        bodyDef.position.set(bodyWidth + bodyRatio, 0);
        Body bodyRight = world.createBody(bodyDef);//世界中創(chuàng)建剛體
        bodyRight.createFixture(fixtureDef2);//剛體添加物理屬性

    }
    /**
     * 創(chuàng)建圓形描述
     */
    private Shape createCircle(View view) {
        CircleShape circleShape = new CircleShape();
        circleShape.setRadius(pixelsToMeters(view.getWidth() / 2));
        return circleShape;
    }
    /**
     * 隨機(jī)運(yùn)動(dòng)
     * 施加一個(gè)脈沖,立刻改變速度
     */
    public void rockBallByImpulse() {
        int childCount = mViewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            Vec2 mImpulse = new Vec2(random.nextInt(1000), random.nextInt());
            View view = mViewGroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.body_tag);
            if (body != null) {
                body.applyLinearImpulse(mImpulse, body.getPosition(), true);
                Log.e("btn", "有脈沖");
            } else {
                Log.e("btn", "body == null");
            }
        }
    }
    /**
     * 向指定位置移動(dòng)
     */
    public void rockBallByImpulse(float x, float y) {
        int childCount = mViewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            Vec2 mImpulse = new Vec2(x, y);
            View view = mViewGroup.getChildAt(i);
            Body body = (Body) view.getTag(R.id.body_tag);
            if (body != null) {
                body.applyLinearImpulse(mImpulse, body.getPosition(), true);
            }
        }
    }
    public float metersToPixels(float meters) {
        return meters * ratio;
    }
    public float pixelsToMeters(float pixels) {
        return pixels / ratio;
    }
    /**
     * 弧度轉(zhuǎn)角度
     *
     * @param radians
     * @return
     */
    private float radiansToDegrees(float radians) {
        return radians / 3.14f * 180f;
    }
    /**
     * 大小發(fā)生變化
     * @param pWidth
     * @param pHeight
     */
    public void onSizeChanged(int pWidth, int pHeight) {
        this.pWidth = pWidth;
        this.pHeight = pHeight;
    }
    private void setStartEnable(boolean b) {
        startEnable = b;
    }
    public void onStart() {
        setStartEnable(true);
    }
    public void onStop() {
        setStartEnable(false);
    }
}

項(xiàng)目地址:https://github.com/truemi/Sphere-collision
box2d 圓形邊界的創(chuàng)建 :http://www.reibang.com/p/1522d97c5b39
轉(zhuǎn)載請(qǐng)注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌造寝,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惑淳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)饺窿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)歧焦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事绢馍∠虼桑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵舰涌,是天一觀的道長(zhǎng)猖任。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瓷耙,這世上最難降的妖魔是什么朱躺? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮搁痛,結(jié)果婚禮上长搀,老公的妹妹穿的比我還像新娘。我一直安慰自己鸡典,他們只是感情好源请,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著彻况,像睡著了一般谁尸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纽甘,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天良蛮,我揣著相機(jī)與錄音,去河邊找鬼贷腕。 笑死背镇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泽裳。 我是一名探鬼主播瞒斩,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涮总!你這毒婦竟也來(lái)了胸囱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瀑梗,失蹤者是張志新(化名)和其女友劉穎烹笔,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抛丽,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谤职,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亿鲜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片允蜈。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饶套,到底是詐尸還是另有隱情漩蟆,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布妓蛮,位于F島的核電站怠李,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蛤克。R本人自食惡果不足惜捺癞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咖耘。 院中可真熱鬧翘簇,春花似錦撬码、人聲如沸儿倒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夫否。三九已至,卻和暖如春叫胁,著一層夾襖步出監(jiān)牢的瞬間凰慈,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工驼鹅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留微谓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓输钩,卻偏偏與公主長(zhǎng)得像豺型,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子买乃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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

  • 開(kāi)門(mén)見(jiàn)山姻氨,一針見(jiàn)血~~先來(lái)一張圖片再說(shuō)! 前言 JBox2D是開(kāi)源的物理引擎Box2D的Java版本剪验,可以直接用于...
    紅黑軍團(tuán)號(hào)閱讀 4,557評(píng)論 4 7
  • BYXIAOBAI·2018年4月8日 前端開(kāi)發(fā)者丨HTML5 https://www.rokub.com 前言雖...
    麋鹿_720a閱讀 1,499評(píng)論 1 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理肴焊,服務(wù)發(fā)現(xiàn),斷路器功戚,智...
    卡卡羅2017閱讀 134,701評(píng)論 18 139
  • 做生活的高手娶眷,專注你的目標(biāo),專注你的夢(mèng)想啸臀,不要被你的生活所打倒届宠,不要把你的眼睛交給你的敵人,要把眼睛交給你的夢(mèng)想,...
    珣珣爸閱讀 96評(píng)論 0 0
  • 對(duì)桃花醉臉熏熏的日子已遠(yuǎn)去只留下背影席揽,看如今飛綿滾滾迷了路人的眼睛顽馋。我一雙老花改了半天卷子格外仿佛上下眼皮粘乎乎有...