When you view the contents below, in landscape mode it's possible to auto-rotate.
So then How to automatically rotate in portrait mode?
How to setting?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//
// There are 2 ways to support auto-rotation:
// - The OpenGL / cocos2d way
// - Faster, but doesn't rotate the UIKit objects
// - The ViewController way
// - A bit slower, but the UiKit objects are placed in the right place
//
#if GAME_AUTOROTATION==kGameAutorotationNone
//
// EAGLView won't be autorotated.
// Since this method should return YES in at least 1 orientation,
// we return YES only in the Portrait orientation
//
return ( interfaceOrientation == UIInterfaceOrientationPortrait );
#elif GAME_AUTOROTATION==kGameAutorotationCCDirector
//
// EAGLView will be rotated by cocos2d
//
// Sample: Autorotate only in landscape mode
//
if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
[[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeRight];
} else if( interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
}
// Since this method should return YES in at least 1 orientation,
// we return YES only in the Portrait orientation
return ( interfaceOrientation == UIInterfaceOrientationPortrait );
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
//
// EAGLView will be rotated by the UIViewController
//
// Sample: Autorotate only in landscpe mode
//
// return YES for the supported orientations
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
#else
#error Unknown value in GAME_AUTOROTATION
#endif // GAME_AUTOROTATION
// Shold not happen
return NO;
}
If you change shouldAutorotateToInterfaceOrientation to only:
return ( interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown)
It will rotate for all orientations except portrait upside down.
Related
I am new using cocos2d-x and I'm reading HelloWorldScene.cpp code file, and so far I understood everything but the following lines of code:
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
My question is the following: what does the variables CC_TARGET_PLATFORM, CC_PLATFORM_IOS do? , what does the line of cofigo Director::getInstance()->end() does -> end ();do? and where is the funtion menuCloseCallback being called?
here is the code:
#include "HelloWorldScene.h"
//#include "MainmenuScene.h"
USING_NS_CC;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
auto closeItem = MenuItemImage::create(
"continuar.jpg",
"continuar1.jpg",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
/*////////////////////////////
// 3. add your codes below...
// add a label shows "Hello World"
// create and initialize a label
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
// position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));
// add the label as a child to this layer
this->addChild(label, 1);
// add "HelloWorld" splash screen"
auto sprite = Sprite::create("HelloWorld.png");
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(sprite, 0);*/
return true;
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
auto closeItem = MenuItemImage::create(
"continuar.jpg",
"continuar1.jpg",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
MenuItemImage has callbacks ( functions that call's on some event make):
on button pressed but doesn't release finger from pushing - MenuItemImage show continuar1.jpg, in other case it's show continuar.jpg.
on button pressed (on finger push up after pressed it) - it call function HelloWorld::menuCloseCallback with parametr.
The block of code
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
checks to see if the target platform for compilation is iOS and if it is it adds in the exit(0);
The
Director::getInstance()->end();
ends the currently running app (closes - which is what the close menu item does) This function is hooked up as call back in the menu item create.
I have an image that loads on a MainMenu scene and appears as wrong sized when the game launches but then after finishing a level returns you to the MainMenu again the image appears right sized.
The first time the image appears to be three quarters or 4/5 of the size of the screen from left to right. The image has a white background around it so I can see a black tall rectangle in the right side of the screen on the main menu's first launch. But after a game it is sized properly and the white background image is sized properly.
Anybody ever have this happen?
Here is the init code for the MainMenuLayer:
-(id)init {
if( (self=[super initWithColor:ccc4(255,255,255,255)]) ) {
[[GameManager sharedGameManager] playBackgroundTrack:BACKGROUND_TRACK_MAIN_MENU];
CGSize screenSize = [CCDirector sharedDirector].winSize;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CCSprite *background = [CCSprite spriteWithFile:#"MainMenu-iPad.png"];
[background setPosition:ccp(screenSize.width/2,screenSize.height/2)];
[self addChild:background];
[self displayMainMenu];
} else {
CCSprite *background = [CCSprite spriteWithFile:#"MainMenu.png"];
[background setPosition:ccp(screenSize.width/2,screenSize.height/2)];
[self addChild:background];
[self displayMainMenu];
}
-
It works fine on the simulator though...
Print screen position, if position is wrong then put you code in onEnter instead of init.
See this thread in Stack overflow.
-(id)init {
if( (self=[super initWithColor:ccc4(255,255,255,255)]) ) {
}
return self;
}
-(void)onEnter {
[super onEnter];
[[GameManager sharedGameManager] playBackgroundTrack:BACKGROUND_TRACK_MAIN_MENU];
CGSize screenSize = [CCDirector sharedDirector].winSize;
CCSprite *background = [CCSprite spriteWithFile:#"MainMenu.png"];
[background setPosition:ccp(screenSize.width/2,screenSize.height/2)];
[self addChild:background];
[self displayMainMenu];
}
The image was apparently being cached even after clean and build! I ended up replacing the image by removing the original and adding the same one but with some markers just to make sure it got replaced.
I have a sprite that I am rotating on a menu screen in my Cocos2d game like this:
CCAction* action = [CCRepeatForever actionWithAction:
[CCRotateBy actionWithDuration:1.0 angle:90.0f]];
[sprite runAction:action];
The problem occurs when I send the game to the background, and then resume the game. If the send to background / resume operation is quick there is a slight glitch. The longer the game stays in the background, the longer the sprite will "twitch" when the game resumes, before it will begin rotating normally again. I am on Cocos2d 2.0, Xcode 4.5, running on iOS 6.
Edit: Good point Gangcil! Here is what I had (it was, I believe, from the Cocos2d boilerplate:
// getting a call, pause the game
-(void) applicationWillResignActive:(UIApplication *)application
{
if( [_navController visibleViewController] == _director )
[_director pause];
}
// call got rejected
-(void) applicationDidBecomeActive:(UIApplication *)application
{
if( [_navController visibleViewController] == _director )
[_director resume];
}
I was able to get the problem to go away by changing these functions to:
// getting a call, pause the game
-(void) applicationWillResignActive:(UIApplication *)application
{
if( [_navController visibleViewController] == _director )
{
[_director stopAnimation];
[_director pause];
}
}
// call got rejected
-(void) applicationDidBecomeActive:(UIApplication *)application
{
if( [_navController visibleViewController] == _director )
{
[_director stopAnimation];
[_director resume];
[_director startAnimation];
}
}
I am not sure if this was the correct approach or not - there is a slight hesitation at first (understandably), but then the animation commences smoothly. The slight hesitation is better than the wild jittering that I saw before - but I don't know if this solution can be improved on.
How does one move the background image in a timer using cocos2d.
-(void) update:(ccTime)delta
What would be set in this method to move the background only on its y axis? I would like to scroll the map/background downwards as if the player is moving upwards.
I would like to then call this update method somehow every second or so.
-(void)update:(ccTime)delta
{
backgrd.position = ccp(backgrd.position.x,backgrd.position.y-10);
}
In your init:
-(id)init
{
self = [super init];
if(self)
{
//init your backgrd and stuff..
[self schedule:#selector(update:) interval: 1.0];
}
return self;
}
I need make active background which consists of 2 CCSprites which moves successive. But at the same time between CCSprites appear a little interval. How fix it?
Some init code:
sprite1 = [sprites objectAtIndex:0];
[sprite2 setPosition:ccp(240.0,self.position.y)];
sprite2 = [sprites objectAtIndex:1];
[sprite2 setPosition:ccp(720.0,self.position.y)];
[self addChild:sprite1 z:0];
[self addChild:sprite2 z:1];
[self schedule:#selector(update) interval:1/60.0];
This is the code, which move sprites:
-(void)update{
if (sprite1.position.x<=-239.0) {
[sprite1 setPosition:ccp(720.0,self.position.y)];
flag = false;
}else{
if (sprite2.position.x<=-239.0) {
[sprite2 setPosition:ccp(720.0,self.position.y)];
flag = true;
}
}
if (sprite1.position.x<=720.0) {
if (flag) {
[sprite1 setPosition:ccp(sprite1.position.x-speed, self.position.y)];
[sprite2 setPosition:ccp(sprite1.position.x+480, self.position.y)];
}else {
[sprite2 setPosition:ccp(sprite2.position.x-speed, self.position.y)];
[sprite1 setPosition:ccp(sprite2.position.x+480, self.position.y)];
}
}
}
Interval : image
If the gap is just one pixel, it's likely this is just the way OpenGL/Cocos2D behaves.
Instead of making your images 480x320, make them 482x320, and make them overlap with those extra pixels. Then the gap will be gone.