0

EDIT2: 以下の回答に応えて、CCShaky3D エフェクトによってアニメーション化された 4 つのスプライトでフレームレートのパフォーマンスをテストするために、別の GameScene を作成しました。fps がまだ約 15fps であるため、問題は解決しません。読みやすくするために、この質問の最後にコードを貼り付けます。私の推測では、同時に複数の CCShaky3D を実行しているという事実によるものです。フレームレートを落とさずに複数の CCShaky3D エフェクトを同時に実行できる人はいますか?

ゲームに cocos2d のエフェクト ( cocos2d プログラミング ガイド) を導入したところ、FPS が劇的に遅くなることに気付きました。エフェクトを適用したスプライトが表示されたら、60fps から 10fps まで。

私は最初にそれらをゲームに導入しましたが、黒い背景の問題がありました (post so postのように)。私は解決策に従い、問題は解決しました。

デバッガーで、アニメーションを適用する 4 番目のスプライトが表示されると、アプリケーションがメモリ警告を受け取ることに気付きました。エフェクトを適用した 2 番目のスプライトが表示されるとすぐに、フレーム レートが低下します。シーンでは、画面に他の 2 ~ 3 の敵スプライトとプレイヤー スプライトが同時に表示されていますが、これはメモリの問題である可能性があります。次に、アニメーション付きのスプライトを 1 つだけ追加しようとしましたが、残りの 2 ~ 3 個の敵スプライトはまだそこにあり、フレーム レートは「わずか」~ 45 fps に低下します。

編集: これらのスプライトにエフェクトを適用しない場合、フレーム レートは変わりません (~60fps のままです)。

これは私の記憶の管理方法によるものだと思いますが、コードを劇的に変更する前に、これについて意見を集めたいと思いました。たとえば、シーンを実行できますか。効果のある 2 ~ 3 個のスプライトと、4 ~ 5 個の他のスプライト (敵やプレイヤーなど) が動き回っていますか?

EAGLView の適切な初期化:

エフェクトを実行するには、EAGLView の初期化を変更する必要がありました。関係があると思われるので、ここに投稿します。私は UIViewController と EAGLView の初期化に非常に慣れていないので、何か間違ったことをしているのか、それがフレームレートに影響を与える可能性があるのか​​ 疑問に思っています。

「 iPhone と iPad の学習 cocos2d」第 8 章のソース コードから ShootEmUp の例を変更したところ、例の AppDelegate に RootViewController インスタンスがないことに気付きました。代わりに、Coco2d クックブックでは、RootViewController が AppDelegate と、Cocos2d を使用して作成したすべてのテンプレートで使用されます。私のコードでは、 CC_DIRECTOR_INIT() マクロを変更して、投稿2で提案されているように EAGLView の初期化を追加しました。

ShootEmUp の例 ( 3 )でのアプローチを確認する cocos2d アプリケーションで UIViewController を作成する必要はないと述べているこの公式 cocos2d ガイドを見つけました。CCDirector、EAGLView、UIViewController の役割にまだ慣れていないので、それらがどのように相互に作用するか、またそれらの初期化がフレーム レートに影響を与える可能性があるかどうかについて、コミュニティに説明を求めたいと思います。どうもありがとう。

編集 2 - CCShaky3D エフェクト効果を fps パフォーマンス レートでテストするために使用したソース コード:

// Element.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Element : CCSprite {

}
+(id) elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:(enum ElementsType)type:  (int)time  :(NSString*)frameName :(CGPoint) spawnPosition;
@end


//Implementation of elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos method.. 
+(id) elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:(enum ElementsType)type:  (int)time  :(NSString*)frameName :(CGPoint) spawnPosition;
{
    return [[[self alloc] initWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:type :time :frameName :spawnPosition] autorelease];
}

//TestLayer.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface TestLayer : CCLayer {

}
+(CCScene *) scene;
@end


//TestLayer.m

#import "TestLayer.h"
#import "Element.h"

@implementation TestLayer


+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    TestLayer *layer = [TestLayer node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

/ on "init" you need to initialize your instance
-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {
        CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
        [frameCache addSpriteFramesWithFile:@"game-art-hd.plist"];

        // ask director the the window size
        CGSize size = [[CCDirector sharedDirector] winSize];

        CCSprite *background = [CCSprite spriteWithFile:@"bg1.png"];
        background.anchorPoint = CGPointMake(0.5f, 0);
        background.position = CGPointMake(size.width/2, 0);
        [self addChild:background];

        Element * element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(100.0f, 20.0f)];
        element.visible=TRUE;
        id shaky = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];
        [element runAction:shaky ];
        [self addChild:element ];

        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(140.0f, 20.0f)];
        id shaky2 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        element.visible=TRUE;
        [element runAction:shaky2 ];
        [self addChild:element ];

        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(240.0f, 20.0f)];
        element.visible=TRUE;
        id shaky3 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        [element runAction:shaky3 ];
        [self addChild:element ];


        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(340.0f, 20.0f)];
        element.visible=TRUE;
        id shaky4 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        [element runAction:shaky4 ];
        [self addChild:element ];

    }
    return self;
}
4

2 に答える 2

1

実際のデバイスで実行したときに取得した FPS は? シミュレーターは、実際のデバイスと比較してパフォーマンスが大幅に低下することを知っておく必要があります。私は現在、戦闘シーンで 16 以上のアニメーション化されたスプライトを含むアプリを実行しています。デバイスでは非常に適切なフレーム レートで動作しますが、シミュレーターでは 10 FPS 未満です。そして、はい、そのメモリ警告に注意してください。どこかで適切に割り当てが解除されないスプライトがある可能性があります。これを確認するには、コードの適切な場所に次の行を追加する必要があります。

    [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
    [[CCDirector sharedDirector] purgeCachedData];
    [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];

テクスチャ キャッシュにあるものが期待どおりであることを確認します。そうでない場合は、「サプライズ」テクスチャを追跡し、それらが適切に削除されていることを確認してください。

于 2012-05-16T12:12:28.810 に答える
1

同じ問題かどうかはわかりませんが、CCShaky3D アクションを実行した後、フレーム レートが 60 ~ 50 fps から 30 ~ 20 fps に低下しました。

CCShaky3D と CCStopGrid を使用してアクション シーケンスを作成することで、問題を解決できました。最後の 1 つは、フレーム レートの回復を担当します。

于 2013-01-24T09:20:14.763 に答える