Я создаю игру с 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_)
});
}
Это почти работает. Пуля указывает в правильном направлении, но траектория теперь далека и, кажется, в результате вращения отклоняется от цели: чем резче вращение, тем сильнее искрение. На следующем рисунке показано, что происходит:
Итак, кажется, что установка поворота заставляет физический движок вести себя так, как я изначально не ожидал. Я ломал голову над путями исправления траектории полета, но пока не повезло! Любые предложения будут с благодарностью. Спасибо!
Задача ещё не решена.
Других решений пока нет …