zoukankan      html  css  js  c++  java
  • ParallaxEffect

    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 = 0; 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 = 0; for (SKNode *node in self.children) { node.position = CGPointMake(offsetX*delta*childNumber, offsetY*delta*childNumber); childNumber++; } } @end

      核心算法在udpate方法中。

  • 相关阅读:
    C#进程操作(使用cmd启动和停止.exe)
    NCHW 与NHWC 的区别
    对于openeuler x_86_64,openeuler aarch_64的安装以及yum换源
    读西瓜书笔记
    修改SpringBoot启动Logo
    SpringBoot集成Redis
    SpringBoot集成Dubbo
    那些Java架构师必知必会的技术
    CompletableFuture 入门学习
    使用 VirtualBox+Vagrant 快速搭建 Linux 虚拟机环境
  • 原文地址:https://www.cnblogs.com/tekkaman/p/3667055.html
Copyright © 2011-2022 走看看