Как мне добиться правильной траектории с узлом Cocos2d-x, используя 2D-импульсы Бурундука и вращение?

Я создаю игру с Cocos2d-x версии 3.13.1, и я решил использовать встроенный физический движок (Chipmunk 2D) для анимации и обнаружения столкновений. У меня есть простой снаряд под названием BulletUnit что наследует от cocos2d::Node, У него есть дочерний спрайт, который отображает иллюстрацию, и прямоугольное физическое тело с теми же размерами, что и у иллюстрации.

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

bool BulletUnit::init() {
if (!Unit::init()) return false;

displaySprite_ = Sprite::createWithSpriteFrameName(frameName_);
this->addChild(displaySprite_);

auto physicsBody = PhysicsBody::createBox(displaySprite_->getContentSize());
physicsBody->setCollisionBitmask(0);
this->setPhysicsBody(physicsBody);

return true;
}

void BulletUnit::update(float dt) {
auto mass = this->getPhysicsBody()->getMass();
this->getPhysicsBody()->applyImpulse({
acceleration_ * mass * cosf(angle_),
acceleration_ * mass * sinf(angle_)
});
}

void BulletUnit::fireAtPoint(const Point &point) {
angle_ = Trig::angleBetweenPoints(this->getPosition(), point);

auto physicsBody = this->getPhysicsBody();
physicsBody->setVelocityLimit(maxSpeed_);
physicsBody->setVelocity({
startingSpeed_ * cosf(angle_),
startingSpeed_ * sinf(angle_)
});
}

Это работает именно так, как я хочу. Вы можете видеть на изображении ниже, мои пули ускоряются, как планировалось, и движутся прямо к моим щелчкам мыши.

Физическое тело без вращения.

Но есть один очевидный недостаток: пуля остается плоской, а не вращается, чтобы «указать» на цель. Итак, я настраиваю fireAtPoint применить вращение к узлу. Вот обновленный метод:

void BulletUnit::fireAtPoint(const Point &point) {
angle_ = Trig::angleBetweenPoints(this->getPosition(), point);

// This rotates the node to make it point towards the target
this->setRotation(angle_ * -180.0f/M_PI);

auto physicsBody = this->getPhysicsBody();
physicsBody->setVelocityLimit(maxSpeed_);
physicsBody->setVelocity({
startingSpeed_ * cosf(angle_),
startingSpeed_ * sinf(angle_)
});
}

Это почти работает. Пуля указывает в правильном направлении, но траектория теперь далека и, кажется, в результате вращения отклоняется от цели: чем резче вращение, тем сильнее искрение. На следующем рисунке показано, что происходит:

Физическое тело с вращением, которое портит мою траекторию!

Итак, кажется, что установка поворота заставляет физический движок вести себя так, как я изначально не ожидал. Я ломал голову над путями исправления траектории полета, но пока не повезло! Любые предложения будут с благодарностью. Спасибо!

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …