前言

  简单实现弹幕功能,表跟我谈效率,但也有用队列控制同时弹的数量。

声明
  欢迎转载,但请保留文章原始出处:)
  博客园:http://www.cnblogs.com
  农民伯伯: http://over140.cnblogs.com

正文

    let DANMAKU_SPEED: CGFloat =     // 弹幕每秒移动速度
let DANMAKU_SPACE_TIME: NSTimeInterval = // 弹幕之间的时间间隔
let DANMAKU_MAX_ROW = // 最多同时弹幕行数
let danmakuFont = UIFont.systemFontOfSize() // 弹幕字体大小
var rowArray = Array<Array<Danmaku>>(count: , repeatedValue: Array<Danmaku>())
var danmakuQueue = NSOperationQueue() // 队列 class Danmaku : NSObject{
var msg: Msg
var view: UILabel?
var size = CGSize(width: , height: )
var row =
var startTime: NSDate?
var duration: NSTimeInterval =
var delay: NSTimeInterval = init(_ msg: Msg, _ row: Int, _ delay: NSTimeInterval = ) {
self.msg = msg
self.row = row
self.delay = delay
}
} func queueDanmaku(msg: Msg) {
danmakuQueue.addOperation(NSBlockOperation(block: { [weak self] in if let weakself = self {
repeat {
//检测放第几行
for var row = ; row < weakself.DANMAKU_MAX_ROW; ++row {
let rowDanmaku = weakself.rowArray[row]
if rowDanmaku.count == {
let danmaku = Danmaku(msg, weakself.danmakuFont, row)
weakself.rowArray[row].append(danmaku)
self?.performSelectorOnMainThread("sendDanmaku:", withObject: danmaku, waitUntilDone: true)
return
} else {
if let lastDanmaku = rowDanmaku.last {
if let startTime = lastDanmaku.startTime {
let now = NSDate()
let seconds = now.timeIntervalSinceDate(startTime)
let widthDuration = Double(lastDanmaku.size.width / weakself.DANMAKU_SPEED) var delay = seconds - weakself.DANMAKU_SPACE_TIME - widthDuration
if delay >= {
delay =
} else {
if lastDanmaku.delay > lastDanmaku.duration {
continue
}
} let danmaku = Danmaku(msg, weakself.danmakuFont, row, abs(delay) + lastDanmaku.delay)
weakself.rowArray[row].append(danmaku) self?.performSelectorOnMainThread("sendDanmaku:", withObject: danmaku, waitUntilDone: true)
return
}
}
}
} sleep()
} while self != nil
} }))
} func sendDanmaku(danmaku: Danmaku) {
let text = "\(danmaku.msg.user_name) : \(danmaku.msg.text)"
let size = NSString(string: text).sizeWithAttributes([NSFontAttributeName : danmakuFont])
let width = UIScreen.mainScreen().bounds.size.width
let top = + danmaku.row * (Int(size.height) + )
let label = UILabel(frame: CGRectMake(width, CGFloat(top), size.width, size.height))
let duration = (width + size.width) / DANMAKU_SPEED danmaku.view = label
danmaku.size = size
danmaku.startTime = NSDate()
danmaku.duration = NSTimeInterval(duration) label.text = text
label.font = danmakuFont
label.textColor = UIColor.whiteColor()
label.shadowColor = UIColor.blackColor()
label.shadowOffset = CGSizeMake(, -1.0) self.view.addSubview(label)
UIView.animateWithDuration(Double(duration), delay: danmaku.delay, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
label.left = -label.width
}) { [weak self] (Bool) -> Void in
if !(self?.rowArray[danmaku.row].isEmpty ?? true) {
self?.rowArray[danmaku.row].removeFirst()
}
label.removeFromSuperview()
}
}

    代码说明:

      代码控制了最多同时只能弹三行,每行最后一条如果延迟大于跑弹幕的时间(已经有一条处于完全等待状态)就自动切到下一行,超过最大限制就等待。

      *  rowArray 主要用于查询前一个弹幕的位置和时间

      *  别忘了在 deinit 里面加上 danmakuQueue.cancelAllOperations()

      *  注意 NSBlockOperation 的 block 并不在主线程上

最新文章

  1. Flex Layout Attribute
  2. 4412开发板学习笔记-NFS服务器的搭建
  3. 【JavaScript】之【Object】
  4. MVC - Action和ActionResult
  5. DelphiXE下的字符串变化
  6. JavaScript 事件——“事件类型”中“复合事件”和“变动事件”的注意要点(转)
  7. 自定义饼图(PieChart)各个PieSlice的外观
  8. python中的reduce(转)
  9. call_user_func_array
  10. 自定义类模板 重载&lt;&lt;遇到的问题
  11. Android特效--粒子效果之雨
  12. MinGW 使用 msvcr90.dll
  13. css控制父元素下的子元素自适应高度,且高度一致
  14. SQL to JSON Data Modeling with Hackolade
  15. 将表格导出为excel
  16. node.js 基础一 安装
  17. SQL Server 合并复制如何把备份的发布端或订阅端BAK文件还原为数据库
  18. [Swift实际操作]七、常见概念-(6)日期Date和DateFormatter日期的格式化
  19. hadoop2.x 异常
  20. hdu 4859 最小割

热门文章

  1. 通过3个Hello World应用来了解ASP.NET 5应用是如何运行的(2)
  2. Lua 学习笔记(八)错误(error)
  3. geotrellis使用(十三)数据导入BUG解决方案说明
  4. 记录一则数据库连接故障ORA-12560,ORA-12518
  5. 【LeetCode】Palindrome Pairs(336)
  6. 【十大经典数据挖掘算法】CART
  7. Moon.Orm版本维护及下载(跟踪报道)
  8. ASP.NET MVC动作过滤器
  9. asp.net WebService+Ajax调用
  10. jquery仿搜狐投票动画代码