问题描述
我正在使用ARC
在我的代码中(基于我强烈建议的这本书中的ShootEmUp示例)可以在此处中找到第8章中的代码.通过以下方式访问GameScene:
In my code (based on the ShootEmUp example in this book, which I highly reccomend, source code in chapter 8 available here) I often use the trick of accessing the GameScene via:
+(GameScene *)sharedGameScene;
+(GameScene*) sharedGameScene;
返回对GameScene静态实例的引用,并被GameScene的所有子级(例如ShipEntity,InputLayer等)用于与GameScene对话(aka GameScene的单个实例>).
which returns a reference to the static instance of GameScene and is used by all children of GameScene (e.g. ShipEntity, InputLayer.. etc..) to dialog with GameScene ( aka singleton instance of GameScene).
要创建多个级别,我想到了实现一个名为sceneWithId:(int)方法的方法,该方法每次都加载不同的级别数据.
To create multiple levels I thought of implementing a method calledsceneWithId:(int) method where I load different level data each time.
初始化方法的代码段:
-(id) initWithId:(int)sceneId
{
CCLOG(@"scene With id");
if ((self = [super init]))
{
//All common initialization happens here..
switch (sceneId) {
case 1:
[self loadFirstLevelData];
break;
case 2:
[self loadSecondLevelData];
break;
default:
[self loadSecondLevelData];
break;
}
//Other common stuff..
[self setUpCounters];
[self setUpWeaponsMenu];
[self scheduleUpdate];
[self schedule:@selector(timerUpdate:) interval:1];
InputLayerButtons* inputLayer = [InputLayerButtons node];
[self addChild:inputLayer z:1 tag:GameSceneLayerTagInput];
}
该初始化方法可以吗?我发现这篇文章使用dispatch_once.我应该这样做吗?
Is that init method ok? I have found this post which uses dispatch_once. Should I do the same?
还是我应该pheraps创建一个GameScene类,然后对其进行继承?
Or should I pheraps create a GameScene class and then sublcass it?
E.g. FirstGameScene : GameScene
我遵循@ LearnCocos2D的建议并使用了清理方法,并用它来停止播放单例对象音乐层(MusicLayer对象在AppDelegate中初始化,我的意思是使用它来管理"所有场景中的音乐-问题在于,如果不停止对其进行释放,它会一直播放在初始化时加载的音乐).
I have followed the advice of @LearnCocos2D and used the cleanup method, and I used it to stop a singleton object music layer to play (the MusicLayer object is initialized in AppDelegate and I meant to use it to "manage" the music across all scenes - the problem was that without stopping it in dealloc it would have kept playing the music that was loaded at init time).
-(void) loadFirstLevelData{
//HERE WILL LOAD ALL SPECIFIC ELEMENTS: ENEMIES, BONUSES etc..
//AS WELL AS THE MUSIC FOR THE LEVEL
[[MusicLayer sharedMusicLayer] _loadMusic:@"1.mp3"];
[[MusicLayer sharedMusicLayer] playBackgroundMusicFile: @"1.mp3"];
}
-(void) cleanup
{
//Should I remove all child loaded in LoadLevelData??
CCLOG(@"cleanup GameScene");
[[MusicLayer sharedMusicLayer] stopAllMusic];
//MusicLayer is not a child of GameScene but of AppDelegate - the idea is to keep loading and unloading music files - sometimes I need to keep playing the file between scenes and hence I used the singleton pattern for this as well..
[super cleanup];
}
但是我仍然有一些疑问:
But I still have some doubts:
-
在GameScene类中具有几个loadLevelData方法可以吗?每种方法可以长达200行!我试图订阅GameScene,但有点混乱.我解释得更好.我在子类的头文件中导入了"GameScene.h",通过这样做,我期望如果仅对某些方法进行ovverriden(例如init),我将能够看到在GameScene中导入的各种类(例如InputLayerButtons).事实并非如此.所以我可能不了解导入在Objective-C中的工作方式
Is it ok to have several loadLevelData methods in GameScene class? Each method can be 200 lines long! I tried to sublcass GameScene but is a bit messy. I explain better. I imported "GameScene.h" in the header file of the subclass and by doing so I expected that if I had ovverriden only certain methods (e.g. init) I would have been able to see the various classes imported in GameScene (e.g. InputLayerButtons). It is not the case. So I probably don't understand how imports work in Objective-C
可以在清理方法中删除特定的子级吗?我以为我会删除在LoadLevelXXXData方法中添加的所有子项,以减少内存使用量.
Is it ok to remove specifc children in the cleanup method? I thought that I would remove all child that are added in the LoadLevelXXXData method to reduce the memory usage.
我已经为这个问题设置了赏金,但是我可能对答案没有足够清楚的理解,因此我可能需要测试答案并重新编辑.希望还可以.
PS:如果有人希望共享一个Cocos2D Shooter Game的 UML风格图,其中具有不同的关卡和GameScene(使用单例模式:),那就太好了./p>
PS: Would be great if someone would feel like sharing a UML style diagram of a Cocos2D Shooter Game where with various levels and GameScene using singleton pattern :).
推荐答案
我将重点关注底部的问题:
I'll focus on the questions on the bottom:
- 在GameScene类中具有几个loadLevelData方法可以吗?每种方法可以长达200行!我试图订阅GameScene但有点乱.我解释得更好.我在子类的头文件,这样做,我希望如果我有ovverriden仅可以使用某些方法(例如init)请参阅在GameScene中导入的各种类(例如InputLayerButtons).事实并非如此.所以我可能不明白导入如何在Objective-C中工作
拥有长方法并没有错.但是我怀疑您的加载方法执行的例程非常相似,因此您应该检查是否可以将其概括为子例程.一个很好的指标是,除了参数或变量名外,几行代码是否完全相同.最佳做法是只编写一次相同的代码,然后使用不同的参数多次执行该代码.
There's nothing wrong with having long methods. However I suspect your loading methods perform very similar routines, so you should check if you can generalize these into subroutines. A good indicator is if several lines of code are absolutely identical except for the parameters or variable names. The best practice is to write identical code only once, and execute it many times with varying parameters.
#import
语句用于允许编译器查看"其他类.如果不导入其他头文件,就不会在没有编译器抱怨的情况下使用该类的方法和属性.
The #import
statement is used to allow the compiler to "see" other classes. Without importing other header files, you couldn't use that class' methods and properties without the compiler complaining.
在清理过程中删除孩子没有任何意义.Cocos2D会在清除过程中自动删除所有子项.
It makes no sense to remove children during cleanup. Cocos2D removes all children during cleanup automatically.
如果这似乎不是您的情况,那么您的保留周期会阻止子节点取消分配.
If that does not seem to be the case for you, you have a retain cycle somewhere that prevents child nodes from deallocating.
这篇关于Cocos2d with ARC:拥有多个关卡时,GameScene的单例模式的最佳实现是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!