2016-02-01 16 views
5

でのシーンの背景の周りにカメラをクランプので、私は、以下のビットバケットリンクで見つけることができますベースのゲームを設定していますシーンのレイアウトに関連してカメラノードを翻訳する。はSpriteKitベース

目標は、シーンのサイズによって定義されるコーナー境界に達するまで、カメラをプレイヤーに追従させることです。

:新しい位置に文字を追跡するように設定されている場合、この特定のテストシナリオのセットアップでは、シーンは1

のカメラ規模以下のコードでサイズは1000×1000であるが、カメラの位置を変更するために使用されます

var cameraPosition: CGPoint { 

     get { 
      return CGPoint(x: camera!.position.x, y: camera!.position.y) 
     } 

     set { 

      let cameraScale = CGFloat(1) 
      let sceneScale = CGFloat(1)//CGFloat(1 - 0.44 + 0.05 /*possible rounding error adjustment*/) 
//   let viewAspectRatio = CGRectGetWidth(view!.frame)/CGRectGetHeight(view!.frame) 
      let newPositionValue = double2(x: Double(newValue.x * sceneScale), y: Double(newValue.y * sceneScale)) 

      let scaledSceneSize = CGSize(width: size.width * sceneScale , height: size.height * sceneScale) 
////   scaledSceneSize.height = scaledSceneSize.height/viewAspectRatio 

      let cameraSize = view!.bounds.size 
      let scaledCameraSize = CGSize(width: cameraSize.width * cameraScale, height: cameraSize.height * cameraScale) 


      let minX = 0//-scaledSceneSize.width * anchorPoint.x + scaledCameraSize.width/2 
      let minY = -219//-scaledSceneSize.height * anchorPoint.y + scaledCameraSize.height/2 

      let minValues = double2(x: Double(minX), y: Double(minY)) 

      let maxX = 0//(scaledSceneSize.width * anchorPoint.x - scaledCameraSize.width/2) //size.width - cameraSize.width/2 
      let maxY = 219//(scaledSceneSize.height * anchorPoint.y - scaledCameraSize.height/2) //- cameraSize.height/2 

      let maxValues = double2(x: Double(maxX), y: Double(maxY)) 

      let clampedPosition = clamp(newPositionValue, min: minValues, max: maxValues) 


      camera!.position = CGPoint(x: (clampedPosition.x/Double(sceneScale)), y: (clampedPosition.y/Double(sceneScale))) 
     } 

    } 

現在、必要なシーンサイズに合ったハードコアの値があります。スケールを介してその結果を取得する方法がわかりません。デフォルトではスケールがある: - cameraSize.width/2 largestSceneDimensionYValue - cameraSize.height/2スケールでの翻訳があります知っての知識がなくても

/* Set the scale mode to scale to fit the window */ 
      scene.scaleMode = .AspectFill 

、デフォルトでは、私は境界が largestSceneDimensionXValueことを期待します

上位レベルの例として、誰でもこの翻訳を手伝うことができますか?

全体のシーンはすべてのコーナーでは、次のようになります。 goal

VSのようなカメラに黒の背景オーバーフローを持つ:

anti goal

答えて

1

私はあなたのコードを使用していませんでした。私はサンプルプロジェクトを作ってこれを手に入れました。

enter image description here

HERESに私のコード

import SpriteKit 

class GameScene: SKScene { 

    let world = SKSpriteNode(imageNamed: "world.jpg") 
    let player = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(10, 10)) 

    var cam: SKCameraNode! 

    override init(size: CGSize) { 
     super.init(size: size) 
     print(world.size) 
     addChild(world) 
     addChild(player) 

     world.zPosition = 1 
     player.zPosition = 2 

     cam = SKCameraNode() 
     self.camera = cam 
     addChild(cam) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     for touch: AnyObject in touches { 
      let location = touch.locationInNode(self) 

      player.position = location 
     } 
    } 

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     for touch: AnyObject in touches { 
      let location = touch.locationInNode(self) 

      player.position = location 
     } 
    } 

    func clampCamera(){ 

     func clamp(inout input: CGFloat, num1: CGFloat, num2: CGFloat) { 
      if input < num1 { 
       input = num1 
      } 
      else if input > num2 { 
       input = num2 
      } 
     } 

     let lBoundary = -world.size.width/2 + size.width/2 
     let rBoundary = world.size.width/2 - size.width/2 
     let bBoundary = -world.size.height/2 + size.height/2 
     let tBoundary = world.size.height/2 - size.height/2 

     clamp(&camera!.position.x, num1: lBoundary, num2: rBoundary) 
     clamp(&camera!.position.y, num1: bBoundary, num2: tBoundary) 

    } 

    override func update(currentTime: NSTimeInterval) { 
     camera!.position = player.position 
     clampCamera() 
    } 
} 

これは私が私の "世界" として使用されるのと同じ画像であり、このような http://i.imgur.com/XhZbh8q.jpg

+0

これは私の最初のアプローチと非常によく似ていますが、これはカメラの背もたれや他の条件をスケーリングするときには機能しません。上記のコードを添付した主な理由は、特定のシナリオを参照することです。レポに掲載されたコードで上記のコードを使用することができれば、完璧であるはずですが、私は100%肯定的です。カメラのスケールは0.44にする必要がありますが、値がどこから来ているかを調べるためにすべてを正規化しました。 – TheCodingArt

+0

シーンの幅がカメラの幅と一致していないことに注意してください。 – TheCodingArt

+0

私はあなたのコードとその周りに遊んで自分自身のプロジェクトの笑になり始めました..本当にたくさんそこに進んでいます.. もし私があなたの新しいサンプルプロジェクトを開始するかもしれない複雑さの各要素(cameraScale ..あなたが問題を解決する簡単な方法を見つけることができるまで、一度に1つずつ)。 – hamobi

2

アプリケーションはSKConstraintがためですまさにです。

WWDC15セッションのDeeper into GameplayKit with DemoBotsで、この正確な機能のデモを見ることができます。カメラを拘束してプレーヤに追従させ、レベルの周りに空きスペースをあまり表示しません。*(リンクこの機能の議論が始まる話では約7:27にそこにジャンプします)

DemoBotsサンプルコードからいくつか抜粋して、ビデオで何の要旨:。

  1. を使用します距離カメラをプレーヤーの中央に維持するための制約(自動的にupdate()に直接camera.positionを設定する必要はありません)。

    // Constrain the camera to stay a constant distance of 0 points from the player node. 
    let zeroRange = SKRange(constantValue: 0.0) 
    let playerBotLocationConstraint = SKConstraint.distance(zeroRange, toNode: playerNode) 
    
  2. レベルのエッジの特定の範囲内カメラを維持する位置制約を使用。レベルのフレームを取得し、カメラがレベルの端から守るべき距離だけその矩形を挿入することによって、その範囲を計算します。

    // get the scene size as scaled by `scaleMode = .AspectFill` 
    let scaledSize = CGSize(width: size.width * camera.xScale, height: size.height * camera.yScale) 
    
    // get the frame of the entire level contents 
    let boardNode = childNodeWithName(WorldLayer.Board.nodePath)! 
    let boardContentRect = boardNode.calculateAccumulatedFrame() 
    
    // inset that frame from the edges of the level 
    // inset by `scaledSize/2 - 100` to show 100 pt of black around the level 
    // (no need for `- 100` if you want zero padding) 
    // use min() to make sure we don't inset too far if the level is small 
    let xInset = min((scaledSize.width/2) - 100.0, boardContentRect.width/2) 
    let yInset = min((scaledSize.height/2) - 100.0, boardContentRect.height/2) 
    let insetContentRect = boardContentRect.insetBy(dx: xInset, dy: yInset) 
    
    // use the corners of the inset as the X and Y range of a position constraint 
    let xRange = SKRange(lowerLimit: insetContentRect.minX, upperLimit: insetContentRect.maxX) 
    let yRange = SKRange(lowerLimit: insetContentRect.minY, upperLimit: insetContentRect.maxY) 
    let levelEdgeConstraint = SKConstraint.positionX(xRange, y: yRange) 
    levelEdgeConstraint.referenceNode = boardNode 
    
  3. あなたSKCameraNodeに両方の制約を適用します。コメントをたくさん持っていると私は過度に長くなってからこのポストを維持するために上記のスニペットからトリミングされたコードをサポートしているより深く見て、download Apple's DemoBots sample code projectについて

    camera.constraints = [playerBotLocationConstraint, levelEdgeConstraint] 
    

。カメラの制約のためのすべてはfunc setCameraConstraints()LevelScene.swiftにあります。

*セッション名にもかかわらず、これは単なるGameplayKit以上のものです... iOS 8/OS X 10.11/Xcode 7で導入された多くのテクノロジをフル活用して本格的なゲーム:App Thinning、新しいSpriteKit機能、ReplayKitなど。

+0

あなたは質問のポイントを見落としています。はい、これは制約のための主要なアプリケーションですが、上記の質問が答えを得ようとしていることである一般的なオフセットをまだ計算して知る必要があります。 – TheCodingArt

+0

*レベルが十分に大きく、カメラの縮尺や回転がない場合は、画面の幅/高さの半分になるように設定することができます*レベルが常にデバイス画面より小さい場合は、あなたが必要とするのはレベルフレームからです。 – rickster

+0

これらの条件は上記のサンプルアプリケーションには適用されません。カメラに合わせて調整可能なものが必要です。 – TheCodingArt

関連する問題