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方法中。

最新文章

  1. .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点
  2. unity3d中获得物体的size
  3. TODO:小程序开发环境搭建
  4. [译]SQL Server分析服务的权限配置
  5. ios 随记录
  6. Windows 95 vs. Windows 10
  7. iOS 学习资料整理
  8. M2的来源很简单
  9. root 授权
  10. 关于VIM在Win10下的无意义折腾
  11. win7开启远程桌面
  12. HDU 4358 Boring counting 树状数组+思路
  13. ios9下ionic框架报[$rootScope:infdig] 10 $digest() iterations reached. Aborting!的解决办法
  14. Java网络编程(TCP协议-练习-上传文本文件)
  15. Ntop监控网络流量
  16. [置顶] 程序员必知(二):位图(bitmap)
  17. 最简单的 RabbitMQ 监控方法 - 每天5分钟玩转 OpenStack(158)
  18. Python——Django-__init__.py的内容
  19. 免费的DDos网络测试工具集合
  20. Python关于Pyqt

热门文章

  1. [置顶] C语言学习入门
  2. pg_buffercache
  3. vim 插件使用
  4. 没有绝对的cc.ResolutionPolicy.FIXED_WIDTH或cc.ResolutionPolicy.FIXED_HEIGHT
  5. MySql必知必会实战练习(二)数据检索
  6. sizeof与strlen()、递归优化题解
  7. angular中的 input select 值绑定无效,以及多出一个空白选项问题
  8. Java 引用类型变量的声明和使用
  9. STM32从boot跳转到app失败
  10. 【openCV学习笔记】【1】如何载入一张图片