iOS实现爆炸的粒子效果示例代码

照例我们先看看效果图

怎么样?效果很不错吧,下面来一起看看实现的过程和代码示例。

实现原理

从图中可以大致看出,爆炸点点都是取的某坐标的颜色值,然后根据一些动画效果来完成的。

取色值

怎么取的view的某个点的颜色值呢?google一下,就可以找到很多答案。就不具体说了。创建1*1的位图,然后渲染到屏幕上,然后得到RGBA。我这里写的是UIViewextension

extension UIView {

 public func colorOfPoint(point:CGPoint) -> UIColor
 {
  var pixel:[CUnsignedChar] = [0,0,0,0]

  let colorSpace = CGColorSpaceCreateDeviceRGB()
  let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)

  let context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, colorSpace, bitmapInfo.rawValue)

  CGContextTranslateCTM(context, -point.x, -point.y)

  self.layer.renderInContext(context!)

  let red: CGFloat = CGFloat(pixel[0]) / 255.0
  let green: CGFloat = CGFloat(pixel[1]) / 255.0
  let blue: CGFloat = CGFloat(pixel[2]) / 255.0
  let alpha: CGFloat = CGFloat(pixel[3]) / 255.0

  return UIColor(red:red, green: green, blue:blue, alpha:alpha)
 }
}

粒子的生成

这里我写的比较简单,就是固定每个粒子大小,根据View的宽高算出横向,纵向的粒子数,取该点的色值,设置粒子背景色,然后生成即可。

主要代码如下:

frameDict是我预先计算好的坐标表,colorDict是颜色表。以"i-j"为key

class func createExplosionPoints(containerLayer: ExplosionLayer, targetView: UIView, animationType: ExplosionAnimationType) {

  let hCount = self.caculatePointHCount(containerLayer.targetSize.width)
  let vCount = self.caculatePointVCount(containerLayer.targetSize.height)

  for i in 0..<hCount {
   for j in 0..<vCount {
    let key = String(format: "%d-%d", i, j)
    if let rect = containerLayer.frameDict[key], color = containerLayer.colorDict[key] {

     let layer = createExplosionPointLayer(rect, bgColor: color, targetViewSize: containerLayer.targetSize)

     // animation
     layer.explosionAnimation = self.createAnimationWithType(animationType, position: layer.position, targetViewSize: containerLayer.targetSize)

     containerLayer.addSublayer(layer)

     layer.beginAnimation()
    }
   }
  }
 }

动画效果

每个粒子都有一个CAAnimation动画,数据由调用者提供,灵活点。

这里定义了一个protocol:ExplosionAnimationProtocol ,可以自定义实现了该protocol的动画对象,提供动画效果。

protocol ExplosionAnimationProtocol {

 // 粒子初始位置
 var oldPosition: CGPoint { set get }

 // 粒子最终位置
 var newPosition: CGPoint { set get }

 // 缩放
 var scale: CGFloat { set get }

 // 动画时长
 var duration: CFTimeInterval { set get }

 // 动画重复次数
 var repeatCount: Float { set get }

 // 生成动画
 func animation() -> CAAnimation

 // 设置动画完之后的属性
 func resetLayerProperty(layer: CALayer)
}

要发生爆炸view的动画效果

这个比较简单,就是上下左右震动下。具体代码就不贴出来了。

let shakeAnimation = CAKeyframeAnimation(keyPath: "position")
...

代码结构

大致思路就是这样。代码结构如下:

ExplosionLayer是粒子的父容器,

ExplosionPointLayer是粒子本身

ExplosionHelper是个辅助类,用于计算粒子位置,颜色值。

FallAnimationUpAnimation是实现了ExplosionAnimationProtocol的动画,分别提供向下落,向上的效果。

碰到的问题

刚开始我是在边计算颜色值,边绘制粒子,发现会卡一下才会有爆炸效果出来,分析可能是在计算颜色值在主线程,时间较长,所以卡住了。

后来想到放到后台线程中去做,但是在主线程中取色值的时候,后台必须执行完,所以用了信号量来进行同步。

// 震动效果
private func shake() {

  self.createSemaphore()

  // 计算位置,色值
  self.caculate()

  let shakeAnimation = CAKeyframeAnimation(keyPath: "position")

  shakeAnimation.values = [NSValue.init(CGPoint: self.position), NSValue.init(CGPoint: CGPointMake(self.position.x, self.position.y + 1)), NSValue.init(CGPoint: CGPointMake(self.position.x + 1, self.position.y - 1)), NSValue.init(CGPoint: CGPointMake(self.position.x - 1, self.position.y + 1))]

  shakeAnimation.duration = 0.2
  shakeAnimation.repeatCount = 15
  shakeAnimation.delegate = self
  shakeAnimation.removedOnCompletion = true

  self.targetView?.layer.addAnimation(shakeAnimation, forKey: "shake")
 }

当要爆炸的view开始震动时,就开始在后台计算。震动动画结束后,等待计算完成。

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {

  // wait for caculate
  dispatch_semaphore_wait(self.semaphore!, DISPATCH_TIME_FOREVER)

  print("shake animation stop")

  // begin explode
  if let targetView = self.targetView {
   self.parentLayer?.addSublayer(self)
   ExplosionHelper.createExplosionPoints(self, targetView: targetView, animationType: self.animationType)

   self.targetView?.hidden = true
  }
 }

在后续的创建粒子时,就直接从缓存中取就行了。

总结

好了,以上就是iOS实现爆炸效果的全部内容了,实现后的效果是不是非常的炫酷?感兴趣的朋友们快快实践起来吧,只有自己操作了才能真正的理解,希望这篇文章对大家的学习或者工作能带来一定的帮助。

(0)

相关推荐

  • IOS 粒子系统 (CAEmitterLayer)实例详解

    一.系统剖析 在UIKit中,粒子系统由两部分组成: ·      一个或多个CAEmitterCells:发射器电池可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾).当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子.此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期. ·      一个或多个CAEmitterLayers,但通常只有一个:这个发射的层主要控制粒子的形状(例如,一个点,矩形或圆形)和发射的位置(例如,在矩形内,或边缘).

  • iOS CAEmitterLayer实现粒子发射动画效果

    iOS实现粒子发射动画效果图 代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo 动画效果用 CAEmitterLayer 实现.CAEmitterLayer 显示粒子发射动画,具体的粒子由 CAEmitterCell 封装.代码示例是展示 CAEmitterLayer 如何使用.为了方便,直接在控制器(UIViewController)中设置 CAEmitterLayer.如果在项目中使用,有时在自定义视图(UIVi

  • iOS中利用CAEmitterLayer实现粒子动画详解

    前言 你肯定见过很酷炫的iOS动画吧,例如微信的表情雨

  • iOS使用核心动画和粒子发射器实现点赞按钮的方法

    首先放上效果图,大家可以看一下 实现的方法如下 一.使用到的类 CAKeyframeAnimation       // 核心动画-关键帧动画 CAEmitterLayer            // 粒子发射器(其实就是一个Layer,其父类是CALayer) CAEmitterCell             // 粒子 PS:核心动画应该不用多说了; CAEmitterLayer和CAEmitterCell,其实可以比喻成"炮"和"炮弹",应该不难理解; 二.

  • iOS实现爆炸的粒子效果示例代码

    照例我们先看看效果图 怎么样?效果很不错吧,下面来一起看看实现的过程和代码示例. 实现原理 从图中可以大致看出,爆炸点点都是取的某坐标的颜色值,然后根据一些动画效果来完成的. 取色值 怎么取的view的某个点的颜色值呢?google一下,就可以找到很多答案.就不具体说了.创建1*1的位图,然后渲染到屏幕上,然后得到RGBA.我这里写的是UIView的extension. extension UIView { public func colorOfPoint(point:CGPoint) -> U

  • jQuery 动态粒子效果示例代码

    1.js部分 var RENDERER = { PARTICLE_COUNT : 1000, PARTICLE_RADIUS : 1, MAX_ROTATION_ANGLE : Math.PI / 60, TRANSLATION_COUNT : 500, init : function(strategy){ this.setParameters(strategy); this.createParticles(); this.setupFigure(); this.reconstructMetho

  • iOS 对view进行截图的示例代码

    本文主要介绍了iOS 对view进行截图的示例代码,分享给大家,具体如下: 需要对WKWebView进行截图,之前用的是下面的方法,高版本的系统是没有问题的,低版本的却截到一张白图 - (UIImage *)convertViewToImage:(UIView *)view{ // 第二个参数表示是否非透明.如果需要显示半透明效果,需传NO,否则YES.第三个参数就是屏幕密度了 UIGraphicsBeginImageContextWithOptions(CGSizeMake(view.boun

  • Flutter 实现酷炫的3D效果示例代码

    此文讲解3个酷炫的3D动画效果. 下面是要实现的效果: Flutter 中3D效果是通过 Transform 组件实现的,没有变换效果的实现: class TransformDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('3D 变换Demo'), ), body: Container( alignm

  • Android开发TextvView实现镂空字体效果示例代码

    记录一下... 自定义TextView public class HollowTextView extends AppCompatTextView { private Paint mTextPaint, mBackgroundPaint; private Bitmap mBackgroundBitmap,mTextBitmap; private Canvas mBackgroundCanvas,mTextCanvas; private RectF mBackgroundRect; private

  • Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的错位感,代码很简单: import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.MotionEvent import android.vi

  • Vue中实现过渡动画效果示例代码

    目录 Vue的transition动画 Transition动画的使用 Transition组件的原理 Transition动画的class Vue的animation动画 Animation动画的使用 同时设置两种动画(了解) 过渡的模式mode 列表过渡 列表过渡的介绍 列表过渡的使用 Vue的transition动画 Transition动画的使用 在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,可以很好的增加用户体验: React框架本身并没有提供任何动画相关的API,所以在R

  • iOS如何为圆角添加阴影效果示例代码

    前言 大家都知道在iOS中为UIView添加阴影还是比较简单的,只需要设置layer的shadow属性就可以了,但是问题在于设置阴影之后,必须设置masksToBounds为NO,而圆角图片则要求masksToBounds必须为YES,两者相互冲突,会导致无法正确的添加阴影.下面就来给大家介绍正确为圆角添加阴影的效果,话不多说了,来一起看看详细的介绍吧. 先来看看效果图: 正确的做法: 先创建一个透明的UIView,并添加阴影,设置masksToBounds为NO: 然后在透明的UIView上添

  • IOS设置按钮为圆角的示例代码

    iOS中很多时候都需要用到指定风格的圆角按钮,以下是UIButton提供的创建圆角按钮方法 设置按钮的4个角: 左上:UIRectCornerTopLeft 左下:UIRectCornerBottomLeft 右上:UIRectCornerTopRight 右下:UIRectCornerBottomRight 示例代码: UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(50, 60, 80, 40)]; button.b

  • iOS中使用对象的弱引用示例代码

    简介 我们都知道使用 UIImage imageNamed 创建的 UIImage 对象会被持有(强引用),如果图片太大会占用内存,损耗 APP 的性能,影响用户体验,如果能改造对其的强引用变为弱引用就可以解决问题. 我们可能会有类似上面的场景,有些对象暂时保存起来,可能后面会用到,也有可能不会使用,但是又不想去管理它们的生命周期,如果它们能够自己被销毁就很省事,不需要去关心这些对象到底耗费了多少内存. 今天跟大家聊聊如何在 iOS 开发中保持对对象的弱引用而不是强引用,希望看完之后,能帮助到大

随机推荐