I'm using a GameManager singleton to handle some of the shared tasks required by my game. One of those tasks is loading individual game scenes. When the game starts up, whichever scene/layer combo I have displayed appears incorrectly; it looks like maybe the coordinates that items are positioned in relation to are wrong.
It doesn't matter which layer I choose–they all appear incorrectly. If you click on a button and load another scene/layer, then go back to the scene/layer in question, everything displays correctly. This only happens on retina display devices, so I think it might be related to the scaling I set for the different display types in the game manager. However, changing the scaling for Retina displays breaks things even more (the layers are too small).
Here's my 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];
}
}
You are calling
node
with the scene objects call[MainMenuScene scene];
and tryand make this method with return type CCScene* and use to get return the scene and write
Edit --