Застрял, пытаясь реализовать прикосновение и удержание (пуля)? - cocos2d-x

0

У меня возникли проблемы с реализацией плавного и надежного решения Touch-and-Hold для стрельбы пулями (спрайты) - даже после того, как посмотрели на решения других людей.

Решение должно переключаться между касанием, касанием, перемещением и касанием бесконечно: всегда стрелять пулями в месте касания до тех пор, пока палец не будет отпущен. На данный момент у меня много проблем с надежностью и стабильностью в каждом случае, но touchmoved, который отлично работает.

Точная проблема примерно в половине случаев, когда палец удерживается (touchBegan + scheduler), появляются пули, но исчезают через секунду, но в других случаях они отлично перемещаются к касанию - что-то удаляет их, и у меня нет большого опыта работы с планировщиками или действия, чтобы знать, что.

Heres мой код, я использовал 2 различных метода стрельбы: один запланирован для запуска каждые 0,05 секунды после touchBegan, и один срабатывает каждый раз, когда touchMoved обнаружен. TouchMoved работает отлично, но заставить его работать с ненадежным touchBegan - это проблема. Очень раздражающая часть, даже если я удаляю сенсорную часть и просто планирую спрайты, чтобы появляться и запускать запланированные действия без остановок от init, возникает такая же проблема надежности (исчезновение/удаление). Может быть, я не понимаю, как планировщики и действия играют хорошо, или, может быть, лучший способ прикосновения и удержания? Заранее благодарю за любую помощь.

bool HelloWorld::init()
{ 
... miscellaneous sprite creation
this->schedule(schedule_selector(HelloWorld::fireBullets), 0.05);   
}

void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( pTouches->anyObject() );               // get single-touch as opposed to multitouch

    touchLocation = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

    if (touchLocation.x > 400)
    {
        float dX = touchLocation.x - gun->getPosition().x;
        float dY = touchLocation.y - gun->getPosition().y;

        touchAngle = atan2(dY, dX);  
        gun->setRotation(-CC_RADIANS_TO_DEGREES(touchAngle));

        cursor->setPosition(touchLocation);

        screenHeld = true;
    }
}

void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( pTouches->anyObject() );               // for single-touch as opposed to multitouch

    touchLocation = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

    if (touchLocation.x > 400)
    {   
        float dX = touchLocation.x - gun->getPosition().x;
        float dY = touchLocation.y - gun->getPosition().y;

        float angle = atan2(dY, dX);  
        gun->setRotation(-CC_RADIANS_TO_DEGREES(angle));

        cursor->setPosition(touchLocation);

        screenHeld = false; //not technically true but touchMoved bullet firing works differently (not scheduled, every movement instead)

        if (getTimeTick() - lastBulletFire > 50) //getTickTime is simple get system time method, works fine
        {
            fireBullet(angle);
        }
    }
}

//this is for touchBegan and has issues, scheduled to run every 50ms touch-held
void HelloWorld::fireBullets(CCTime dt) 
{
  if (screenHeld)
  {
    CCSprite* bullet = CCSprite::create("bullet.png");
    bullet->setPosition(ccp(gun->getPosition().x, gun->getPosition().y));
    bullet->setRotation(-CC_RADIANS_TO_DEGREES(touchAngle));

    //send bullet towards touchlocation
    bullet->runAction(CCSequence::create(CCMoveBy::create(1.5f, ccp(800 * cos(touchAngle), 800 * sin(touchAngle))), NULL));

    this->addChild(bullet, 5);
  }
}


//this is for touchMoved and works fine, everytime finger is moved bullet fired
void HelloWorld::fireBullet(float angle) 
{
  CCSprite* bullet = CCSprite::create("bullet.png");
  bullet->setPosition(ccp(gun->getPosition().x, gun->getPosition().y)); //add a random spread to the y value (or maybe the y-value of the destination)
  this->addChild(bullet, 5);

  bullet->setRotation(-CC_RADIANS_TO_DEGREES(angle));

  bullet->runAction(CCSequence::create(CCMoveBy::create(1.5f, ccp(800 * cos(angle), 800 * sin(angle))), NULL));

  lastBulletFire = getTimeTick();
}
  • 0
    почему тэг андроид?
  • 0
    Потому что cocos2d-x является мультиплатформенным и я разрабатываю на телефоне Android
Показать ещё 1 комментарий
Теги:
cocos2d-x

1 ответ

0

Найденное решение, оно не имело ничего общего с действиями/планировщиками, но тот факт, что я не вызывал keep() на пули. Обычно я управлял памятью C++ вручную, но этот гибридный стиль отбрасывал меня

Ещё вопросы

Сообщество Overcoder
Наверх
Меню