iOS使用动画构建海底世界

效果如图:


鱼的最大数量可控制,运动速度随机,大小随机,摆尾速度随机,运动轨迹随机,气泡个数随机,气泡位置随机,出现时间随机。

参考文章:波浪效果
     帧动画与UIView动画
     气泡

1.先写一个波浪效果:TBMyInfoTopView.swift


import UIKit
class TBMyInfoTopView: UIView {
    
    //提供给外部调用接口
    
    ///曲线振幅
    var waterAmplitude: CGFloat = 8
    ///曲线角速度
    var waterPalstance: CGFloat = 0
    ///曲线初相
    var waterX: CGFloat = 0
    ///曲线偏距
    let waterY: CGFloat = 100
    ///曲线移动速度
    var waterMoveSpeed: CGFloat = 0
    
    //内部接口

    fileprivate let waterColor = UIColor(red: 118/255.0, green: 165/255.0, blue: 242/255.0, alpha: 0.6)
    fileprivate let BackGroundColor = UIColor(red: 80/255.0, green: 140/255.0, blue: 238/255.0, alpha: 1)
    //前面的波浪
    fileprivate let waterLayer1 = CAShapeLayer()
    fileprivate let waterLayer2 = CAShapeLayer()
    fileprivate var disPlayLink = CADisplayLink()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = BackGroundColor
        buildInterface()
        buildData()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func buildInterface(){
        //初始化波浪
        waterLayer1.fillColor = waterColor.cgColor
        waterLayer1.strokeColor = waterColor.cgColor
        waterLayer1.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        waterLayer2.fillColor = waterColor.cgColor
        waterLayer2.strokeColor = waterColor.cgColor
        waterLayer2.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        layer.addSublayer(waterLayer1)
        layer.addSublayer(waterLayer2)
    }
    
    ///初始化数据
    func buildData(){
        waterPalstance = CGFloat(Double.pi) / bounds.size.width
        waterMoveSpeed = 5 * waterPalstance
        //以屏幕刷新速度为周期刷新曲线的位置
        disPlayLink = CADisplayLink(target: self, selector: #selector(self.updatewater(link:)))
        disPlayLink.add(to: RunLoop.main, forMode: .commonModes)
    }
    
    func updatewater(link: CADisplayLink){
        //更新x
        waterX += waterMoveSpeed
        updatewater(shapLayer: waterLayer1, isSin: false)
        updatewater(shapLayer: waterLayer2, isSin: true)
    }
    
    func updatewater(shapLayer: CAShapeLayer, isSin: Bool){
        //波浪宽度
        let waterwaterWidth = bounds.size.width
        //初始化运动路径
        let path = CGMutablePath()
        //设置起始位置
        path.move(to: CGPoint(x: 0, y: waterY))
        //初始化波浪,y为偏距
        var tempY = waterY
        //正弦曲线公式为: y=Asin(ωx+φ)+k
        for x in 0..<Int(waterwaterWidth){
            tempY = isSin ? waterAmplitude * sin(waterPalstance * CGFloat(x) + waterX) + waterY : waterAmplitude * cos(waterPalstance * CGFloat(x) + waterX) + waterY
            path.addLine(to: CGPoint(x: CGFloat(x), y: tempY))
        }
        //填充底部颜色
        path.addLine(to: CGPoint(x: waterwaterWidth, y: 200))
        path.addLine(to: CGPoint(x: 0, y: 200))
        path.closeSubpath()
        shapLayer.path = path
    }
}

使用方法

2.加上旋转的阳光

更改上面的代码,更改后如下:

import UIKit

class TBMyInfoTopView: UIView {
    
    //提供给外部调用接口
    
    ///曲线振幅
    var waterAmplitude: CGFloat = 8
    ///曲线角速度
    var waterPalstance: CGFloat = 0
    ///曲线初相
    var waterX: CGFloat = 0
    ///曲线偏距
    let waterY: CGFloat = 70
    ///曲线移动速度
    var waterMoveSpeed: CGFloat = 0

    fileprivate let waterColor = UIColor(red: 118/255.0, green: 165/255.0, blue: 242/255.0, alpha: 0.6)
    fileprivate let BackGroundColor = UIColor(red: 80/255.0, green: 140/255.0, blue: 238/255.0, alpha: 1)
    //前面的波浪
    fileprivate let waterLayer1 = CAShapeLayer()
    fileprivate let waterLayer2 = CAShapeLayer()
    fileprivate var disPlayLink = CADisplayLink()
    
    //阳光
    var sunshinView = UIImageView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = BackGroundColor
        buildInterface()
        buildData()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func buildInterface(){
        //初始化波浪
        waterLayer1.fillColor = waterColor.cgColor
        waterLayer1.strokeColor = waterColor.cgColor
        waterLayer1.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        waterLayer2.fillColor = waterColor.cgColor
        waterLayer2.strokeColor = waterColor.cgColor
        waterLayer2.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        layer.addSublayer(waterLayer1)
        layer.addSublayer(waterLayer2)
        
        //阳光
        sunshinView = UIImageView(frame: CGRect(x: 200, y: -100, width: 200, height: 200))
        sunshinView.image = #imageLiteral(resourceName: "gx.png")
        addSubview(sunshinView)
        // 创建动画
        let anim = CABasicAnimation(keyPath: "transform.rotation")
        // 设置动画属性
        anim.toValue = 2 * Double.pi
        anim.repeatCount = MAXFLOAT
        anim.duration = 20
        anim.isRemovedOnCompletion = false
        // 将动画添加到图层上
        sunshinView.layer.add(anim, forKey: nil)
    }
    
    ///初始化数据
    func buildData(){
        waterPalstance = CGFloat(Double.pi) / bounds.size.width
        waterMoveSpeed = 5 * waterPalstance
        //以屏幕刷新速度为周期刷新曲线的位置
        disPlayLink = CADisplayLink(target: self, selector: #selector(self.updatewater(link:)))
        disPlayLink.add(to: RunLoop.main, forMode: .commonModes)
    }
    
    func updatewater(link: CADisplayLink){
        //更新x
        waterX += waterMoveSpeed
        updatewater(shapLayer: waterLayer1, isSin: false)
        updatewater(shapLayer: waterLayer2, isSin: true)
    }
    
    func updatewater(shapLayer: CAShapeLayer, isSin: Bool){
        //波浪宽度
        let waterwaterWidth = bounds.size.width
        //初始化运动路径
        let path = CGMutablePath()
        //设置起始位置
        path.move(to: CGPoint(x: 0, y: waterY))
        //初始化波浪,y为偏距
        var tempY = waterY
        //正弦曲线公式为: y=Asin(ωx+φ)+k
        for x in 0..<Int(waterwaterWidth){
            tempY = isSin ? waterAmplitude * sin(waterPalstance * CGFloat(x) + waterX) + waterY : waterAmplitude * cos(waterPalstance * CGFloat(x) + waterX) + waterY
            path.addLine(to: CGPoint(x: CGFloat(x), y: tempY))
        }
        //填充底部颜色
        path.addLine(to: CGPoint(x: waterwaterWidth, y: 200))
        path.addLine(to: CGPoint(x: 0, y: 200))
        path.closeSubpath()
        shapLayer.path = path
    }
    
}

3.用帧动画创建游动的鱼群FishView.swift

值得注意的是下面这部分代码当时遇到一点小坑


arc4random() % UInt32(x)中x必须大于1,而abs(frame.height - 35)之类的结果是有可能小于1的,所以需要做相应处理,不能直接arc4random() % UInt32(abs(frame.height - 35))

import UIKit

class FishView: UIView {
    
    var fishMaxNum = 5

    fileprivate var imageViewArray = [UIImageView]()
    fileprivate var timer: Timer!
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        for _ in 0..<fishMaxNum{
            let tempX = abs(frame.width - 60)
            let x = arc4random() % UInt32(tempX >= 1 ? tempX : 1)
            let tempY = abs(frame.height - 35)
            let y = arc4random() % UInt32(tempY >= 1 ? tempY : 1)
            let w = arc4random() % 50 + 10
            let h = arc4random() % 30 + 5
            let imageView = UIImageView(frame: CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(w), height: CGFloat(h)))
            addSubview(imageView)
            imageViewArray.append(imageView)
        }
        
        self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.timerAction(timer:)), userInfo: nil, repeats: true)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func timerAction(timer:Timer){
        let count = imageViewArray.count
        //随机要动的鱼数量
        let num = arc4random() % UInt32(count)
        for _ in 0..<num{
            //随机数组中哪几个动
            let num2 = arc4random() % UInt32(count)
            changeFrame(imageView: imageViewArray[Int(num2)])
        }
        
        timer.invalidate()
        self.timer = Timer.scheduledTimer(timeInterval: TimeInterval(arc4random() % 5 + 1), target: self, selector: #selector(self.timerAction(timer:)), userInfo: nil, repeats: true)
    }
    
    func changeFrame(imageView: UIImageView){
        let tempX = CGFloat(arc4random() % 100) - 50
        let tempY = CGFloat(arc4random() % 100) - 50
        let frameOr = imageView.frame.origin
        if tempX + frameOr.x > 0 && tempX + frameOr.x < frame.width - imageView.frame.width{
            imageView.stopAnimating()
            if tempX + frameOr.x > imageView.frame.origin.x{
                animation(isLeft: false, imageView: imageView)
            }else{
                animation(isLeft: true, imageView: imageView)
            }
            UIView.animate(withDuration: TimeInterval(arc4random() % 5 + 1), animations: {
                imageView.frame.origin.x += tempX
            })
        }
        if tempY + frameOr.y > 0 && tempY + frameOr.y < frame.height - imageView.frame.height{
            UIView.animate(withDuration: TimeInterval(arc4random() % 5 + 1), animations: {
                imageView.frame.origin.y += tempY
            })
        }
    }
    
    func animation(isLeft: Bool, imageView: UIImageView){
        imageView.animationImages = []
        for item in 0...9{
            let imageName = isLeft ? "fishl\(item).png" : "fish\(item).png"
            let image = UIImage(named: imageName)
            imageView.animationImages?.append(image!)
            
        }
        imageView.animationDuration = Double((arc4random() % 20) + 5) / 10.0
        imageView.startAnimating()
    }

}

使用


组合到上面的代码中需要将背景色改变成透明

4.气泡

气泡搬了个砖,然后稍作修改,代码是OC写的,如下
TBBubbleView.h

#import <UIKit/UIKit.h>

@interface TBBubbleView : UIView

@property (nonatomic, assign)CGFloat maxLeft;//漂浮左边最大距离
@property (nonatomic, assign)CGFloat maxRight;//漂浮右边最大距离
@property (nonatomic, assign)CGFloat maxHeight;//漂浮最高距离
@property (nonatomic, assign)CGFloat duration;//一组图片播放完的时间
@property (nonatomic, copy)NSArray *images;//图片数组


//init
-(instancetype)initWithFrame:(CGRect)frame
                folatMaxLeft:(CGFloat)maxLeft
               folatMaxRight:(CGFloat)maxRight
              folatMaxHeight:(CGFloat)maxHeight
                bubbleNum:(NSInteger)bubbleNum;

//开始动画
-(void)startBubble;

@end

TBBubbleView.m

#import "TBBubbleView.h"

@interface TBBubbleView()
@property(nonatomic,strong)NSTimer *timer;

@property(nonatomic,assign)CGFloat maxWidth;

@property(nonatomic,assign)CGPoint startPoint;

@property(nonatomic,strong) NSMutableArray *layerArray;

@property(nonatomic) NSUInteger bubbleNum;

@property(nonatomic) NSInteger tempNum;

@end


@implementation TBBubbleView


//初始化
-(instancetype)initWithFrame:(CGRect)frame folatMaxLeft:(CGFloat)maxLeft folatMaxRight:(CGFloat)maxRight folatMaxHeight:(CGFloat)maxHeight bubbleNum:(NSInteger)bubbleNum
{
    self = [super initWithFrame:frame];
    if(self)
    {
        _maxLeft = maxLeft;
        _maxRight = maxRight;
        _maxHeight = maxHeight;
        _layerArray = [NSMutableArray array];
        _bubbleNum = bubbleNum;
        _tempNum = 0;
    }
    return self;
}
//外部方法 开始气泡
-(void)startBubble
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(generateBubble) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop]addTimer:self.timer forMode:UITrackingRunLoopMode];
}

-(void)generateBubble
{
    if (_tempNum == _bubbleNum) {
        [self.timer invalidate];
        return;
    }
    CALayer *layer =[CALayer layer];;
    UIImage *image = self.images[arc4random() % self.images.count];
    
    layer = [self createLayerWithImage:image];
    [self.layer addSublayer:layer];
    [self generateBubbleByLayer:layer];
    _tempNum += 1;
}

//创建带有Image的Layer
- (CALayer *)createLayerWithImage:(UIImage *)image
{
    CGFloat scale = [UIScreen mainScreen].scale;
    CALayer *layer = [CALayer layer];
    layer.frame    = CGRectMake(0, 0, image.size.width / scale, image.size.height / scale);
    layer.contents = (__bridge id)image.CGImage;
    return layer;
}


-(void)generateBubbleByLayer:(CALayer*)layer
{
    _maxWidth = _maxLeft + _maxRight;
    _startPoint = CGPointMake(self.frame.size.width/2, 0);
    
    CGPoint endPoint = CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight);
    
    CGPoint controlPoint1 =
    CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight * 0.2);
    CGPoint controlPoint2 =
    CGPointMake(_maxWidth * [self randomFloat] - _maxLeft, -_maxHeight * 0.6);
    
    CGMutablePathRef curvedPath = CGPathCreateMutable();
    CGPathMoveToPoint(curvedPath, NULL, _startPoint.x, _startPoint.y);
    CGPathAddCurveToPoint(curvedPath, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
    UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:curvedPath];
    //[path addCurveToPoint:endPoint controlPoint1:_startPoint controlPoint2:controlPoint1];
    
    CAKeyframeAnimation *keyFrame = [CAKeyframeAnimation animation];
    keyFrame.keyPath = @"position";
    keyFrame.path = path.CGPath;
    keyFrame.duration = self.duration;
    keyFrame.calculationMode = kCAAnimationPaced;
    
    [layer addAnimation:keyFrame forKey:@"keyframe"];
    
    
    CABasicAnimation *scale = [CABasicAnimation animation];
    scale.keyPath = @"transform.scale";
    scale.toValue = @1;
    scale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 0.1)];
    scale.duration = 0.5;
    
    CABasicAnimation *alpha = [CABasicAnimation animation];
    alpha.keyPath = @"opacity";
    alpha.fromValue = @1;
    alpha.toValue = @0;
    alpha.duration = self.duration * 0.4;
    alpha.beginTime = self.duration - alpha.duration;
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[keyFrame, scale, alpha];
    group.duration = self.duration;
    group.delegate = self;
    group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    group.fillMode = kCAFillModeForwards;
    group.removedOnCompletion = NO;
    [layer addAnimation:group forKey:@"group"];
    
    [self.layerArray addObject:layer];
}
-(void)dealloc
{
    [self.layerArray removeAllObjects];
    [self.timer invalidate];
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (flag)
    {
        CALayer *layer = [self.layerArray firstObject];
        [layer removeAllAnimations];
        [layer removeFromSuperlayer];
        [self.layerArray removeObject:layer];
        if (self.layerArray.count == 0) {
            [self removeFromSuperview];
        }
    }
    
}
- (CGFloat)randomFloat{
    return (arc4random() % 100)/100.0f;
}

@end

使用

5.组合

组合后TBMyInfoTopView文件如下

import UIKit

class TBMyInfoTopView: UIView {
    
    //提供给外部调用接口
    
    ///曲线振幅
    var waterAmplitude: CGFloat = 8
    ///曲线角速度
    var waterPalstance: CGFloat = 0
    ///曲线初相
    var waterX: CGFloat = 0
    ///曲线偏距,越小距离顶端越近
    let waterY: CGFloat = 50
    ///曲线移动速度
    var waterMoveSpeed: CGFloat = 0

    fileprivate let waterColor = UIColor(red: 118/255.0, green: 165/255.0, blue: 242/255.0, alpha: 0.3)
    fileprivate let BackGroundColor = UIColor(red: 80/255.0, green: 140/255.0, blue: 238/255.0, alpha: 1)
    //前面的波浪
    fileprivate let waterLayer1 = CAShapeLayer()
    fileprivate let waterLayer2 = CAShapeLayer()
    fileprivate var disPlayLink = CADisplayLink()
    
    //阳光
    var sunshinView = UIImageView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = BackGroundColor
        buildInterface()
        buildData()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func buildInterface(){
        
        //珊瑚
        let shImageView = UIImageView(frame: CGRect(x: frame.width - 60, y: frame.height - 60, width: 60, height: 60))
        shImageView.image = #imageLiteral(resourceName: "shanhu.png")
        addSubview(shImageView)
        let scImageView = UIImageView(frame: CGRect(x: 150, y: frame.height - 40, width: 40, height: 40))
        scImageView.image = #imageLiteral(resourceName: "shuicao.png")
        addSubview(scImageView)
        
        sendSubview(toBack: scImageView)
        
        //初始化波浪
        waterLayer1.fillColor = waterColor.cgColor
        waterLayer1.strokeColor = waterColor.cgColor
        waterLayer1.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        waterLayer2.fillColor = waterColor.cgColor
        waterLayer2.strokeColor = waterColor.cgColor
        waterLayer2.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        layer.addSublayer(waterLayer1)
        layer.addSublayer(waterLayer2)
        
        //阳光
        sunshinView = UIImageView(frame: CGRect(x: 200, y: -100, width: 200, height: 200))
        sunshinView.image = #imageLiteral(resourceName: "gx.png")
        addSubview(sunshinView)
        // 创建动画
        let anim = CABasicAnimation(keyPath: "transform.rotation")
        // 设置动画属性
        anim.toValue = 2 * Double.pi
        anim.repeatCount = MAXFLOAT
        anim.duration = 20
        anim.isRemovedOnCompletion = false
        // 将动画添加到图层上
        sunshinView.layer.add(anim, forKey: nil)
        
        //鱼群
        let fishView = FishView(frame: CGRect(x: 0, y: waterY + 10, width: frame.width, height: frame.height - waterY - 10))
        fishView.backgroundColor = UIColor.clear
        insertSubview(fishView, belowSubview: shImageView)
        Timer.scheduledTimer(timeInterval: TimeInterval(arc4random() % 10 + 5), target: self, selector: #selector(self.showBubble(timer:)), userInfo: nil, repeats: false)
    }
    
    ///初始化数据
    func buildData(){
        waterPalstance = CGFloat(Double.pi) / bounds.size.width
        waterMoveSpeed = 5 * waterPalstance
        //以屏幕刷新速度为周期刷新曲线的位置
        disPlayLink = CADisplayLink(target: self, selector: #selector(self.updatewater(link:)))
        disPlayLink.add(to: RunLoop.main, forMode: .commonModes)
    }
    
    func updatewater(link: CADisplayLink){
        //更新x
        waterX += waterMoveSpeed
        updatewater(shapLayer: waterLayer1, isSin: false)
        updatewater(shapLayer: waterLayer2, isSin: true)
    }
    
    func updatewater(shapLayer: CAShapeLayer, isSin: Bool){
        //波浪宽度
        let waterwaterWidth = bounds.size.width
        //初始化运动路径
        let path = CGMutablePath()
        //设置起始位置
        path.move(to: CGPoint(x: 0, y: waterY))
        //初始化波浪,y为偏距
        var tempY = waterY
        //正弦曲线公式为: y=Asin(ωx+φ)+k
        for x in 0..<Int(waterwaterWidth){
            tempY = isSin ? waterAmplitude * sin(waterPalstance * CGFloat(x) + waterX) + waterY : waterAmplitude * cos(waterPalstance * CGFloat(x) + waterX) + waterY
            path.addLine(to: CGPoint(x: CGFloat(x), y: tempY))
        }
        //填充底部颜色
        path.addLine(to: CGPoint(x: waterwaterWidth, y: 200))
        path.addLine(to: CGPoint(x: 0, y: 200))
        path.closeSubpath()
        shapLayer.path = path
    }
    
    func showBubble(timer:Timer){
        
        //气泡数量
        let num = arc4random() % 5
        //x坐标
        let x = arc4random() % UInt32(frame.width)
        if let bubbleView = TBBubbleView(frame: CGRect(x: CGFloat(x), y: self.frame.height - 10, width: 0, height: 0), folatMaxLeft: 30, folatMaxRight: 30, folatMaxHeight: frame.height - waterY - 20, bubbleNum: Int(num)){
            insertSubview(bubbleView, at: 3)
            if let image = UIImage.init(named: "2"){
                bubbleView.images = [image]
            }
            bubbleView.duration = 4
            bubbleView.startBubble()
            
            timer.invalidate()
            Timer.scheduledTimer(timeInterval: TimeInterval(arc4random() % 10 + 5), target: self, selector: #selector(self.showBubble(timer:)), userInfo: nil, repeats: true)
        }
    }
    
}

Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 郑润远小朋友荣获淄博市 围棋赛少儿组第一名!
    张县明阅读 144评论 0 0
  • 夜明时分,闲来无事,遂一人闲庭信步,游于沙湖岸。心有所想,忽见天色骤变,不堪苦言。咦嘘唏,忽记起早年间曾读碟庵...
    可能会下雨阅读 232评论 0 0
  • 音乐,是一种旋律,打着节拍的律动!有人喜欢伤感、有人喜欢欢快、有人喜欢DJ!不管是什么音乐,不管什么流派,既然这首...
    Jimmy随笔阅读 1,231评论 2 2