реализация статического объекта на движущейся сцене

Как реализовать «меню», которое кажется застрявшим на своем месте? Здесь с застрявшим я хотел сказать, что либо scene движется, либо все еще остается на своем месте. Что дает ощущение, что он на своем месте. Я реализую это, перемещая его с помощью прокручиваемой сцены, он работает, но ведет себя нелепо, «иногда».

Вот код, как я создаю menu:

resetPosition =[CCMenuItemImage itemFromNormalImage:@"position.png"
                                      selectedImage:@"position_over.png" 
                                      disabledImage:@"disabled.png"
                                             target:self
                                           selector:@selector(reset)]; 
resetPosition.position =ccp(400, 300);
myresetMenu = [CCMenu menuWithItems:resetPosition, nil];
myresetMenu.position = ccp(0,0);
[[self parent] addChild:myresetMenu z:10];  
[resetPosition setIsEnabled:NO];

А теперь код для перемещения сцены (когда пользователь пытается прокрутить сцену). Также я переместил меню с scene, так что получается, что меню все еще с scene:

if([touchArray count]==1)//scroll
        {

            UITouch *myTouch = [touches anyObject];
            CGPoint location = [myTouch locationInView:[myTouch view]];
            moveLocation1 = [[CCDirector sharedDirector] convertToGL:location];
            float diffX = beginLocation1.x - moveLocation1.x;
            float diffY = beginLocation1.y - moveLocation1.y;   

            //NAVIGATION TOWARDS X AND Y WhenEver and how ever you want         
            if (abs(diffX) > abs(diffY))
            {
                CCLOG(@"yScrlFlag=%d",yScrlFlag);
                if(diffX > 0)
                {
                    xScrlFlag=1;
                    [self.parent runAction:[CCMoveTo actionWithDuration:round(-(-3112-self.parent.position.x)/650)
                                                               position:ccp((-3112-self.position.x),self.parent.position.y)]];
                    [resetPosition setIsEnabled:YES];
                    [resetPosition runAction:[CCMoveTo actionWithDuration:round(-(-3112-self.parent.position.x)/650) 
                                                                 position:ccp((3112+self.position.x+400),resetPosition.position.y)]];
                }
                else
                {
                    xScrlFlag=0;                        
                    [self.parent runAction:[CCMoveTo actionWithDuration:(-self.parent.position.x/650) 
                                                               position:ccp(0,self.parent.position.y)]];
                    //[resetPosition setIsEnabled:YES];
                    [resetPosition runAction:[CCMoveTo actionWithDuration:(-self.parent.position.x/650) 
                                                                 position:ccp(400,resetPosition.position.y)]];
                }
            }
            else
            {                       
                if(diffY < 0)
                {
                    yScrlFlag=1;
                    CCLOG(@"\n nodePosition.x=%f \n nodePosition.y=%f",nodePosition.x,nodePosition.y);
                    [self.parent runAction:[CCMoveTo actionWithDuration:(-(-300-self.parent.position.y)/650) 
                                                               position:ccp(self.parent.position.x,(-self.position.y))]];
                    //[self.parent runAction:[CCMoveBy actionWithDuration:(-(-300-self.parent.position.y)/650)
                    //                                         position:ccp(self.parent.position.x, -diffY)]];
                    [resetPosition setIsEnabled:YES];
                    //[resetPosition runAction:[CCMoveBy actionWithDuration:round(-(-300-self.parent.position.x)/650) 
                    //                                           position:ccp(resetPosition.position.x, (self.parent.position.y))]];
                }
                else
                {   
                    yScrlFlag=0;
                    [self.parent runAction:[CCMoveTo actionWithDuration:(-(-300-self.parent.position.y)/650) 
                                                               position:ccp(self.parent.position.x,0)]];
                    //[resetPosition runAction:[CCMoveTo actionWithDuration:round(-(-300-self.parent.position.x)/650) 
                    //                                           position:ccp(resetPosition.position.x,300)]];
                }   
            }
        }

person rptwsthi    schedule 14.06.2011    source источник


Ответы (3)


У меня были небольшие проблемы с этим некоторое время назад. Я пытался сделать так, чтобы элементы пользовательского интерфейса не терялись при перемещении камеры. В итоге я добавил CCParallaxNode в качестве дочернего элемента и установил коэффициент параллакса на ccp(0.0, 0.0) для всего, что я на него наложил. Таким образом, сцена может двигаться, но мой слой пользовательского интерфейса остается на месте. Я не уверен, что это лучший способ сделать это, но я грязный программист :)

person Aaron Goselin    schedule 16.06.2011
comment
Что бы и как бы ты ни делал, ты делал это как нельзя лучше. спасибо... :) - person rptwsthi; 16.06.2011

Вы не указываете, как вы создаете свои меню и что вы с ними делаете, поэтому мой ответ довольно общий...

Для меня правильный подход к этому — иметь слой пользовательского интерфейса, на котором вы размещаете все свои элементы пользовательского интерфейса (меню, кнопки и т. д.) и к которому вы относитесь иначе, чем к другим игровым слоям. Другими словами, вы даете своему слою пользовательского интерфейса фиксированное положение, а затем не применяете к нему никаких действий или каких-либо других преобразований. Таким образом, он должен оставаться довольно статичным.

Cocos2d предлагает свои собственные классы для управления CCMenu, CCMenuItem и CCLabel, которые позволяют легко создавать пользовательский интерфейс. Но, если хотите, вы также можете попробовать интегрировать UIKit объектов. Взгляните на CCUIViewWrapper, если вам это действительно нужно.

РЕДАКТИРОВАТЬ:

Идея наличия слоя пользовательского интерфейса заключается в следующем:

  1. у вас есть корневой слой, действующий как контейнер всех ваших слоев;

  2. один из этих слоев — это «игровой слой», который у вас сейчас почти такой же;

  3. другой - «уровень пользовательского интерфейса»;

  4. касания и любые преобразования применяются только к «слою игры», которые перемещаются внутри корневого слоя, не затрагивая «слой пользовательского интерфейса».

Об этом есть хороший учебник в статье Штеффена Иттерхейма Learn Game Development with Cocos2D. Эта книга отлично подойдет, если вы хотите изучить несколько отличных подходов к своей игре cocos2d. Учебник, о котором я говорю, доступен в виде кода на сайте Штеффена. Вы можете загрузить его с этой страницы и просмотреть главу 5 "Scene и Layers», начиная с ScenesAndLayers04, где вы найдете классы MultiLayerScene.h/m.

person sergio    schedule 14.06.2011
comment
Спасибо за ответ, пожалуйста, просмотрите код, который я упомянул в редактировании, и поскольку я перемещаю свою сцену во время прокрутки, будет ли выгодно добавлять какой-либо слой? - person rptwsthi; 14.06.2011
comment
Я отредактировал свой ответ, добавив больше деталей и ссылку на хороший учебник. - person sergio; 14.06.2011

У @sergio правильная идея.

Хотя с вашим кодом. Поместите его в слой сам по себе, а затем при касании переместите его, как вы уже есть, и просто сбросьте его положение, когда вы предпримете действие, чтобы снова открыть меню.

person Shannon    schedule 14.06.2011
comment
MMmmhhhh, то, что я делаю, близко к правильному, и поскольку menu уже используется предложение sergio также в реализации (согласно тому, что я получил его решение, поправьте меня, если я этого не сделал), но много раз это ведет себя абсурдно, это реально проблема. - person rptwsthi; 14.06.2011