I am creating a game of questions and answers for iphone using cocos2d, and I wonder how can I do to display the question on the screen using ccLabel seeking data from a plist. can someone help me with this!
What you want to do is grab it from your resources bundle, and save it into a dictionary. From there you have access to every value inside of your plist. That can be achieved with something like this:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"myList.plist"];
NSDictionary *plistData = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
Then when you're ready to display the question just use the [plistData objectForKey: ] method. Do you need help setting up the label also?
Sure man. You want to set it up like this:
CCLabel* questionLabel = [CCLabel labelWithString:#"Your Question"
fontName:#"Marker Felt" fontSize:64];
CGSize size = [[CCDirector sharedDirector] winSize];
label.position = ccp( size.width /2 , size.height/2 );
[self addChild: questionLabel];
That'll display your label in the middle of the screen. You can change the position, font, etc. The way you access your data from the plist is determined by exactly how you set it up. But using the technique I gave your earlier you shouldn't have a problem.
Related
Simply trying to test retina display. I setup the director like this:
CCDirectorIOS* director = (CCDirectorIOS*)[CCDirector sharedDirector];
director.wantsFullScreenLayout = NO;
director.projection = kCCDirectorProjection2D;
director.animationInterval = 1.0 / 60.0;
director.displayStats = YES;
[director enableRetinaDisplay:YES];
I create two versions of the file in Photoshop - outline-hd.png and outline.png. I color the HD version red so I can tell if it's being displayed.
Display code:
CCSprite *border = [CCSprite spriteWithFile:#"outline.png"];
[self addChild:border];
Yet it is the non-hd image that gets displayed on my iPhone5. Why?
I came across this question while trying to solve the exact same problem in my own project. Had to dig around in the cocos2d source to figure it out. The problem is that the director's enableRetinaDisplay:YES method doesn't work unless the director's view is set. So, it needs to be called after the glView is set up, and you've called setView on the director:
CCGLView *glView = [CCGLView viewWithFrame:aFrame
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
[[CCDirector sharedDirector] setView:glView];
NSLog(#"glView is set, enable retina...");
[[CCDirector sharedDirector] enableRetinaDisplay:YES];
This should fix the problem for you!
May be you forgot:
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO];
[sharedFileUtils setiPhoneRetinaDisplaySuffix:#"-hd"];
Can someone explain to me how cocos2d uses png as a font?
I would like to do something similar as my font only contains numbers.
if you do a global search on the string fps_images.png , your IDE should take you real close to the following lines in cocos CCDirector class (version 2.0) :
FPSLabel_ = [[CCLabelAtlas alloc] initWithString:#"00.0" charMapFile:#"fps_images.png" itemWidth:12 itemHeight:32 startCharMap:'.'];
SPFLabel_ = [[CCLabelAtlas alloc] initWithString:#"0.000" charMapFile:#"fps_images.png" itemWidth:12 itemHeight:32 startCharMap:'.'];
drawsLabel_ = [[CCLabelAtlas alloc] initWithString:#"000" charMapFile:#"fps_images.png" itemWidth:12 itemHeight:32 startCharMap:'.'];
then look up CCLabelAtlas. Your image must be for a fixed width font.
If you want to reuse the same image included to make something other than the FPS display the following code should work:
CCLabelAtlas *scoreLabel = [[CCLabelAtlas alloc] initWithString:#"00.0" charMapFile:#"fps_images.png" itemWidth:12 itemHeight:32 startCharMap:'.'];
Then to set it to the numbers you want something like this works:
[scoreLabel setString:[NSString stringWithFormat:#"%d", (int)score]];
after few headaches i figured out that using CCSpriteBatchNode with cocos2d olny allows to z-order sprites added to it as child (which is obvious, now i see..)
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"token_default.plist"];
CCSpriteBatchNode *tokenSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"token_default.png"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"objects_default.plist"];
CCSpriteBatchNode *objectsSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"objects_default.png"];
CCSprite *token = [[[CCSprite alloc] initWithSpriteFrameName:#"token_SE.png"] autorelease];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [[[CCSprite alloc] initWithSpriteFrameName:#"token_blak_SE.png"] autorelease];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [[[CCSprite alloc] initWithSpriteFrameName:#"house_small.png"] autorelease];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [[[CCSprite alloc] initWithSpriteFrameName:#"house_big.png"] autorelease];
[houseB setPosition:[self randomHousePosition]];
[tokenSpriteSheet addChild:token];
[tokenSpriteSheet addChild:enemy];
[objectsSpriteSheet addChild:houseA];
[objectsSpriteSheet addChild:houseB];
and since i have to add them to the display list as follows..
[_isoMap addChild:objectsSpriteSheet];
[_isoMap addChild:tokenSpriteSheet];
there is no way i can change the z-order of single tokens between other houses...
they will be always rendered over the house until i change the order of these batch nodes
btw, i can "merge" all sprites' arts in one big single batch node... doing so it became possible to order sprites using sprite's coordinates
[fullSpriteSheet reorderChild:token z:token.position.y];
i'm a little stuck with it...... is there a way to achieve that, having different sprite bacth nodes? or is possible to programmatically merge two batchnodes? (or something like that)
i found KnightFight, a really interesting open project on github by LozArcher.. he used CCSpriteFrame and CCSprite's setDisplayFrame method, instead of batch nodes... but i can't run it since it seems to be an older version of cocos2d (apparently not working with xcode 4)
i found out that changing the vertexZ property of a CCNode (like a CCSprite) it actually changes its Z position (so it will be slightly bigger/smaller, and also translated)
so, in order to arrange on z-index CCSprites with different spriteSheet i had to use reorderChild method (to just change the rendering order) and mostly i need NOT TO USE CCSpriteBatchNode..
after a little refactoring of the above example, i should have:
CCSprite *token = [CCSprite spriteWithSpriteFrameName:#"token_SE.png"];
[token setPosition:tokenSpawnPoint];
CCSprite *enemy = [CCSprite spriteWithSpriteFrameName:#"token_blak_SE.png"];
[enemy setPosition:enemySpawnPoint];
CCSprite *houseA = [CCSprite spriteWithSpriteFrameName:#"house_small.png"];
[houseA setPosition:[self randomHousePosition]];
CCSprite *houseB = [CCSprite spriteWithSpriteFrameName:#"house_big.png"];
[houseB setPosition:[self randomHousePosition]];
[_isoMap addChild:token];
[_isoMap addChild:enemy];
[_isoMap addChild:houseA];
[_isoMap addChild:houseB];
i also added each sprite to a NSMutableArray
and then in a for loop (inside the update scheduled method):
CCSprite *sprite = [mySpritesArray objectAtIndex:i];
[_isoMap reorderChild:sprite z:(_isoMap.mapSize.height - sprite.y)];
hope this could help someone :)
I still think that is not better solution,
if your objects on map are moving dynamically, you can still stuck in z order issues.
I know its very old post, and people keep coming here by google search,
so I am posting solution here.
float lowestZ = tilemap.map.width +tilemap.map.height ;
float currentZ = self.gridLocation.x + self.gridLocation.y ;
int zOrderDecided = lowestZ + currentZ - 1 ;
[self.parent reorderChild:self z:zOrderDecided];
Set the Sprites Z order to it's Y position on the map. Reorder your dynamic sprites in an update loop. Calculate the Z order using the Sprites current Y position and the visible height of the map.
void LocalGameController::SetZOrderForObject(cocos2d::Sprite *object){
int objectZOrder = visibleSize.height - object->getPositionY();
context->reorderChild(object, objectZOrder);
}
I have a Tabbar control (as the root control).
In the first tab, I have a split view, which I programmatically created like so:
UISplitViewController *split = [[[UISplitViewController alloc] init] autorelease];
split.navigationItem.title = #"All";
MasterSplitViewController *root = [[[MasterSplitViewController alloc] init] autorelease];
root.navigationItem.title = #"Areas";
root.detailViewController = detail;
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:root] autorelease];
split.tabBarItem = controller.tabBarItem;
split.viewControllers = [NSArray arrayWithObjects: nav, detail, nil];
split.delegate = detail;
Everything works fine, except... If I start the app in Landscape mode, then the layout breaks a bit on the Master view.
If the app starts in Portrait, then I rotate to Landscape, then it is fine.
The only scenario when it breaks is when the app starts in Landscape.
When this happens, I check the console and see this message:
Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations. BUT I am not using a two-stage rotation anywhere!!
These 2 functions are overridden:
shouldAutorotateToInterfaceOrientation and willAnimateRotationToInterfaceOrientation
Please see the attached screen shot.
http://img97.imageshack.us/i/screenshot20110405at308.png/
Please help me. Any suggestion would be greatly appreciated. Thanks very much!!
I had this problem.
Add this code to AppDelegate.m.
self.tabBarController.selectedIndex = 0;
Is it possible? I guess it is, but I can't figure it out.
So, the code for the movie thus far:
shrigString = [[NSBundle mainBundle] pathForResource:#"shrig_h264_720p" ofType:#"mov"];
shrigURL = [NSURL fileURLWithPath:shrigString];
//shrigMovie = [QTMovie movieWithFile:#"shrig_h264_720p.mov" error:nil];
shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:shrigWindow ordered:NSWindowAbove];
[shrigWindow setContentView:shrigNSView];
[shrigNSView setLayer:shrigMovieView];
shrigMovieView.frame = CGRectMake(size.width /2, size.height /2, 1024, 576);
[shrigMovie autoplay];
[shrigMovie play];
NSLog(#"shrigMovie: %#", shrigMovie);
NSLog(#"shrigMovie is: %#", QTStringFromTime([shrigMovie currentTime]));
However, I can't figure out how to ad that to my scene. This is Cocos2D for Mac btw.
In the console:
shrigMovie is: 0:00:00:00.00/2500 So I guess it's loading ok, but simply not displaying?
Any ideas would be hugely appreciated.
Thanks.
I ran into the same problem and spent quite a while trying to figure out how to solve it using QTMovie in combination with cocos2D. Eventually I gave up and started looking if there was a good existing solution to this. And voilĂ , I found VideoPlayer. Very easy to use and very lightweight, you can find it on https://github.com/psineur/CCVideoPlayer. Just be sure to copy only the necessary VideoPlayer-folder from the zip-file and don't forget the CustomVideoView.nib in the Resources folder. Add those to some lib-folder within your project, then you can start playing Video-files using those two lines:
[VideoPlayer setDelegate:self];
[VideoPlayer playMovieWithFile:#"intro.mov"];
You can then add the following delegate methods to your class
- (void) moviePlaybackFinished
{
}
- (void) movieStartsPlaying
{
}
Got it working in less than 10 minutes :)
Cheers