I created a regular simple iOS app (a single view application) with one button and I want to launch a cocos2D game from the iOS app. In other words, I want to launch the cocos2D game when I press on the button from my myapp.xib. I don't want to use URL schemes to launch the game because that will require the user to download my app as well as download the game. I want the user to be able to launch the game from my app internally. This is the game I want to launch from my app:
http://www.raywenderlich.com/14439/how-to-make-a-game-like-fruit-ninja-with-box2d-and-cocos2d-part-3
I was able to successfully add this game as a dependency in my xcode project. However, I'm not sure how to go about launching the game from app.
Here's some ideas that I had, but they didn't really work for me.
Is there any way I can:
Call the app delegate of the game (not the app delegate of my app) from the IBAction in my app to launch the game?
Call the didFinishLaunchingWithOptions method of the game (not the didFinishLaunchingWithOptions of my app) from the IBAction in my app to launch the game?
Call the main.m file of the game (not the main.m of my app) from the IBAction in my app to launch the game?
From what I understand, these are three different ways of launching an iOS app. Keep in mind that I am developing an app (not a game) that will allow a user to launch the game above internally through the app. Ideally, it would nice (and also easy) if I can simply do a pushviewcontroller from my app to the game, but I'm not sure if there is an easy way to approach this.
Is there anyway I can launch this game internally through my app? Any advice, suggestions, sample source code would be greatly appreciated.
Short answer: YES
You would need to have just one AppDelegate (the one of your iOS app), and move there all the cocos2D init stuff. Then, you can launch the game from your IBAction with something like this.-
CCDirector *director = [CCDirector sharedDirector];
[director pushScene:[YourFirstGameScene node]];
[director resume];
[self presentModalViewController:director animated:YES];
Please, take next snippet as an example to init/end cocos2d from your appDelegate
- (void) initCocos {
// Create an CCGLView with a RGB565 color buffer, and a depth buffer of 0-bits
CCGLView *glView = [CCGLView viewWithFrame:[self.window bounds]
pixelFormat:kEAGLColorFormatRGBA8 //kEAGLColorFormatRGBA8
depthFormat:0 //GL_DEPTH_COMPONENT24_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
self.director = (CCDirectorIOS*) [CCDirector sharedDirector];
self.director.wantsFullScreenLayout = YES;
// Display FSP and SPF
[self.director setDisplayStats:NO];
// set FPS at 60
[self.director setAnimationInterval:1.0/60];
// attach the openglView to the director
[self.director setView:glView];
// for rotation and other messages
[self.director setDelegate:self];
// 2D projection
[self.director setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [self.director enableRetinaDisplay:NO] )
CCLOG(#"Retina Display Not supported");
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change anytime.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// When in iPhone RetinaDisplay, iPad, iPad RetinaDisplay mode, CCFileUtils will append the "-hd", "-ipad", "-ipadhd" to all loaded files
// If the -hd, -ipad, -ipadhd files are not found, it will load the non-suffixed version
//[CCFileUtils setiPhoneRetinaDisplaySuffix:#"-hd"]; // Default on iPhone RetinaDisplay is "-hd"
[CCFileUtils setiPadSuffix:#""]; // Default on iPad is "" (empty string)
//[CCFileUtils setiPadRetinaDisplaySuffix:#"-ipadhd"]; // Default on iPad RetinaDisplay is "-ipadhd"
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
}
- (void) endCocos {
CC_DIRECTOR_END();
self.director = nil;
}
Actually, what I do is a call to initCocos just before pushing my director, and endCocos just after closing the game, like
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
[[CCDirector sharedDirector] dismissModalViewControllerAnimated:YES];
[appDelegate endCocos];
Hope it helps.
Related
Has anything changed in 5.1 which would affect how a MPMoviePlayerViewController works regarding device orientation?
I started getting reports from users today that videos were playing only in portrait mode. I figured out that they were using 5.1 and I quickly upgraded a device to recreate the situation. My code has not changed and works perfectly in 4.x, 5.0, and 5.01.
All the views in my app display in portrait mode except when a user clicks on a video, the movie player is suppose to take over the whole screen and launch into landscape more. The app using the 5.0 SDK but targeting 4.0. Here is the code I am using to display a video:
VideoPlayer *vp = [[VideoPlayer alloc] initWithContentURL:movieURL];
vp.moviePlayer.movieSourceType = src;
vp.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
vp.moviePlayer.shouldAutoplay = TRUE;
[self presentMoviePlayerViewControllerAnimated:vp];
VideoPlayer is a subclass of MPMoviePlayerViewController where the shouldAutorotateToInterfaceOrientation is overridden like so:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIDeviceOrientationLandscapeLeft);
}
This pattern is recommended all over the internet and even by Apple. I don't understand why its not working under iOS 5.1 or why more people aren't complaining about this.
Any help will be greatly appreciated.
I had the same problem also - i was playing the movie on a opengl subview, (im making an interactive ebook in landscape mode so needed my movie - (in a uiview) to play in landscape also)
I corrected this by:
subclassing the open glview to a *viewcontroller then linking that *viewcontroller to the window
So while working with cocos2d i can now use all uikit in the correct orientation.
Sending all uikit views to my subclasses opengl view. (while making sure to add in my app delegate and checking that orientation is stated in plist too.)
"#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
"#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
"#endif
hope this helps someone :) im very new at cocos2d so it took a while to figure out what i was doing wrong.
I had the same issue in iOS 5. The only way I was able to get it to work was to subclass MPMoviePlayerViewController.
#implementation MovieViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
#end
It looks you have already tried to do this, but this block of code is working for me on the device with iOS 5.1. Not sure about the simulator.
I had a bunch of orientation issues after upgrading to iOS 5.1. For me, it was because the allowed orientations of sibling viewcontrollers up the chain resulted in no allowable orientation for a modal controller I was adding.
Do you have any cases in your view hierarchy where two subviews are added to a view? I was adding two subviews to my window in applicationDidFinishLaunching, and before iOS 5.1, they could have independent allowable orientations. ie, I could have one fixed in portrait orientation while the one on top rotated. Now, the other subview insists on portrait orientation.
My solution was to force the non-rotating view below:
[self.window insertSubview:self.nonRotatingViewController.view belowSubview:self.rotatingViewController.view];
This post helped me figure that out (and has some code):
iOS: Disable Autorotation for a Subview
I know Cocos2d 2.0 is in alpha and will obviously have certain issues with it. I am trying to convert several projects to use OpenGL 2.0 for multiple reasons, but am having one very strange issue.
When I start up a scene, my textures load as desired and everything works great. I then display some Apple UI elements that allow me to quit the scene. The scene and its view controller are deallocated, the director is told to end, and I return to another view. Then I press a UIButton that launches the scene again. The scene begins again and runs, but no textures are visible. Fonts load and display, audio loads and plays, but no textures are visible. When dumping info from the CCTextureCache, I can see that the desired textures are available in the cache ( [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo] ). I have also tried clearing the cache before the scene is relaunched. No matter what, I can not see any textures or add nodes to the scene.
There could be something wrong with how I reset the scene, or how the EAGLView is setup. Here is the code for starting said scene from a View Controller:
(void)startGame {
CCDirector *director = [CCDirector sharedDirector];
EAGLView *glView = [EAGLView viewWithFrame:[self.view bounds]];
[director setOpenGLView:glView];
[self setView:glView];
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
//[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[[CCDirector sharedDirector] runWithScene:[Cocos2DChipmunkScene scene]];
}
Then, the scene is quit, and the following is called:
CCDirector *director = [CCDirector sharedDirector];
[[director openGLView] removeFromSuperview];
[director end];
The above startGame method is called again when I try to start the game again. This is the point where no textures are displayed.
Let me know if I need to provide more details on this issue.
My recommendation is to not shut down the director and keep the openGLView in the hierarchy, just set it as hidden: openGLView.hidden = YES;
You can start and stop cocos2d via [[CCDirector sharedDirector] startAnimation] respectively stopAnimation.
I am trying to play video inside a view so I can move it around, perform layout together with other views, but I can't seem to get it work to using MPMoviePlayerController. I came across this link on how to play video in portrait mode but this is not possible because the video source is coming from the web and should be playable in different platforms not only on iPhone.
I've been successful rotating the video and scaling it but it is still contained in a UIWindow which fills the whole screen. Is there a way to create an intermediate UIWindow but not visible in the current screen, so you can play the video there and probably add subviews and return everything as a UIView where I can place it anywhere? Similar to creating a CGGraphics context draw objects there and output as an image. This would also prevent the current screen from rotating from portrait to landscape.
----- 2010/06/22 06:10+08:00 ---
IN response to Jasarien's answer (below), actually it is possible to rotate and scale a video. After the video has preloaded it creates another instance of UIWindow which then becomes the keywindow at that moment. By creating a callback selector at MPMoviePlayerContentPreloadDidFinishNotification, it is possible to apply transform modification of the current keywindow.
-(void)myMovieFinishedPreloading:(NSNotification*)aNotification {
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *moviePlayerWindow = nil;
if ([windows count] > 1)
{
moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
}
CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);
transform = CGAffineTransformRotate(transform, -90.0f*M_PI/180.0f);
[moviePlayerWindow setTransform:transform];
}
Now my question is now that its part of UIWindow and since UIWindow is a UIView subclass, is it possible to subview this UIView? Also I can't seem to disable the autorotate behavior upon preloading of the video.
Video on the iPhone is played fullscreen at all times. The iPad with iOS 3.2 has APIs that allow a video to be treated as a normal view.
For the iPhone, without writing your own video view you're not going to be able to get the functionality you want.
Check out AVPlayer and AVPlayerLayer.
I'm working on an iPhone iOS4 application that incorporates playing music from the user's iPod library. I also want to keep track of what songs have been played and be able to change the song randomly, even while in the background. So I set the music player using:
[self setMusicPlayer: [MPMusicPlayerController iPodMusicPlayer]];
Now, I want this application to continue to run and play music in the background, so I have set:
Required background modes: App plays audio
The problem I'm having is that my application loses control when it is moved into the background (when applicationDidEnterBackground is called, ie. on app switches). Since I'm using the iPodMusicPlayer the music continues to play but my app does not have control and therefore can't track or change the song.
Now, the Apple documentation states that your application should continue to execute in the background using this required background modes tag, but mine does not. Is it because I'm using MPMusicPlayer? Is there any way to get around it? Any ideas?
PS. I'm also trying to get the remote locked and multitasking iPod controllers to work with my application. I'm using the code below, but remoteControlReceivedWithEvent never gets called! Does it work with MPMusicPlayer? I've only seen it with AVAudioPlayer.
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
NSLog(#"remoteControlReceivedWithEvent");
switch (event.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
NSLog(#"Play Pause");
break;
case UIEventSubtypeRemoteControlNextTrack:
NSLog(#"Next");
break;
default:
break;
}
}
- (BOOL)canBecomeFirstResponder {
NSLog(#"canBecomeFirstResponder");
return YES;
}
- (void) viewWillAppear:(BOOL)animated{
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
You are correct. Your iPhone app will not run in the background while using MPMusicPlayerController. This will also prevent you from receiving remote control events.
If you want to play audio from the iPod library and have your app continue running in the background, you must use the lower-level AVPlayer class.
I just finished my concept for an iphone app. I have a main program and in that program I want to start a game.
MAIN PROGRAM (BUTTON 1 / BUTTON 2 / START GAME)
|
|
Cocos2d Game
Is this possible? To use cocos2D in a normal "iphone app"???
Thanks so much!!!
It is definitely possible to mix UIKit with Cocos2d. Usually people accomplish this by putting their UIKit views inside a Cocos2d layer. It sounds like you want to embed the Cocos2d game inside a UIKit view instead. This should be possible, but I am unsure of the specifics involved. Try looking at -(BOOL)attachInView:(UIView *) view in CCDirector.
Note that Cocos2d uses OpenGL and there are possible performance issues when mixing OpenGL and UIKit. Pausing Cocos2d when using the other part of your application will help.
I found a vast array of great tutorials on Cocos2D for iPhone at Ray Wenderlich's site. One tutorial you might especially want to check out is
How to integrate Cocos2D and UIKit
Note: the original "Cocos2D" framework was written in Python and not designed for iOS; here's the actual homepage for the iOS port.
It is possible, but you should know that the main core of your app must be controlled by Cocos2D, that means CCDirector needs to be instantiated in AppDelegate.
Start with:
a). install Cocos2D:
Go to Terminal and write (if you save cocos2D file in desktop, if not use the path where you save it)
cd Desktop/cocos2d-iphone-1.1-beta
sudo ./install-templates.sh
and if you couldn't install try again with
./install-templates.sh -f -u
b). Import cocos2d.h inside AppDelegate
c). Declare CCDirector in applicationDidFinishLaunching method inside
AppDelegate (you should check the code for this in Cocos2D template is pretty straight
forward)
I did this in my applicationDidFinishLaunching method:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setUserInteractionEnabled:YES];
[window setMultipleTouchEnabled:YES];
CCDirector *director = [CCDirector sharedDirector];
// Create an EAGLView with a RGB8 color buffer, and a depth buffer of 24-bits
EAGLView *glView = [EAGLView viewWithFrame:[window frame]
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
[glView setMultipleTouchEnabled:YES];
// attach the openglView to the director
[director setOpenGLView:glView];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
// make the OpenGLView a child of the main window
[window addSubview:glView];
// make main window visible
[window makeKeyAndVisible];
GameScene *gs = [GameScene node];
[[CCDirector sharedDirector] runWithScene:gs];
//General is part of UIKit where I load the tabbar
General *principal;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
principal = [[General alloc] initWithNibName:#"General-iPad" bundle:nil];
} else {
principal = [[General alloc] initWithNibName:#"General" bundle:nil];
}
self.general = principal;
[principal release];
[self showUIViewController:general];
}
To push a scene from tabbar in UIKit
[[CCDirector sharedDirector] pushScene: [CCTransitionMoveInB transitionWithDuration:0.0f scene:[MyScene scene]]];
Next I recommend you to follow Ray Wenderlich's tutorial How to integrate Cocos2D and UIKit and read this post aswell how we can show UIViewController and UIView by using cocos2d? Maybe you should search for some code in the Cocos2D forums too, always help to see that.
EDIT:
1) You can download a easy example from here: UIKit Cocos2D
You could check out this framework too: Kobol2D "is an extended and improved version of the popular Cocos2D for iPhone game engine. Everything you know about Cocos2D can still be applied, and Kobold2D is easier to get started with, more convenient to use, more powerful and flexible than Cocos2D with all the documentation available online and offline. Use Kobold2D to develop iPhone, iPod touch, iPad and Mac OS X games for both Apple App Stores. And it has some examples using UIKIT and Cocos2D".
You can certainly create a game with your requirements in Cocos2D. You might want to ask some follow-up questions over at the Cocos2D forums and read through their documentation.
You can probably do this easily......
You have to only make the (UIView *) view in CCDirector.
after attaching the view.....
Yes.It is very easy and handy to implement Cocos2D with normal Iphone FrameWork.Refer Ray Wenderlich UIKit and Cocos2D Integration Tutorial here.It will helpful to you.
Yes! Is very possible, only install the Cocos2d and his templates.
Inclusive, I used Cocos2d to create simple apps with a lot of effects :)