Что ж, я получил отличную книгу по Cocos2d, написанную Родом Строго и Рэем Вендерлихом под названием «Изучение Cocos2d».В своей книге они реализуют игру, в которой реализован джойстик и все, используя вашу первоначальную настройку.GamePlayLayer содержит как джойстик, так и спрайт героя.(См. Стр. 40).
Я не верю, что они использовали бы плохие практики в своей книге, учитывая, что они очень талантливы!
...
С этимПри этом у меня есть возможные решения, если вы хотите реализовать их на отдельных уровнях:
GameScene
|
|__>GameLayer
|
|__>ControlLayer
Это ваша основная установка.Но, интуитивно, какова цель уровня управления?Управляйте содержанием игрового слоя!Итак, я бы посоветовал вам иметь (слабую) ссылку на GameLayer в ControlLayer.Таким образом, используя простое:
@property (nonatomic, assign) CCSprite* hero;
, теперь у вас есть доступ к герою из ControlLayer!
Дополнительно (при необходимости):
//GameScene init:
- (id)init {
....
gameLayer = [GameLayer node];
controlLayer = [ControlLayer node];
[controlLayer setGameLayerRef:gameLayer];
...
}
// Control layer:
@property (nonatomic, assign) GameLayer* gameLayerRef;
Даже еслиЯ просто предложил этот способ, я не использую его в своих играх:)
Что я обычно делаю, это:
Сделайте класс GameScene «Полу-синглтоном».(Я изучил этот метод из «Изучения iPhone и iPad Game Dev» Иттерхайма (он же игровой ужас, издатель Kobold2d и т. Д.).
Затем внутри слоя управления я бы вызвал объект GameScene:
[[GameScene sharedScene] doSomethingToTheGameLayer];
Да, у gameScene есть упрощенные методы, которые просто зависят от того, что нужно обновить элемент управления в игровом слое.
Редактировать:
Реализация модели полу-синглтона, как описано Иттерхеймом в его книге.
Но что такое полу-синглтон?
Он имеет свойство одноэлементного шаблона: вы можете получить доступ к экземпляру объекта из любого места, используя статический вызов.
[GameScene sharedScene];
Однако одноэлементные объекты обычно сохраняются после первого создания до концажизни приложения.В шаблоне Semi-singleton это не так.
После создания экземпляра вы не можете создать другой экземпляр до того, как уничтожите старый, НО, как только вы закончите с экземпляром, вы уничтожитеэто (dealloc) .Создание другого при необходимости.
Резюме: Полу-синглтон: Создайте из него много объектов, но только один в любой момент времени.Воссоздавать только после уничтожения старого.
Реализация:
Конечно, как и в случае с любым одноэлементным классом, вы сначала объявляете статическую переменную того же типа, что икласс:
//In GameScene.m
static GameScene* instance = nil;
@implementation
//Here we have the static method to access the instance:
+(GameScene*)sharedScene {
//you must have created one before trying to access it "Globally".
///Typically, created where you transition the GameScene using CCDirector's replaceScene.
NSAssert(instance != nil, @"GameScene not instantiated!!");
return instance;
}
-(id)init {
if((self = [super init])) {
//Make sure you don't have another instance of the class created
//NOTE: Possible race condition that I wouldn't worry about, since it should never happen.
NSAssert(instance == nil, @"Another instance is already created!!");
instance = self;
...
}
return self;
}
//Don't forget!! Dealloc!!
- (void)dealloc {
//the only instance we had is dealloc'd! We are back to zero. Can create a new one later! :D
instance = nil;
[super dealloc];
}
Edit2:
Итак, график времени:
CCScene* scene = [GameScene node];
[[CCDirector sharedDirector] replaceScene:scene];
...
[[GameScene sharedScene] doSomething];
...
[[CCDirector sharedDirector] replaceScene:otherScene];
//After the new scene replaces GameScene, dealloc will be called, implicitly. Making instance = nil;
instance = nil;
[super dealloc];
...
//Loop again
CCScene* scene = [GameScene node];
[[CCDirector sharedDirector] replaceScene:scene];
...