花了一整天的时间。我在iOS文档中或在SO上找不到这个。
我有一个SKShapeNode*
,就像我的应用中的一个窗口,我添加了一个SKSpriteNode
的背景,背景中有另外10个SKSpriteNode
作为其子项。所以节点树是这样的:
SKScene -> window -> background -> (child1, ..., child10)
尺寸使得背景与窗口的大小相匹配,并且所有背景的孩子都适合背景。
我想在窗口内点击时进行缩放(让背景和10个孩子全部放大)。我通过设置背景的xScale& amp;来实现这一点。 yScale,孩子们继承这种缩放。但我也不想溢出窗外的边界,所以我制作了一个SKCropNode,并添加了背景作为它的孩子。现在背景没有溢出:
SKScene -> window -> SKCropNode -> background -> (child1, ..., child10)
问题是,当放大时,背景的孩子会溢出。这对我来说是违反直觉的。我尝试在网上搜索并查看文档," SKCropNode是否会裁剪其子女&所有后代"?由于答案似乎不是,我想把所有10个孩子的父母从背景改为SKCropNode:
SKScene -> window -> SKCropNode -> (background, child1, ..., child10)
现在我缩放SKCropNode。这会缩放背景和所有孩子,但现在它再次溢出窗外。 (在游戏的后期,孩子的数量可能会从10个增加到300个,而且我不想在300个项目上进行for循环。所以我希望能够只在一个父级上设置比例。)< / p>
我终于决定尝试一下&#34; hacky&#34;。这我在网上找不到任何地方,所以我想知道我是否在&#34;未定义的行为&#34;境。
SKScene -> window -> SKCropNode1 -> SKCropNode2 -> (background, child1, ..., child10)
我在原始SKCropNode之上添加了另一个SKCropNode。现在,我只缩放SKCropNode2。这有效。但是,现在我的行为非常奇怪。我的SKShapeNode按钮(完全在窗外)会一个接一个地消失,然后回来,像这样循环。此外,&#34;节点:10,60.0 fps&#34;在右下方也会消失并在循环中返回。按循环我的意思是我在窗口内部进行缩放。看来我在SpriteKit中遇到了一个错误?我将按钮的zPosition设置为20,比其他任何东西都高(5以下)。我还设置skview.ignoresSiblingOrder = false;
感谢任何关于如何实现这一目标的帮助或建议!
编辑:在回复评论时,我没有使用模拟器。我在iPad Pro和iPhone 6+上进行了测试,两者都运行iOS 9.2。下面是我编写的代码&amp;再现行为。我也拿出了缩放代码,但它仍然可以重现。请尝试点击太空船(Apple的样本图像)大约30次,然后你会开始看到它。
MainScene.h
#import <UIKit/UIKit.h>
#import <SpriteKit/SpriteKit.h>
@interface MainScene : SKScene<NSStreamDelegate>
@property (strong, nonatomic) SKCropNode* skcrop;
@end
MainScene.m
#import "MainScene.h"
@implementation MainScene
- (void)didMoveToView: (SKView*)view { }
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ((int)[touches count] != 1) return;
UITouch* touch = [touches anyObject];
const CGPoint location = [touch locationInNode:self];
{ // without the 6 lines below, the disappearing-sprites behavior is gone
SKShapeNode* newshape = [SKShapeNode shapeNodeWithRectOfSize:
CGSizeMake(10.0, 10.0) cornerRadius:1.0];
newshape.position = location;
newshape.zPosition = 5;
newshape.fillColor = [UIColor purpleColor];
[self.skcrop addChild:newshape];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { }
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { }
@end
GameViewController.m:
#import "GameViewController.h"
#import "MainScene.h"
#import <CoreFoundation/CoreFoundation.h>
@implementation GameViewController
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft
| UIInterfaceOrientationMaskLandscapeRight;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Configure SKView
SKView* skview = (SKView*)self.view;
skview.showsFPS = true;
skview.showsNodeCount = true;
skview.ignoresSiblingOrder = false;
skview.multipleTouchEnabled = false;
// Get Screen Size
// IPad Pro prints: screen size 768 1024
// IPhone 6+ prints: screen size 375 667
const int screenWidth = floor(0.5+skview.bounds.size.width);
const int screenHeight = floor(0.5+skview.bounds.size.height);
NSLog(@"screen size %d %d", screenWidth, screenHeight);
const double width = (screenWidth < 375) ? 360 : 720;
// Configure SKScene
MainScene *skscene = [[MainScene alloc]
initWithSize:CGSizeMake(screenWidth, screenHeight)];
skscene.scaleMode = SKSceneScaleModeFill;
skscene.backgroundColor = [UIColor whiteColor];
[skview presentScene:skscene];
// Set up window's crop mask
const CGSize winSurface = CGSizeMake(width, width);
const CGPoint winPosition = CGPointMake(
CGRectGetMidX(skscene.frame), CGRectGetMidY(skscene.frame));
NSLog(@"pos %f %f", winPosition.x, winPosition.y);
SKSpriteNode* winMaskParent = [[SKSpriteNode alloc]
initWithColor:[UIColor redColor] size:winSurface];
[winMaskParent retain];
winMaskParent.position = winPosition;
SKCropNode* scnParent = [SKCropNode node];
scnParent.zPosition = 1;
scnParent.maskNode = winMaskParent;
[skscene addChild:scnParent];
SKSpriteNode* winMask = [[SKSpriteNode alloc]
initWithColor:[UIColor blueColor] size:winSurface];
[winMask retain];
winMask.position = winPosition;
SKCropNode* scn = [SKCropNode node];
scn.zPosition = 1;
scn.maskNode = winMask;
[scnParent addChild:scn];
// Add window sprite
SKSpriteNode* win =
[SKSpriteNode spriteNodeWithImageNamed:@"Spaceship.png"];
win.zPosition = 2;
win.position = winPosition;
[scn addChild:win];
for (int i = 0; i < 5; ++i) {
const double height = 30.0;
const double width = 50.0;
const double posY = screenHeight - (1+i)*100.0;
const double posX = screenWidth - width - 10.0;
SKShapeNode* button = [SKShapeNode shapeNodeWithRectOfSize:
CGSizeMake(width, height) cornerRadius:1.0];
button.position = CGPointMake(posX, posY);
button.zPosition = 15;
button.fillColor = [UIColor greenColor];
button.lineWidth = 1.0;
button.glowWidth = 0.0;
[skscene addChild:button];
}
skscene.skcrop = scn;
return;
}
@end
编辑2:我删除了嵌套的SKCropNode
,因此只有一层SKCropNode。点击太空船后,按钮精灵消失了。