Cocos2D + Storyboards,实现Play Again功能并重新加载游戏场景
Posted
技术标签:
【中文标题】Cocos2D + Storyboards,实现Play Again功能并重新加载游戏场景【英文标题】:Cocos2D + Storyboards, implement Play Again feature and reload the game scene 【发布时间】:2014-05-20 10:22:05 【问题描述】:我在一个故事板项目中集成了一个 Cocos2d 游戏。下面是故事板。当游戏结束时(onExit
方法),我向CocosViewController
发送通知并从那里执行segue,打开ScoreViewController
。这工作正常。此外,当用户按下ScoreViewController
中的“再次播放” 按钮时,我想再次加载游戏。
我尝试了一个 unwind segue,它打开了CocosViewController
,但它没有加载游戏,它立即返回到ScoreViewController
。如何实现 Play Again 功能?也许有一个segue?
CocosViewController
-(void)setupCocos2d
CCDirector *director = [CCDirector sharedDirector];
//[[[self navigationController] navigationBar] setHidden:YES];
if([director isViewLoaded] == NO)
// Create the OpenGL view that Cocos2D will render to.
CCGLView *glView = [CCGLView viewWithFrame:self.view.bounds
pixelFormat:kEAGLColorFormatRGB565
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
// Assign the view to the director.
director.view = glView;
// Initialize other director settings.
[director setAnimationInterval:1.0f/60.0f];
[director enableRetinaDisplay:YES];
// Set the view controller as the director's delegate, so we can respond to certain events.
director.delegate = self;
// Add the director as a child view controller of this view controller.
[self addChildViewController:director];
// Add the director's OpenGL view as a subview so we can see it.
[self.view addSubview:director.view];
[self.view sendSubviewToBack:director.view];
// Finish up our view controller containment responsibilities.
[director didMoveToParentViewController:self];
// Run whatever scene we'd like to run here.
NSArray *parameters = [[NSArray alloc] initWithObjects:@"3", @"sound", @"countdown", nil];
if(director.runningScene)
[director replaceScene:[IntroLayer sceneWithParameters:parameters]];
else
[director pushScene:[IntroLayer sceneWithParameters:parameters]];
-(void) viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
[self setupCocos2d];
- (void)viewDidLoad
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationFromGame:) name:@"GameEndedNotification" object:nil];
-(void)receiveNotificationFromGame:(NSNotification *) notification
if ([[notification name] isEqualToString:@"GameEndedNotification"])
NSLog (@"Successfully received the test notification! %@", [self class]);
NSLog(@"score: %d", [notification.userInfo[@"score"] intValue]);
//get variables
score = [notification.userInfo[@"score"] intValue];
gameTracking = notification.userInfo[@"gameTracking"];
//show the next view
[self performSegueWithIdentifier:@"sg_showScore" sender:self];
- (IBAction)unwindToCocosViewController:(UIStoryboardSegue *)sender
//nothing goes there
这就是我初始化 cocos2d 游戏的方式:
-(id) initWithParameters:(NSArray *) parameters
NSLog(@"init TheButton with parameters");
// Apple recommend assigning self with supers return value
self = [super init];
if (!self) return(nil);
gameParameters = parameters;
// Enable touch handling on scene node
[self setIsTouchEnabled:YES];
// Create a colored background (Dark Grey)
//CCNodeColor *background = [CCNodeColor nodeWithColor:[CCColor colorWithRed:0.6f green:0.6f blue:0.6f alpha:1.0f]];
//[self addChild:background];
CCMenuItem *starMenuItem = [CCMenuItemImage
itemFromNormalImage:@"ButtonStar.png" selectedImage:@"ButtonStarSel.png"
target:self selector:@selector(increasePoints:)];
CGSize size = [[CCDirector sharedDirector] winSize];
starMenuItem.anchorPoint = ccp(0.5f,0.5f);
starMenuItem.position = ccp(size.width/2, size.height/2);
CCMenu *starMenu = [CCMenu menuWithItems:starMenuItem, nil];
starMenu.position = CGPointZero;
[self addChild:starMenu];
timeLabel = [CCLabelTTF labelWithString:@"0.00" fontName:@"Arial" fontSize:18.0f];
//timeLabel.positionType = CCPositionTypeNormalized;
timeLabel.position = ccp(30,size.height-10);
// Add the time label
[self addChild:timeLabel];
NSLog(@"time: %@", [gameParameters objectAtIndex:0]);
clicksLabel = [CCLabelTTF labelWithString:@"0" fontName:@"Arial" fontSize:18.0f];
//clicksLabel.positionType = CCPositionTypeNormalized;
clicksLabel.position = ccp(size.width - 20,size.height-10);
// Add the time label
[self addChild:clicksLabel];
[self startGame];
return self;
-(void) startGame
clicks = 0;
myTime = [[gameParameters objectAtIndex:0] intValue];
[self schedule:@selector(update:)];
【问题讨论】:
【参考方案1】:您不需要在-setupCocos2d
中重新添加 glView,因为它已经添加了。我不确定这是否是错误行为的唯一原因,但尝试将此方法调用从viewDidAppear
到-viewDidLoad
,当从ScoreViewController
返回时,只需重置您的 Cocos2d 引擎(例如清除所有标签或移除敌人)而不重新创建视图。
但是,你的方法不是很好,我强烈建议你用 Cocos2d 制作所有场景,而不是 UIViewControllers。场景之间也有很好的过渡(至少在 Cocos2d 3.0 中)。
【讨论】:
我将方法放在 viewDidLoad 但现在场景是纵向而不是横向。另外,如何重置 Cocos2d 引擎?它加载了场景,但倒计时为 0,完成时分数相同。 @nabrugir 我所说的“重置引擎”的意思 - 将分数设置为 0,从头开始倒计时以及您在游戏开始前所做的一切。不知道为什么方向改变了。 我应该从哪里做这个?来自 cocosviewcontroller 还是来自游戏?可以举个例子吗? @nabrugir 我不知道你是如何设置分数的。在游戏开始时,您如何将倒计时和得分设置为适当的值?点击“再次播放”按钮后,您应该执行完全相同的操作 我在问题中添加了源代码。但是主要问题是我不知道如何在第二次加载游戏时调用 [self startgame],因为 onEnter 和 initWithParameters 都没有被调用。以上是关于Cocos2D + Storyboards,实现Play Again功能并重新加载游戏场景的主要内容,如果未能解决你的问题,请参考以下文章
如何在 cocos2d 环境之外实现 cocos2d 游戏的虚拟摇杆?
Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)