在 SpriteKit 中移动相机
Posted
技术标签:
【中文标题】在 SpriteKit 中移动相机【英文标题】:Moving a camera in SpriteKit 【发布时间】:2014-05-25 01:46:10 【问题描述】://更新 添加了更新的代码,可以按我的预期工作。请参阅下面更新代码中的 didSimulatePhysics 方法。就我而言,我只关心在 x 轴上向左或向右移动字符,其中 x 轴上的 0 是绝对左侧,而 x 轴上的右侧是可配置值。 Apple 冒险游戏也确实帮了很多忙。
//下面是原帖
我正在使用 Apple SpriteKit,并且我正在努力实现我希望它表现的相机。我在代码中所做的是加载一个精灵字符、两个按钮和一个红色框,该框在开始时位于视图右侧。我想做的是用按钮移动角色,一旦玩家到达屏幕的中间或末端,相机就会重新调整以发现在视图中看不到的东西。因此,一旦玩家到达那里,向右移动最终应该会显示最初在视图之外关闭的红色框。但是,使用我在下面使用的代码,我根本无法让相机跟随并调整主角的坐标。我查看了 Apple 的高级场景处理文档以及其他一些堆栈溢出帖子,但似乎无法正确理解。如果有人可以提供一些建议,将不胜感激。
#define cameraEdge 150
-(id)initWithSize:(CGSize)size
if (self = [super initWithSize:size])
/* Setup your scene here */
//320 568
self.backgroundColor = [SKColor whiteColor];
myWorld = [[SKNode alloc] init];
[self addChild:myWorld];
mainCharacter = [SKSpriteNode spriteNodeWithImageNamed:@"0"];
mainCharacter.physicsBody.dynamic = YES;
mainCharacter.name = @"player";
mainCharacter.position = CGPointMake(20, 20);
CGRect totalScreenSize = CGRectMake(0, 0, 800, 320);
SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxTwo = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxThree = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(60, 60)];
boxThree.position = CGPointMake(40, 50);
[myWorld addChild:boxThree];
boxTwo.position = CGPointMake(1100, 50);
box.position = CGPointMake(650, 50);
[myWorld addChild:box];
[myWorld addChild:boxTwo];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:totalScreenSize];
self.physicsWorld.gravity = CGVectorMake(0, -5);
mainCharacter.name = @"mainCharacter";
mainCharacter.physicsBody.linearDamping = 0;
mainCharacter.physicsBody.friction = 0;
mainCharacter.physicsBody.restitution = 0;
mainCharacter.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:mainCharacter.size];
[myWorld addChild:mainCharacter];
[self addChild:[self buildLeftButton]];
[self addChild:[self buildRightButton]];
return self;
- (void)didSimulatePhysics
SKSpriteNode *hero = mainCharacter;
if(hero)
CGPoint heroPosition = hero.position;
CGPoint worldPosition = myWorld.position;
NSLog(@"%f", heroPosition.x);
CGFloat xCoordinate = worldPosition.x + heroPosition.x;
if(xCoordinate < cameraEdge && heroPosition.x > 0)
worldPosition.x = worldPosition.x - xCoordinate + cameraEdge;
self.worldMovedForUpdate = YES;
else if(xCoordinate > (self.frame.size.width - cameraEdge) && heroPosition.x < 2000)
worldPosition.x = worldPosition.x + (self.frame.size.width - xCoordinate) - cameraEdge;
self.worldMovedForUpdate = YES;
myWorld.position = worldPosition;
-(SKSpriteNode *)buildLeftButton
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:@"left"];
leftButton.position = CGPointMake(20, 20);
leftButton.name = @"leftButton";
leftButton.zPosition = 1.0;
return leftButton;
-(SKSpriteNode *)buildRightButton
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:@"right"];
leftButton.position = CGPointMake(60, 20);
leftButton.name = @"rightButton";
leftButton.zPosition = 1.0;
return leftButton;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if([node.name isEqualToString:@"leftButton"])
[mainCharacter.physicsBody applyImpulse:CGVectorMake(-120, 0)];
else if([node.name isEqualToString:@"rightButton"])
[mainCharacter.physicsBody applyImpulse:CGVectorMake(120, 10)];
【问题讨论】:
【参考方案1】:如果您希望视图始终以玩家的位置为中心,请记住以下几点修改您的代码:
1) 创建一个 SKNode 并将其命名为 myWorld、worldNode 或任何其他类似名称。
2) 添加世界节点[self addChild:worldNode];
3) 将所有其他节点添加到 worldNode,包括您的播放器。
4) 在didSimulatePhysics
方法中,添加以下代码:
worldNode.position = CGPointMake(-(player.position.x-(self.size.width/2)), -(player.position.y-(self.size.height/2)));
您的视图现在将始终以玩家的位置为中心。
2015 年 5 月更新:
如果您使用的是通过平铺地图编辑器创建的地图,您可以使用免费的SKAToolKit framework。功能包括播放器相机自动跟随、测试播放器、测试 HUD 和精灵按钮。
【讨论】:
感谢 sangony 的回复。我已经修改了原始帖子中的代码以反映您建议的更改。但是,该角色出现在右上角,并且移动按钮消失了。我假设我必须以某种方式将移动按钮锚定在当前视图中,以便它们在视图调整时移动,但不太确定按钮是否应该锚定到场景、世界或相机。 @zic10 - 您可以直接将控制按钮添加到视图中,这样它们就不会移动。如果您需要修改与播放器相关的中心位置,您可以添加偏移值。例如:((player.position.x-(self.size.width/2)+20) 偏移量为+20。 这是否意味着我可以丢弃相机节点而只在 myWorld 节点中执行所有操作? @zic10 - 是的。把“worldNode”想象成一个巨大的画布,你可以在你的视图前四处移动,它有点像一扇窗户。应该与 worldNode 一起移动的所有内容都应该是 worldNode 的子节点。请记住,当窗口(您的视图)保持静止时,您正在移动画布(worldNode)。 抱歉耽搁了,已接受为答案。我还想补充一点,Apple 的“冒险”游戏示例中的一些代码也确实有帮助。将在原始帖子中添加此代码。以上是关于在 SpriteKit 中移动相机的主要内容,如果未能解决你的问题,请参考以下文章
带有 Skview 的 ViewController - SpriteKit SKScene