基于下面的图像(我使用不同颜色的圆和平面,所以他们可以看到,但最终颜色将是相同的),使用Swift和Spritekit,我试图创建一个圆形对象进入的效果厚物质(不一定是粘性的)并与厚物质分离.基本上,当圆形物体分离时,它会在形成圆形时从平坦表面拉开.我想使用图像动画帧,但由于对象是具有物理主体的SKSpriteNodes,因此这将使得对象与动画的碰撞非常困难.另一种方法是使用CAAnimation,但我不知道如何将这与SKSpriteNodes与物理实体结合起来.如何使用上述任何方法或不同方法创建此分离效果?
UPDATE
下图显示了当圆形物体进入厚物质直至其浸没时,厚物质表面的变化.
我有一个基于文档的应用程序,其中每个文档都有一个带有NSScrollView的窗口,它只使用Cocoa进行一些(相当连续的)绘图.
要调用绘图,我使用的是CVDisplayLink,如下面的代码所示:
- (void)windowControllerDidLoadNib:(NSWindowController *) aController {
//other stuff...
[self prepareDisplayLink]; //For some reason putting this in awakeFromNib crashes
}
//Prep the display link.
- (void)prepareDisplayLink {
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetCurrentCGDisplay(displayLink, ((CGDirectDisplayID)[[[[[self windowForSheet]screen]deviceDescription]objectForKey:@"NSScreenNumber"]intValue]));
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
}
//Callback to draw frame
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc]init];
CVReturn result = [(ScrollView*)displayLinkContext getFrameForTime:outputTime];
[pool drain];
return result;
}
//Drawing function:
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
[scrollView lockFocusIfCanDraw];
[self addToCurrentPostion:(dist/time)*CVDisplayLinkGetActualOutputVideoRefreshPeriod(displayLink)]; …
Run Code Online (Sandbox Code Playgroud) 我需要将UIWebView的CALayers镜像到较小的CALayer.较小的CALayer本质上是较大的UIWebView的一部分.我很难做到这一点.唯一接近的是CAReplicatorLayer,但鉴于原始版本和副本必须将CAReplicatorLayer作为父级,我无法在不同的屏幕上拆分原件和副本.
我正在尝试做的一个例子:
用户需要能够与较小的CALayer进行交互,并且两者都需要同步.
我尝试过使用renderInContext和CADisplayLink.不幸的是,有一些滞后/口吃,因为它试图重新绘制每一帧,每秒60次.我需要一种方法来进行镜像而无需在每个帧上重新绘制,除非实际发生了某些变化.所以我需要一种方法来了解CALayer(或儿童CALayers)何时变脏.
我不能简单地拥有两个UIWebView,因为两个页面可能不同(时间关闭,背景不同等等).我无法控制正在显示的网页.我也无法显示整个iPad屏幕,因为屏幕上还有其他元素不应显示在外部屏幕上.
较大的CALayer和较小的"pip"CALayer都需要在iOS 6中逐帧匹配.我不需要支持早期版本.
解决方案需要应用程序存储可通过.
考虑使用这个简单的同步动画CADisplayLink
,
var link:CADisplayLink?
var startTime:Double = 0.0
let animTime:Double = 0.2
let animMaxVal:CGFloat = 0.4
private func yourAnim()
{
if ( link != nil )
{
link!.paused = true
//A:
link!.removeFromRunLoop(
NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
link = nil
}
link = CADisplayLink(target: self, selector: #selector(doorStep) )
startTime = CACurrentMediaTime()
link!.addToRunLoop(
NSRunLoop.currentRunLoop(), forMode:NSDefaultRunLoopMode)
}
func doorStep()
{
let elapsed = CACurrentMediaTime() - startTime
var ping = elapsed
if (elapsed > (animTime / 2.0)) {ping = animTime - elapsed}
let frac = …
Run Code Online (Sandbox Code Playgroud) 我有一个项目,我根据设定的进度动画UIBezierPath.BezierPath呈圆形,位于UIView中,动画现在使用CADisplayLink在drawRect中完成.简单地说,根据设定的进度x
,路径应径向延伸(如果x
比之前大)或收缩(如果x
更小).
self.drawProgress = (self.displayLink.timestamp - self.startTime)/DURATION;
CGFloat startAngle = -(float)M_PI_2;
CGFloat stopAngle = ((self.x * 2*(float)M_PI) + startAngle);
CGFloat currentEndAngle = ((self.oldX * 2*(float)M_PI) + startAngle);
CGFloat endAngle = currentEndAngle-((currentEndAngle-stopAngle)*drawProgress);
UIBezierPath *guideCirclePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
Run Code Online (Sandbox Code Playgroud)
这是x
自我们上次更新以来收缩的情况.我遇到的问题实际上是一些:
startAngle
为-45º没有任何区别,因为它总是"弹出"到45.我有什么可以做的,或者我是否必须采用其他绘图方法?CAShapeLayer
但我还没有完全理解使用这两种方法的实际差异(在缺点和好处方面).如果有人能澄清我会非常感激!更新:我将代码迁移到CAShapeLayer,但现在我面临着另一个问题.最好用这张图片描述:
发生的事情是,当层应该收缩时,薄的外线仍然存在(无论移动方向如何).当棒收缩时,x
除非我明确地在其上形成新的白色形状,否则不会除去1-的Δ .这个代码如下.有任何想法吗?
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:stopAngle clockwise:YES];
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [circlePath CGPath]; …
Run Code Online (Sandbox Code Playgroud) 我有一个CAEAGLLayer支持的视图,它位于UIScrollView中.当我开始滚动时,调用openGL视图的-draw方法的CADisplayLink停止被调用.
我确认滚动时不会调用我的runloop启动/停止方法.一旦滚动开始,-draw方法就不会被调用,并且一旦滚动结束就恢复调用.
滚动开始后,UIKit是否会停止触发CADisplayLink?
显示链接被添加到运行循环中,如下所示:
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Run Code Online (Sandbox Code Playgroud)
也许这个运行循环模式和UIScrollView存在冲突?是否存在其他运行循环模式或替代解决方案,即使在UIScrollView滚动时也能保持CADisplayLink触发?
我认为在任何应用程序中都不只有一个CADisplayLink.那是错的吗?
我发现了CADisplayLink的一个大问题.
我有最基本的EAGLLayer与OpenGL ES 1.1绘制旋转三角形进行测试.这需要以屏幕刷新率调用运行循环方法,所以我像这样启动runloop:
- (void)startRunloop {
if (!animating) {
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
[dl setFrameInterval:1.0];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = dl;
animating = YES;
}
}
- (void)stopRunloop {
if (animating) {
[self.displayLink invalidate];
self.displayLink = nil;
animating = NO;
}
}
Run Code Online (Sandbox Code Playgroud)
当测试应用程序启动时,我调用-startRunloop.当我点击屏幕时,我调用-stopRunloop.当我再次点击时,我调用-startRunloop.等等.乒乓.
我正在测量在20秒内调用-drawFrame方法的频率,以及NSLog它.
FIRST启动/停止循环始终执行100%.我得到了最大帧速率.
所有SUBSEQUENT启动/停止循环仅显示约80%的性能.我的帧速率要小得多.但是:总是几乎完全相同,+/ - 2帧.即使经过50次启动/停止循环后也没有进一步降级的倾向.
总结:像我上面那样创建CADisplayLink是好的,直到它失效或暂停.之后,任何新的CADisplayLink都不再表现良好.即使它是以与以前完全相同的方式创建的.如果我通过使用YES/NO调用-setPaused:方法暂停/恢复它也是如此.
我已经确定Allocations和VM Tracker Instruments没有内存管理问题.我还检查过CADisplayLink的-invalidate方法是否真的被调用了.
设备上的iOS 4.0(iPhone 4).
这是为什么?我错过了什么吗?
我有一个CADisplayLink触发draw
Director对象中的方法.我想使CADisplayLink无效,然后取消分配Director对象使用的一些单独的Cache对象.draw
方法不保留单例Cache对象.
在stopAnimation
Director中调用的方法(此方法与方法无关draw
),我做:
[displayLink invalidate];
Run Code Online (Sandbox Code Playgroud)
然后我开始发布单例Cache对象,但随后启动了CADisplayLink,draw
最后一次调用该方法.这些draw
方法试图访问解除分配的单例对象,一切都崩溃了.
这种情况有时只会发生:有时候应用程序不会崩溃,因为在displayLink实际失效并且draw方法已经完成运行后释放了Cache对象.
在使displayLink无效之后,我如何检查draw方法是否已经完成运行并且它不会再次触发,以便安全地使Cache对象无效?draw
如果可能,我不想修改方法.
我尝试了很多组合,包括displayLink invalidate
在主线程上执行使用
[self performSelectorOnMainThread:@selector(stopAnimation) withObject:self waitUntilDone:YES]
或尝试使用在currentRunLoop中执行它
[[NSRunLoop currentRunLoop] performSelector:@selector(stopAnimation) target:self argument:nil order:10 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
但结果总是一样的,有时它会过早地释放共享的Caches.
我也不想使用performSelector:withObject:afterDelay:
任意延迟的方法.我想确保displayLink无效,draw方法结束,并且不会再次运行.
我需要更新每帧我的动画,在iOS上我CADisplayLink
,对我WinPhone有CompositionTarget
,但我要如何做到这一点在Android?
目前我使用的是Timer
旁边一个Handler
,但我相信有一种方法来同步与刷新率回调.
我有一个使用NSTimer以厘秒(0.01秒)更新间隔的应用程序,以字符串格式显示运行秒表为00:00.00(mm:ss.SS).(基本上克隆iOS内置秒表以集成到实时运动计时数学问题中,将来可能需要毫秒精度)
我使用(误用?)NSTimer来强制更新UILabel.如果用户按下Start,这是用于开始重复该功能的NSTimer代码:
displayOnlyTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("display"), userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)
这是由上面的NSTimer执行的函数:
func display() {
let currentTime = CACurrentMediaTime() - timerStarted + elapsedTime
if currentTime < 60 {
timeDisplay.text = String(format: "%.2f", currentTime)
}else if currentTime < 3600 {
var minutes = String(format: "%00d", Int(currentTime/60))
var seconds = String(format: "%05.2f", currentTime % 60)
timeDisplay.text = minutes + ":" + seconds
}else {
var hours = String(format: "%00d", Int(currentTime/3600))
var minutes = String(format: "%02d", (Int(currentTime/60)-(Int(currentTime/3600)*60)))
var seconds = String(format: …
Run Code Online (Sandbox Code Playgroud) cadisplaylink ×10
ios ×5
swift ×3
android ×1
animation ×1
caeagllayer ×1
calayer ×1
cocoa ×1
core-video ×1
iphone ×1
nstimer ×1
nsview ×1
objective-c ×1
opengl-es ×1
performance ×1
screen ×1
sprite-kit ×1
stopwatch ×1
time-format ×1
uibezierpath ×1
uikit ×1
uiwebview ×1