Хотите, чтобы метка отображалась при столкновении мяча в приложениях cocos2d и box2d

Я использую _world->step(dt,5,5) для обнаружения системы столкновений. Таким образом, столкновение фактически обрабатывается классами box2d. Теперь я хочу показать счет при столкновении шаров в зависимости от того, с каким шаром он столкнулся?

Может ли кто-нибудь помочь мне с этим? Если вы, ребята, хотите, я могу предоставить исходный код функции тика, если это необходимо.

Ваша помощь приветствуется.

Спасибо,

Анкита


person Anks    schedule 15.04.2011    source источник


Ответы (4)


создайте приспособление для каждого тела и в тиковой функции проверьте столкновение...

if((contact.fixtureA == fixture1 && contact.fixtureB == fixture2) ||
(contact.fixtureA == fixture2 && contact.fixtureB == fixture1))
{
//do something
}

Надеюсь это поможет!!!!

person Anish    schedule 15.04.2011
comment
Спасибо за ответ. На самом деле коллизия уже обрабатывается внутри box2d. Мне не нужно было развиваться. Но что мне нужно, так это то, что всякий раз, когда он сталкивается, он должен показывать метку. И я не могу понять на самом деле, какая функция будет обрабатывать это. Потому что Collission.cpp — это класс box2D, а _world-›step на самом деле делает все. Имеет смысл? - person Anks; 15.04.2011
comment
Я думаю. Вы создаете тело, подобное этому fd->createFixture(body) в box2d. Назначьте это в b2Fixture.ie, приспособление1 = fd->createFixture(body). Для каждого тела вы должны назначить с помощью приспособления и метода тика. , Используйте приведенный выше код для проверки столкновения тел (здесь столкновение обнаруживается для определения того, какие два приспособления сталкиваются). - person Anish; 15.04.2011
comment
Аниш, пошаговый метод уже обрабатывает коллизии. Мне просто нужна помощь с отображением метки, чтобы показать счет с использованием пошагового метода. Это понятно? - person Anks; 15.04.2011
comment
Это не для столкновения. Это для определения того, какие два тела сталкиваются. Таким образом, вы можете увеличить свой счет на основе соответствующего столкновения тел. Очистить????? - person Anish; 16.04.2011

Сначала создайте подкласс класса C++ b2ContactListener, например:

class GamePhysicsContactListener : public b2ContactListener 
{
public:
    GamePhysicsContactListener();   
    ~GamePhysicsContactListener();  
    void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);

};

Реализуйте метод PostSolve для проверки двух соприкасающихся тел, используя:

b2Body *bodyA = contact->GetFixtureA()->GetBody();
b2Body *bodyB = contact->GetFixtureB()->GetBody();

И, наконец, создайте экземпляр слушателя, вызвав строку ниже в методе, в котором вы создаете экземпляр b2World (скорее всего, в вашем методе CCLayer init):

_world->SetContactListener(new GamePhysicsContactListener());

p/s: вместо того, чтобы выполнять логику проверки контактов в классе GamePhysicsContactListener, вы также можете заставить этот класс принимать цель и селектор, которые будут вызываться с помощью NSInvocation. Хотя это было бы немного сложнее.

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

Вот рабочая реализация GamePhysicsContactListener: https://gist.github.com/922824 (это часть мой частный фреймворк GamePhysics, объединяющий классы Cocos2D и Box2D)

person Lukman    schedule 15.04.2011
comment
@Lukman: Спасибо за ответ. На самом деле коллизия уже обрабатывается внутри box2d. Мне не нужно было развиваться. Но что мне нужно, так это то, что всякий раз, когда он сталкивается, он должен показывать метку. И я не могу понять на самом деле, какая функция будет обрабатывать это. Потому что Collission.cpp — это класс box2D, а _world-›step на самом деле делает все. Имеет смысл? - person Anks; 15.04.2011
comment
вы правы, что _world-›step уже выполняет обнаружение столкновений, но только для обработки движения тел, например. тела отражаются друг от друга. Но если вам нужно, чтобы box2d сообщил вам, какие тела на самом деле сталкиваются в определенное время, вам нужно установить прослушиватель контактов, поэтому вам нужно использовать коды, подобные тому, который я опубликовал. Вот где вы размещаете свою логику, которая может выглядеть как if (body1 == ballBody && body2 == goalBody) { [self increaseScore]; } и т. д. - person Lukman; 15.04.2011
comment
(продолжайте, потому что количество комментариев ограничено) В этом случае вам не нужно ничего помещать в метод галочки, потому что box2d будет вызывать ваш обработчик контактов, как и когда происходят коллизии. - person Lukman; 15.04.2011
comment
@Lukman: Спасибо, похоже, это должно сработать. Когда я попытался создать класс и создать прослушиватель, он выдает символ (символы), не объявленные ошибкой связывания. Есть ли у вас какие-либо идеи? - person Anks; 15.04.2011
comment
Вы реализовали класс? Потому что код, который я дал в первом блоке, — это просто объявление класса (файл .h). Вам также понадобится реализация класса (файл .mm). - person Lukman; 15.04.2011
comment
Да, я сделал. Но он по-прежнему показывает ту же ошибку, и если я скопирую его определение в файл .h, он говорит о дублирующем объявлении postsolve. Я сделал метод виртуальным, но он не работает :( - person Anks; 15.04.2011
comment
На самом деле, когда я добавляю _world-›SetContactListener(new GamePhysicsContactListener()); эта строка выдает ошибку для неопределенного символа. - person Anks; 15.04.2011
comment
Затем я попытался создать объект, он работает для создания объекта, но когда я говорю obj = new GamePhysicsContactListener(); Выдает ошибку. Любая идея? - person Anks; 15.04.2011
comment
@Lukam: я понял. Я не писал определение всей функции. Я написал это, и оно выполнилось. Но теперь это не входит в метод postSolve. Не могли бы вы помочь мне с этим? - person Anks; 15.04.2011
comment
Вы сделали _world->SetContactListener(new GamePhysicsContactListener());? Попробуйте добавить NSLog в метод PostSolve. - person Lukman; 16.04.2011
comment
@Lukam: нельзя ли использовать beginContact вместо метода PostSolve. Я распознал все коллизии в методе beginContact, и он отлично работает. Однако у меня та же проблема, что и у Анкиты. Я не могу отобразить метку при столкновении. Я объяснил это в своем ответе (скорее вопрос: D). Я также разместил аналогичный вопрос здесь. - person Nitish; 05.05.2011

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

-(void) paintCollisionImage:(CGPoint) point{

CGSize screenSize = self.view.bounds.size;

CGRect myImageRect = CGRectMake((point.x -24), ((screenSize.height - point.y) -24), 48.0f, 48.0f);

NSArray *myImages = [NSArray arrayWithObjects: 
    [UIImage imageNamed:@"collideImage0.png"], 
    [UIImage imageNamed:@"collideImage1.png"], 
                     nil];
UIImageView *myAnimatedView = [UIImageView alloc]; 

[myAnimatedView initWithFrame:myImageRect]; 
myAnimatedView.animationImages = myImages; 
myAnimatedView.animationDuration = 0.25; // seconds 
myAnimatedView.animationRepeatCount = 1; // 0 = loops forever 

[myAnimatedView startAnimating]; 
[self.view addSubview:myAnimatedView]; 
[myAnimatedView release];

}

Я называю это так:

[self paintCollisionImage:collisionPoint];
person Tony Adams    schedule 15.04.2011

Я столкнулся с той же проблемой. Я хотел отображать метку, когда игрок набирает силу. Для этого я создал статическую функцию в CCScene, которая добавляет метку на сцену. И в ContactListener я инициализировал объект сцены в методе beginContact, а затем вызвал функцию сцены.

+(void)addPointLabel  
{  
    DataClass *d5=[DataClass getInstance];  
   [_label setString:@"+10"];        // Define label in init  
    _label.color = ccc3(0,255,0);  
    _label.position = ccp(d5.playerXPosition,d5.playerYPosition);  
    [self addChild:_label];  
    d5.lbl=_label;  
    id action1 = [CCMoveTo actionWithDuration:2 position:ccp(d5.playerXPosition,d5.playerYPosition+20)];  
    id action2 = [CCFadeOut actionWithDuration:1.0f];  
    [_label runAction: [CCSequence actions:action1,action2,  nil]];    
}  

Теперь вызовите этот метод в своем классе ContactListener:

[GameScene addPointLabel];  
person Nitish    schedule 05.05.2011