4

我正在使用 GameManager 单例来处理我的游戏所需的一些共享任务。其中一项任务是加载单个游戏场景。游戏启动时,无论我显示的哪个场景/图层组合出现错误;看起来项目相对于定位的坐标可能是错误的。

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

这是我的 AppDelegate.h

#import <UIKit/UIKit.h>

@class RootViewController;

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

@property (nonatomic, retain) UIWindow *window;

@end

应用委托.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];
}

游戏管理器.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

游戏管理器.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];
    }
}
4

2 回答 2

0

我曾经遇到过类似的问题,但我似乎无法将它直接与您的代码相关联。

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

现在,在可能的情况下,我在初始化时使用该变换来计算比例因子,但这是错误的。如果我将计算延迟到设置转换后,那么一切正常。只有在您创建的图层被添加到其父级之后,转换才准备就绪,但我不确定它什么时候可以。最后,就我而言,我只是对转换进行硬编码,在初始化时就知道所有维度。

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

于 2012-02-11T19:30:24.493 回答
-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;
}
于 2012-02-06T07:19:46.260 回答