Cocos2d - the initial level of the application does not display correctly when the application loads, appears after reboot

I use Singleton GameManager to handle some common tasks that are necessary for my game. One of these tasks is to load individual game scenes. When the game starts, depending on which combination of the scene / layer is displayed, is displayed incorrectly; It looks like the coordinates that the positions are positioned with respect to the wrong ones.

It doesn’t matter which layer I choose - they all display incorrectly. If you click on the button and load another scene / layer, return to the plot / layer in question, everything will be displayed correctly. This only happens on retina display devices, so I think it could be due to the scaling that I set for different types of display in the game manager. However, zooming for Retina displays tears the situation even further (layers are too small).

Here is 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]; } } 
+4
source share
2 answers

I ran into a similar problem once, but I cannot associate it directly with your code.

In short, the problem is that while I create my layer / scene in the init method, nodeToWorldTransformation (at least, possibly others) is not installed. So, if you are trying to calculate the world coordinates (or perhaps the size in world coordinates) of something, this will not work.

Now, in the case, I used this transformation to calculate the scale factor during init, and that was wrong. If I postponed the calculation before the conversion was established, everything was in order. The transformation will be ready only after the layer you create is added to its parent element, but I'm not quite sure when it does it. Finally, in my case, I just encoded the transform, knowing all the dimensions during init.

It seems that your case may be similar to this, but, as I said, I cannot associate this with your code.

0
source

You call node with scene objects that call [MainMenuScene scene]; and try

and make this method with CCScene * return type and use to return the scene and record

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

Edit -

 -(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; } 
-one
source

Source: https://habr.com/ru/post/1394526/


All Articles