ParallaxEffect

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

  1. @interface APAParallaxSprite : SKSpriteNode
  2.  
  3. @property (nonatomic) BOOL usesParallaxEffect;
  4. @property (nonatomic) CGFloat virtualZRotation;
  5.  
  6. /* If initialized with this method, sprite is set up for parallax effect; otherwise, no parallax. */
  7. - (id)initWithSprites:(NSArray *)sprites usingOffset:(CGFloat)offset;
  8.  
  9. - (void)updateOffset;
  10.  
  11. @end
  12.  
  13. @interface APAParallaxSprite ()
    // 指定顶部Node与底部Node最大偏移。
  14. @property (nonatomic) CGFloat parallaxOffset;
  15. @end
  16.  
  17. @implementation APAParallaxSprite
  18.  
  19. #pragma mark - Initialization
  20. - (id)initWithSprites:(NSArray *)sprites usingOffset:(CGFloat)offset {
  21. self = [super init];
  22.  
  23. if (self) {
  24. _usesParallaxEffect = YES;
  25.  
  26. // Make sure our z layering is correct for the stack.
  27. CGFloat zOffset = 1.0f / (CGFloat)[sprites count];
  28.  
  29. // All nodes in the stack are direct children, with ordered zPosition.
  30. CGFloat ourZPosition = self.zPosition;
  31. NSUInteger childNumber = ;
  32. for (SKNode *node in sprites) {
  33. node.zPosition = ourZPosition + (zOffset + (zOffset * childNumber));
  34. [self addChild:node];
  35. childNumber++;
  36. }
  37.  
  38. _parallaxOffset = offset;
  39. }
  40.  
  41. return self;
  42. }
  43.  
  44. #pragma mark - Copying
  45. - (id)copyWithZone:(NSZone *)zone {
  46. APAParallaxSprite *sprite = [super copyWithZone:zone];
  47. if (sprite) {
  48. sprite->_parallaxOffset = self.parallaxOffset;
  49. sprite->_usesParallaxEffect = self.usesParallaxEffect;
  50. }
  51. return sprite;
  52. }
  53.  
  54. #pragma mark - Rotation and Offsets
  55. - (void)setZRotation:(CGFloat)rotation {
  56. // Override to apply the zRotation just to the stack nodes, but only if the parallax effect is enabled.
  57. if (!self.usesParallaxEffect) {
  58. [super setZRotation:rotation];
  59. return;
  60. }
  61.  
  62. if (rotation > 0.0f) {
  63. self.zRotation = 0.0f; // never rotate the group node
  64.  
  65. // Instead, apply the desired rotation to each node in the stack.
  66. for (SKNode *child in self.children) {
  67. child.zRotation = rotation;
  68. }
  69.  
  70. self.virtualZRotation = rotation;
  71. }
  72. }
  73.  
  74. - (void)updateOffset {
  75. SKScene *scene = self.scene;
  76. SKNode *parent = self.parent;
  77.  
  78. if (!self.usesParallaxEffect || parent == nil) {
  79. return;
  80. }
  81.  
  82. CGPoint scenePos = [scene convertPoint:self.position fromNode:parent];
  83.  
  84. // Calculate the offset directions relative to the center of the screen.
  85. // Bias to (-0.5, 0.5) range.
  86. CGFloat offsetX = (-1.0f + (2.0 * (scenePos.x / scene.size.width)));
  87. CGFloat offsetY = (-1.0f + (2.0 * (scenePos.y / scene.size.height)));
  88.  
  89. CGFloat delta = self.parallaxOffset / (CGFloat)self.children.count;
  90.  
  91. int childNumber = ;
  92. for (SKNode *node in self.children) {
  93. node.position = CGPointMake(offsetX*delta*childNumber, offsetY*delta*childNumber);
  94. childNumber++;
  95. }
  96. }
  97.  
  98. @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. NTP服务器和国内可用的NTP地址

    NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备[如计算机.手机]的时间的协议. NTP 实现什么目的?   目的很简单,就是为了提供准确 ...

  2. AndroidManifest.xml activity属性设置大全

    1.android:allowTaskReparenting=["true"|"false"] 是否允许activity更换从属的任务,比如从短信息任务切换到浏 ...

  3. 服务升级带来的Bug,BAT也不能幸免

    这是标题党,关于阿里的,BT躺枪了. 为什么淘宝上找不到"亲淘"了? 好吧,我今天遇到了一个Bug: 立即更新,然后你看到了: 才发现亲淘不能使用了. 看官方页面: 提示:2016 ...

  4. Python标准库之time和datetime

    注:博客转载自:https://www.cnblogs.com/zhangxinqi/p/7687862.html 1.python3日期和时间 Python 程序能用很多方式处理日期和时间,转换日期 ...

  5. ul li 水平居中

    li的float:left方法显然有一个问题,就是无法居中(水平),只能使用padding-left或margin-right的方法方法来固定其居中.但这样可能在宽屏与窄屏的显示不一致.使用这种方法主 ...

  6. BZOJ4832: [Lydsy2017年4月月赛]抵制克苏恩

    传送门 题目大意: 攻击k次,每次可攻击随从或英雄. 随从数不大于7个,且1滴血的a个,2滴b个,3滴c个. 攻击一次血-1,如果随从没死可以生成3滴血随从一个 题解: 概率/期望dp f[i][j] ...

  7. 洛谷 P2920 [USACO08NOV]时间管理Time Management

    传送门 题目大意: 每个工作有截至时间和耗费时间,n个工作求最小开始时间. 题解: 贪心 从n-1安排,让结束时间尽量的晚. 注意:优先级 cout<<st<0?-1:st;  (X ...

  8. CODEVS1049 棋盘染色

    题目大意:01矩阵,1表示黑色,0表示白色,求将白色染成黑色最少的次数 使黑色成为一整个联通块. 题解: 搜索bfs 90... dfs判断连通 #include<iostream> #i ...

  9. 容器中跨主机的网络方案-Calico

    容器中的网络是建立docker集群的重要内容. 本文将介绍如何用Calico实现容器的多节点互通. Calico的组件结构如下: Calico通过etcd同步Bridge的信息,各个Docker no ...

  10. Jmeter录制HTTPS 补充

    Jmeter有录制功能,录制HTTPs需要增加一个证书配置,录制步骤如下: 1.打开jmeter,添加线程组.线程组右键,逻辑控制器>录制控制器 工作台 右键 非测试元件 >HTTP代理服 ...