2

私は常にその中心を中心に回転し、ホイールのように回転する円形のディスクスプライトを持っています。3D空間で向きを変え、回転を維持したいと思います。gridプロパティ、skewX / Y、カメラ、見つけることができるすべてのものをいじってみましたが、回転でこの効果を生成する方法がわかりません。

例

4

2 に答える 2

2

いくつかのルート:

  • 数学を計算して、回転値の正しいスキュー値を取得します。(オプション2からリバースエンジニアリングすることはできますが、申し訳ありませんが、頭のてっぺんからはわかりません)

  • 目的の効果を得るには、サブクラス化して、のメソッドをCCSpriteオーバーライドし、最初にスキューを適用してから、回転を適用する必要があります。これにより、かなり厄介なスプライトサブクラスを犠牲にして、適切なスキュー計算を理解する必要がなくなります。 CCNode- (CGAffineTransform)nodeToParentTransform

そこからCCNode.h、現在の操作の順序を知ることができます。

 /* Order in transformations with grid disabled
 -# The node will be translated (position)
 -# The node will be rotated (rotation)
 -# The node will be skewed (skewX, skewY)
 -# The node will be scaled (scale, scaleX, scaleY)
 -# The node will be moved according to the camera values (camera)
 ... etc. */

これは、最初にスキューを使用した、そのメソッドのハッキングされたバージョンです:(の元のメソッドで見つかった最適化が不足していますCCNode.m

- (CGAffineTransform)nodeToParentTransform
{
    if ( isTransformDirty_ ) {
        // Translate values
        float x = position_.x;
        float y = position_.y;

        if ( ignoreAnchorPointForPosition_ ) {
            x += anchorPointInPoints_.x;
            y += anchorPointInPoints_.y;
        }

        transform_ = CGAffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(skewY_)),
                                           tanf(CC_DEGREES_TO_RADIANS(skewX_)), 1.0f,
                                           x, y );
        // Rotation values
        float c = 1, s = 0;
        if( rotation_ ) {
            float radians = -CC_DEGREES_TO_RADIANS(rotation_);
            c = cosf(radians);
            s = sinf(radians);
        }

        CGAffineTransform rotMatrix = CGAffineTransformMake( c * scaleX_,  s * scaleX_,
                                           -s * scaleY_, c * scaleY_,
                                          0.0f, 0.0f );
        transform_ = CGAffineTransformConcat(rotMatrix, transform_);

        // adjust anchor point
        if( ! CGPointEqualToPoint(anchorPointInPoints_, CGPointZero) )
            transform_ = CGAffineTransformTranslate(transform_, -anchorPointInPoints_.x, -anchorPointInPoints_.y);

        isTransformDirty_ = NO;
    }
    return transform_;
}
于 2012-08-06T21:24:54.117 に答える
2

HachiEthanの答えは良いです、そしてあなたが回転を維持しながらskewX/skewYで遠近法を設定することを可能にします。ただし、遠近感を設定するためにカメラを使用する方が簡単だと思います。その場合、回転するスプライトを親ノードでラップすることで効果を得ることができます。

例えば:

CCNode *node3D;
CCSprite *sprite;

node3D = [CCNode node];
sprite = [CCSprite spriteWithFile:@"HugeDisc_Red.png"];

//[[node3D camera] setCenterX:15 centerY:45 centerZ:40]; // You can use the camera
[node3D setSkewX:25]; // Skew also works if you prefer it
[node3D setRotation:145]; // Skew + rotation looks pretty convincing
[node3D setPosition:ccp(middleX+105, middleY-110)];

[node3D setIgnoreAnchorPointForPosition:NO];
[node3D setAnchorPoint:ccp(0.5f,0.5f)];

[sprite setPosition:ccp(node3D.contentSize.width/2, node3D.contentSize.height/2)];
[sprite runAction:rotate];

[node3D addChild:sprite];

最終的に、それは好みの問題に帰着します。このためのカスタムスプライトオブジェクトを作成しますか?カメラが好きですか、それともスキューが好きですか?ニーズに応じて、これらのいずれかがニーズに合うはずです。

于 2012-08-07T05:35:38.367 に答える