0

私は、宇宙船がレイヤーを通過する小さなゲームを開発中です (doh!)。場合によっては、宇宙船が敵に近づき、レイヤー全体がズーム レベルで宇宙船にズームインされます。船と敵の間の距離に依存します。これはすべて正常に機能します。

ただし、主な問題は、ズームを宇宙船の中心に保つにはどうすればよいかということです。

現在、更新メソッドを使用して GameLayer オブジェクトのズームを制御しています。コードは次のとおりです。

-(void) prepareLayerZoomBetweenSpaceship{
    CGPoint mainSpaceShipPosition  = [mainSpaceShip position];
    CGPoint enemySpaceShipPosition = [enemySpaceShip position];

    float distance = powf(mainSpaceShipPosition.x - enemySpaceShipPosition.x, 2) + powf(mainSpaceShipPosition.y - enemySpaceShipPosition.y,2);
    distance = sqrtf(distance);

    /*
        Distance > 250 --> no zoom
        Distance < 100 --> maximum zoom
     */
    float myZoomLevel = 0.5f;
    if(distance < 100){ //maximum zoom in
        myZoomLevel = 1.0f;
    }else if(distance > 250){
        myZoomLevel = 0.5f;
    }else{
        myZoomLevel = 1.0f - (distance-100)*0.0033f;
    }

    [self zoomTo:myZoomLevel];
}

-(void) zoomTo:(float)zoom {
    if(zoom > 1){
        zoom = 1;
    }

    // Set the scale.
    if(self.scale != zoom){
        self.scale = zoom;
    }
}

基本的に私の質問は次のとおりです。レイヤーをズームして、2 つの船のちょうど真ん中に配置するにはどうすればよいですか? これは2本指でピンチズームみたいな感じかな!

4

2 に答える 2

1

以下は、それを機能させるためのコードです。基本的に、次のことを行います。

  1. parentNodeの座標系内で船の位置を更新します
  2. これらの新しい位置によって画面がどの軸に拘束されるかを把握します。
  3. スケーリングと再配置parentNode

まばらなコメントをいくつか追加しましたが、他に質問や問題がある場合はお知らせください。最初にこれをテストプロジェクトにダンプするのが最も簡単かもしれません...

CCLayer に入れる ivar:

CCNode *parentNode;
CCSprite *shipA;
CCSprite *shipB;
CGPoint destA, deltaA;
CGPoint destB, deltaB;
CGPoint halfScreenSize;
CGPoint fullScreenSize;

CCLayer に入れる初期化要素:

CGSize size = [[CCDirector sharedDirector] winSize];
fullScreenSize = CGPointMake(size.width, size.height);
halfScreenSize = ccpMult(fullScreenSize, .5f);
parentNode = [CCNode node];
[self addChild:parentNode];

shipA = [CCSprite spriteWithFile:@"Icon-Small.png"]; //or whatever sprite
[parentNode addChild:shipA];

shipB = [CCSprite spriteWithFile:@"Icon-Small.png"];
[parentNode addChild:shipB];

//schedules update for every frame... might not run great.
//[self schedule:@selector(updateShips:)]; 

//schedules update for 25 times a second
[self schedule:@selector(updateShips:) interval:0.04f]; 

ズーム / センター / 船の更新方法:

-(void)updateShips:(ccTime)timeDelta {
    //SHIP POSITION UPDATE STUFF GOES HERE
    ...

    //1st: calc aspect ratio formed by ship positions to determine bounding axis
    float shipDeltaX = fabs(shipA.position.x - shipB.position.x);
    float shipDeltaY = fabs(shipA.position.y - shipB.position.y);
    float newAspect = shipDeltaX / shipDeltaY;

    //Then: scale based off of bounding axis

    //if bound by x-axis OR deltaY is negligible
    if (newAspect > (fullScreenSize.x / fullScreenSize.y) || shipDeltaY < 1.0) { 
        parentNode.scale = fullScreenSize.x / (shipDeltaX + shipA.contentSize.width);
    } 
    else { //else: bound by y-axis or deltaX is negligible
        parentNode.scale = fullScreenSize.y / (shipDeltaY + shipA.contentSize.height);
    }


    //calculate new midpoint between ships AND apply new scale to it
    CGPoint scaledMidpoint = ccpMult(ccpMidpoint(shipA.position, shipB.position), parentNode.scale);
    //update parent node position (move it into view of screen) to scaledMidpoint
    parentNode.position = ccpSub(halfScreenSize, scaledMidpoint);
}

また、たくさんのことが起こっているときにどれだけうまく機能するかはわかりませんが、それは別の問題です!

于 2012-04-14T03:06:23.287 に答える
0

ビュー全体を移動して、船が画面の中央にくるように配置してみませんか? あなたの例で試したことはありませんが、簡単なはずです。多分このようなもの -

CGFloat x = (enemySpaceShipPosition.x - mainSpaceShipPosition.x) / 2.0 - screenCentreX;
CGFloat y = (enemySpaceShipPosition.y - mainSpaceShipPosition.y) / 2.0 - screenCentreY;


CGPoint midPointForContentOffset = CGPointMake(-x, -y);

[self setContentOffset:midPointForContentOffset];

... screenCentreX と Y を既にセットアップしている場所。UISCrollView をかなり長い間使用していません (Unity で何かに取り組んでいるので、Obj-C ですべてを忘れています)。方法を思い出せません。 contentOffset はズーム レベルの影響を受けます。試してみてください!(UIScrollView を使用していると仮定しています。使用していない場合は、それも試してみてください)

于 2012-04-11T10:14:49.583 に答える