ParallaxEffect
2024-08-26 22:04:07
【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方法中。
最新文章
- .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点
- unity3d中获得物体的size
- TODO:小程序开发环境搭建
- [译]SQL Server分析服务的权限配置
- ios 随记录
- Windows 95 vs. Windows 10
- iOS 学习资料整理
- M2的来源很简单
- root 授权
- 关于VIM在Win10下的无意义折腾
- win7开启远程桌面
- HDU 4358 Boring counting 树状数组+思路
- ios9下ionic框架报[$rootScope:infdig] 10 $digest() iterations reached. Aborting!的解决办法
- Java网络编程(TCP协议-练习-上传文本文件)
- Ntop监控网络流量
- [置顶] 程序员必知(二):位图(bitmap)
- 最简单的 RabbitMQ 监控方法 - 每天5分钟玩转 OpenStack(158)
- Python——Django-__init__.py的内容
- 免费的DDos网络测试工具集合
- Python关于Pyqt
热门文章
- [置顶]
 C语言学习入门
- pg_buffercache
- vim 插件使用
- 没有绝对的cc.ResolutionPolicy.FIXED_WIDTH或cc.ResolutionPolicy.FIXED_HEIGHT
- MySql必知必会实战练习(二)数据检索
- sizeof与strlen()、递归优化题解
- angular中的 input select 值绑定无效,以及多出一个空白选项问题
- Java 引用类型变量的声明和使用
- STM32从boot跳转到app失败
- 【openCV学习笔记】【1】如何载入一张图片