Cocos2d - 初始应用层在应用加载时显示不正确,在重新加载后显示正确

时间:2012-02-03 02:13:59

标签: uiview cocos2d-iphone cclayer

我正在使用GameManager单例来处理我的游戏所需的一些共享任务。其中一项任务是加载单个游戏场景。当游戏启动时,我显示的任何场景/图层组合都显示不正确;看起来物品相对于的位置坐标可能是错误的。

我选择哪一层并不重要 - 它们都显示不正确。如果单击按钮并加载另一个场景/图层,则返回到相关场景/图层,一切都正确显示。这只发生在视网膜显示设备上,所以我认为它可能与我为游戏管理器中的不同显示类型设置的缩放有关。但是,更改Retina显示的缩放会使事情更加突破(图层太小)。

这是我的AppDelegate.h

#import <UIKit/UIKit.h>

@class RootViewController;

@interface AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow            *window;
    RootViewController  *viewController;
}

@property (nonatomic, retain) UIWindow *window;

@end

AppDelegat.m

#import "cocos2d.h"

#import "AppDelegate.h"
#import "GameConfig.h"
#import "RootViewController.h"
#import "GameplayScene.h"
#import "GameManager.h"

@implementation AppDelegate

@synthesize window;

- (void) removeStartupFlicker
{
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
#endif
}


- (void) applicationDidFinishLaunching:(UIApplication*)application
{
    // Init the window
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Try to use CADisplayLink director
    // if it fails (SDK < 3.1) use the default director
    if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
        [CCDirector setDirectorType:kCCDirectorTypeDefault];


    CCDirector *director = [CCDirector sharedDirector];

    // Init the View Controller
    viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    viewController.wantsFullScreenLayout = YES;

    EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
                                   pixelFormat:kEAGLColorFormatRGB565   // kEAGLColorFormatRGBA8
                                   depthFormat:0                        // GL_DEPTH_COMPONENT16_OES
                        ];

    // attach the openglView to the director
    [director setOpenGLView:glView];
    [director setDeviceOrientation:kCCDeviceOrientationPortrait];

    [director setAnimationInterval:1.0/60];
    [director setDisplayFPS:YES];


    // make the OpenGLView a child of the view controller
    [viewController setView:glView];

    // make the View Controller a child of the main window
    [window addSubview: viewController.view];

    [window makeKeyAndVisible];

    [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];


    // Removes the startup flicker
    [self removeStartupFlicker];

    // Run the intro Scene
    //[[CCDirector sharedDirector] runWithScene:[GameplayScene node]];
    [[GameManager sharedGameManager] runSceneWithID:kMainMenuScene];
}

- (void)dealloc {
    [[CCDirector sharedDirector] end];
    [window release];
    [super dealloc];
}

GameManager.h

#import <Foundation/Foundation.h>
#import "Constants.h"
#import "CommonProtocols.h"

@interface GameManager : NSObject {
    BOOL isMusicON;
    BOOL isSoundEffectsON;
    BOOL hasPlayerDied;
    BOOL newHighScore;
    BOOL newBestTime;
    BOOL isUiTextLeft;
    int currentScore;
    int highScore;
    int lengthPlayed;
    int bestTime;
    int randomPurple;
    int randomGreen;
    int timeBonus;
    int timeTillDeath;
    int uiBackgroundHeight;
    CharacterStates previousPurpleState;
    CharacterStates previousGreenState;
    SceneTypes currentScene;
}

@property (readwrite) BOOL isMusicON;
@property (readwrite) BOOL isSoundEffectsON;
@property (readwrite) BOOL hasPlayerDied;
@property (readwrite) BOOL newHighScore;
@property (readwrite) BOOL newBestTime;
@property (readwrite) BOOL isUiTextLeft;
@property (readwrite) int currentScore;
@property (readwrite) int highScore;
@property (readwrite) int lengthPlayed;
@property (readwrite) int bestTime;
@property (readwrite) int randomPurple;
@property (readwrite) int randomGreen;
@property (readwrite) int uiBackgroundHeight;
@property (readwrite) CharacterStates previousPurpleState;
@property (readwrite) CharacterStates previousGreenState;
@property (readwrite) int timeBonus;
@property (readwrite) int timeTillDeath;

+(GameManager*)sharedGameManager;
-(void)runSceneWithID:(SceneTypes)sceneID;
-(void)openSiteWithLinkType:(LinkTypes)linkTypeToOpen ;

@end

GameManager.m

#import "GameManager.h"
#import "GameplayScene.h"
#import "MainMenuScene.h"
#import "OptionsScene.h"
#import "CreditsScene.h"
#import "IntroScene.h"
#import "LevelCompleteScene.h"

@implementation GameManager

static GameManager* _sharedGameManager = nil; 
@synthesize isMusicON;
@synthesize isSoundEffectsON;
@synthesize hasPlayerDied;
@synthesize newHighScore;
@synthesize newBestTime;
@synthesize isUiTextLeft;
@synthesize currentScore;
@synthesize highScore;
@synthesize lengthPlayed;
@synthesize bestTime;
@synthesize previousPurpleState;
@synthesize previousGreenState;
@synthesize randomPurple;
@synthesize randomGreen;
@synthesize timeBonus;
@synthesize timeTillDeath;
@synthesize uiBackgroundHeight;

+(GameManager*)sharedGameManager {
    @synchronized([GameManager class])
    {
        if(!_sharedGameManager)
            [[self alloc] init]; 
        return _sharedGameManager;
    }
    return nil; 
}

+(id)alloc {
    @synchronized([GameManager class]){
        NSAssert(_sharedGameManager == nil, @"Attempted to allocate a second instance of the Game Manager singleton");
        _sharedGameManager = [super alloc];
        return _sharedGameManager;
    }
    return nil;
}

-(id) init {
    self = [super init];
    if (self != nil) {
        // Game manager initialized
        CCLOG(@"Game manager singleton, init");
        hasPlayerDied = NO;
        // DECODING INFO FROM DEFAULTS
        NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [dirPaths objectAtIndex:0];

        NSMutableData *gameData;
        NSKeyedUnarchiver *decoder;

        NSString *documentPath = [documentsDirectory stringByAppendingPathComponent:@"gameState.dat"];
        gameData = [NSData dataWithContentsOfFile:documentPath];

        if (gameData) {
            decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData];

            highScore = [decoder decodeIntForKey:@"highScore"];
            bestTime = [decoder decodeIntForKey:@"bestTime"];
            isMusicON = [decoder decodeBoolForKey:@"isMusicON"];
            isSoundEffectsON = [decoder decodeBoolForKey:@"isSoundEffectsON"];
            isUiTextLeft = [decoder decodeBoolForKey:@"isUiTextLeft"];
            //currentScore = [decoder decodeIntForKey:@"currentScore"];

            [decoder release];
        } else {
            highScore = 0;
            bestTime = 0;
            isMusicON = TRUE;
            isSoundEffectsON = TRUE;
            isUiTextLeft = TRUE;
            //currentScore = 0;
        }

        CCLOG(@"Music - %s", isMusicON ? "true" : "false");
        CCLOG(@"Sound - %s", isSoundEffectsON ? "true" : "false");
        //****************************
        currentScore = 0;
        timeBonus = 0;
        timeTillDeath = 0;
        uiBackgroundHeight = 0;
        currentScene = kNoSceneUninitialized;
    }

    return self;
}

-(void)runSceneWithID:(SceneTypes)sceneID {

    SceneTypes oldScene = currentScene;
    currentScene = sceneID;
    id sceneToRun = nil;

    switch (sceneID) {
        case kMainMenuScene:
            sceneToRun = [MainMenuScene node];
            break;
        case kOptionsScene:
            sceneToRun = [OptionsScene node];
            break;
        case kCreditsScene:
            sceneToRun = [CreditsScene node];
            break;
        case kIntroScene:
            sceneToRun = [IntroScene node];
            break;
        case kLevelCompleteScene:
            sceneToRun = [LevelCompleteScene node];
            break;
        case kGameplayScene:
            sceneToRun = [GameplayScene node];
            break;
        default:
            CCLOG(@"Unknown ID, cannot switch scenes");
            return;
            break;
    }

    if (sceneToRun == nil) {
        // Revert back, since no new scene was found
        currentScene = oldScene;
        return;
    }

    // Menu Scenes have a value of < 100
    if (sceneID < 100) {

        if ([[CCDirector sharedDirector] enableRetinaDisplay:YES]) {
            // iPhone 4 Retina
            [sceneToRun setScaleX:1.0f];
            [sceneToRun setScaleY:1.0f];
            CCLOG(@"GM:Scaling for iPhone 4 (retina)");
        } else {
            [sceneToRun setScaleX:1.0f];
            [sceneToRun setScaleY:1.0f];
            CCLOG(@"GM:Scaling for iPhone 3G(non-retina)");
        }
    }

    if ([[CCDirector sharedDirector] runningScene] == nil) {
        [[CCDirector sharedDirector] runWithScene:sceneToRun];
    } else {
        [[CCDirector sharedDirector] replaceScene:sceneToRun];
    }
}

2 个答案:

答案 0 :(得分:0)

我曾遇到过类似的问题,但我似乎无法直接将其与您的代码联系起来。

简而言之,问题是当我在init方法中构建我的图层/场景时,nodeToWorldTransformation(至少,可能还有其他人)也没有设置。因此,如果您正在尝试计算某事物的世界坐标(或可能是世界坐标的大小),则它不起作用。

现在,在可能的情况下,我使用该变换在初始时计算比例因子,这是错误的。如果我在设置转换后将计算延迟到了,那么一切都很好。只有 之后您正在创建的图层已添加到其父级,但我不确定它何时发生。最后,在我的情况下,我只是硬编码转换,知道初始时的所有维度。

您的案例似乎与此类似,但正如我所说,我无法将此与您的代码联系起来。

答案 1 :(得分:-1)

您正在使用场景对象调用node来调用[MainMenuScene scene];并尝试

并使用返回类型CCScene *创建此方法并使用返回场景并写入

[[CCDirector sharedDirector]runWithScene:[obj runSceneWithID:1]];

编辑 -

-(CCScene*)runSceneWithID:(SceneTypes)sceneID {

    SceneTypes oldScene = currentScene;
    currentScene = sceneID;
    id sceneToRun = nil;

    switch (sceneID) {
        case kMainMenuScene:
            sceneToRun = [MainMenuScene node];
            break;
        case kOptionsScene:
            sceneToRun = [OptionsScene node];
            break;
        case kCreditsScene:
            sceneToRun = [CreditsScene node];
            break;
        case kIntroScene:
            sceneToRun = [IntroScene node];
            break;
        case kLevelCompleteScene:
            sceneToRun = [LevelCompleteScene node];
            break;
        case kGameplayScene:
            sceneToRun = [GameplayScene node];
            break;
        default:
            CCLOG(@"Unknown ID, cannot switch scenes");
            return nil;
            break;
    }

    if (sceneToRun == nil) {
        // Revert back, since no new scene was found
        currentScene = oldScene;

    }
    return sceneToRun;
}