- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章IOS 实现简单的弹幕功能由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
简单实现弹幕功能,表跟我谈效率,但也有用队列控制同时弹的数量.
正文 。
代码实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
let DANMAKU_SPEED: CGFloat = 150
// 弹幕每秒移动速度
let DANMAKU_SPACE_TIME: NSTimeInterval = 1
// 弹幕之间的时间间隔
let DANMAKU_MAX_ROW = 3
// 最多同时弹幕行数
let danmakuFont = UIFont.systemFontOfSize(18)
// 弹幕字体大小
var rowArray = Array<Array<Danmaku>>(count: 3, repeatedValue: Array<Danmaku>())
var danmakuQueue = NSOperationQueue()
// 队列
class
Danmaku : NSObject{
var msg: Msg
var view: UILabel?
var size = CGSize(width: 0, height: 0)
var row = 0
var startTime: NSDate?
var duration: NSTimeInterval = 0
var delay: NSTimeInterval = 0
init(_ msg: Msg, _ row: Int, _ delay: NSTimeInterval = 0) {
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 = 0; row < weakself.DANMAKU_MAX_ROW; ++row {
let rowDanmaku = weakself.rowArray[row]
if
rowDanmaku.count == 0 {
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 >= 0 {
delay = 0
}
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(1000)
}
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 = 54 + danmaku.row * (Int(size.height) + 10)
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(0, -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 并不在主线程上 。
以上就是对IOS开发 简单的弹幕功能的实现代码,有需要开发这种功能的朋友可以参考下.
最后此篇关于IOS 实现简单的弹幕功能的文章就讲到这里了,如果你想了解更多关于IOS 实现简单的弹幕功能的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!