0

我正在开发一个小游戏,其中一艘飞船穿过一个层(doh!),在某些情况下飞船靠近敌人,整个层在飞船上以缩放级别放大取决于船和敌人之间的距离。所有这一切都很好。

然而,主要的问题是,我如何保持变焦以飞船为中心?

目前我通过update方法控制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;
    }
}

基本上我的问题是:如何缩放图层并将其准确地居中在两艘船之间?我想这就像用两根手指捏缩放!

4

2 回答 2

1

下面是一些应该让它为你工作的代码。基本上你想要:

  1. parentNode在的坐标系中更新您的船舶位置
  2. 找出这些新位置将导致屏幕被绑定到哪个轴。
  3. 缩放和重新定位parentNode

我添加了一些稀疏的评论,但如果您还有其他问题/问题,请告诉我。首先将其转储到测试项目中可能是最简单的......

ivars 放入您的 CCLayer:

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]; 

Zoom / Center / Ship 更新方式:

-(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 回答