ParallaxEffect

  ParallaxEffect是一种用简单的2D贴图来模拟3D效果的简易方法。譬如一棵树,摄像机俯视时,当树远离摄像机时,树顶偏远,当树靠近,树顶偏近。苹果官方Adventure中展示了此种技术。

@interface APAParallaxSprite : SKSpriteNode

@property (nonatomic) BOOL usesParallaxEffect;
@property (nonatomic) CGFloat virtualZRotation; /* If initialized with this method, sprite is set up for parallax effect; otherwise, no parallax. */
- (id)initWithSprites:(NSArray *)sprites usingOffset:(CGFloat)offset; - (void)updateOffset; @end @interface APAParallaxSprite ()
// 指定顶部Node与底部Node最大偏移。
@property (nonatomic) CGFloat parallaxOffset;
@end @implementation APAParallaxSprite #pragma mark - Initialization
- (id)initWithSprites:(NSArray *)sprites usingOffset:(CGFloat)offset {
self = [super init]; if (self) {
_usesParallaxEffect = YES; // Make sure our z layering is correct for the stack.
CGFloat zOffset = 1.0f / (CGFloat)[sprites count]; // All nodes in the stack are direct children, with ordered zPosition.
CGFloat ourZPosition = self.zPosition;
NSUInteger childNumber = ;
for (SKNode *node in sprites) {
node.zPosition = ourZPosition + (zOffset + (zOffset * childNumber));
[self addChild:node];
childNumber++;
} _parallaxOffset = offset;
} return self;
} #pragma mark - Copying
- (id)copyWithZone:(NSZone *)zone {
APAParallaxSprite *sprite = [super copyWithZone:zone];
if (sprite) {
sprite->_parallaxOffset = self.parallaxOffset;
sprite->_usesParallaxEffect = self.usesParallaxEffect;
}
return sprite;
} #pragma mark - Rotation and Offsets
- (void)setZRotation:(CGFloat)rotation {
// Override to apply the zRotation just to the stack nodes, but only if the parallax effect is enabled.
if (!self.usesParallaxEffect) {
[super setZRotation:rotation];
return;
} if (rotation > 0.0f) {
self.zRotation = 0.0f; // never rotate the group node // Instead, apply the desired rotation to each node in the stack.
for (SKNode *child in self.children) {
child.zRotation = rotation;
} self.virtualZRotation = rotation;
}
} - (void)updateOffset {
SKScene *scene = self.scene;
SKNode *parent = self.parent; if (!self.usesParallaxEffect || parent == nil) {
return;
} CGPoint scenePos = [scene convertPoint:self.position fromNode:parent]; // Calculate the offset directions relative to the center of the screen.
// Bias to (-0.5, 0.5) range.
CGFloat offsetX = (-1.0f + (2.0 * (scenePos.x / scene.size.width)));
CGFloat offsetY = (-1.0f + (2.0 * (scenePos.y / scene.size.height))); CGFloat delta = self.parallaxOffset / (CGFloat)self.children.count; int childNumber = ;
for (SKNode *node in self.children) {
node.position = CGPointMake(offsetX*delta*childNumber, offsetY*delta*childNumber);
childNumber++;
}
} @end

  核心算法在udpate方法中。

ParallaxEffect的更多相关文章

  1. 视差滚动(Parallax Scrolling)效果的原理与实现

    视差滚动(Parallax Scrolling)效果的原理与实现1.视差滚动效果的主要特点:    1)直观的设计,快速的响应速度,更合适运用于单页面    2)差异滚动 分层视差    页面上很多的 ...

  2. leaflet地图库

    an open-source JavaScript libraryfor mobile-friendly interactive maps Overview Tutorials Docs Downlo ...

  3. [Android Pro] AndroidX重构和映射

    原文地址:https://developer.android.com/topic/libraries/support-library/refactor https://blog.csdn.net/ch ...

  4. iOS7向开发者开放的新功能汇总

    转自:http://www.25pp.com/news/news_28002.html iOS7才放出第二个测试版本,我们已经看到了不少的新功能和新改变.最近,科技博客9to5Mac将iOS7中向开发 ...

随机推荐

  1. C# 中字段和属性的使用时机

    在C#中,我们可以非常自由的.毫无限制的访问公有字段,但在一些场合中,我们可能希望限制只能给字段赋于某个范围的值.或是要求字段只能读或只能写,或是在改变字段时能改变对象的其他一些状态,这些单靠字段是无 ...

  2. mysql的5.6版本支持分区吗?

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/72291698 本文出自[我是干勾鱼的博客] 我们知道,查看mysql是否支持分区 ...

  3. ng 过滤器

    1.ng中自带的过滤器过滤器:实现对数据的筛选.过滤.格式化. 过滤器是一个有返回值的方法. 过滤器语法:{{ expression |过滤器1:'参数' | 过滤器2:'参数' }} | --> ...

  4. Precision/Recall、ROC/AUC、AP/MAP等概念区分

    1. Precision和Recall Precision,准确率/查准率.Recall,召回率/查全率.这两个指标分别以两个角度衡量分类系统的准确率. 例如,有一个池塘,里面共有1000条鱼,含10 ...

  5. (转) Myisam和Innodb索引实现的不同(存储结构)

    转自 :  https://blog.csdn.net/donghaixiaolongwang/article/details/60751543

  6. 查看 nginx 的并发连接数

    通过查看Nginx的并发连接,我们可以更清除的知道网站的负载情况.Nginx并发查看有两种方法(之所以这么说,是因为笔者只知道两种),一种是通过web界面,一种是通过命令,web查看要比命令查看显示的 ...

  7. Java中数据库连接池原理机制的详细讲解(转)

    连接池的基本工作原理 1.基本概念及原理 由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理.我们知道,对于共享资源,有一个很著名的设计模式:资源池 (Resource Pool).该模 ...

  8. SSH项目配置数据源的方法(jndi)

    1.在tomcat6.0/conf/context.xml加入以下代码 [xhtml] view plain copy     <Resource name="jdbc/oracleD ...

  9. verilog中task的用法

    任务就是一段封装在“task-endtask”之间的程序.任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的.调用某个任务时可能需要 ...

  10. DispatcherServlet的处理流程

    前言 上一篇介绍了SpringMVC的启动过程,DispatcherServlet作为一个前端控制器,分发处理http请求 1.DispatcherServlet流程图 具体流程: 1. 用户发请求- ...