Создание оружия ближнего боя в Box2D (libGDX)

10

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

Я представляю две разные атаки (удар и удар)

Я попытался создать два приспособления (персонаж + оружие), два разных тела, два разных тела + вращающееся соединение, но я не могу закодировать его так, чтобы он вел себя так, как я себе представляю. мое воображение

STAB:

Таким образом, при нажатии кнопки тело / прибор (датчик) выходил бы на ~ 1 секунду и затем исчезал (в качестве альтернативы, тело / прибор всегда мог находиться на герое и просто поворачиваться на 90 градусов вокруг вершин при нажатии, и потом вернись в нормальное состояние)

SWING:

То же самое, но теперь оружие будет начинаться сверху и качаться вниз. Оружие также будет сенсором.

Что я пробовал:

Я создал два динамических тела.

Оружие должно следовать за героем, поэтому я использовал вращающийся сустав, чтобы удержать их вместе. Когда клавиша нажата, я устанавливаю угловую скорость оружия на число. Однако оружие продолжит вращаться после того, как я отпущу ключ. Я попытался реализовать проверку if (если угол больше ___, установить угловую скорость на ноль). Однако это просто означает, что оружие перестанет вращаться, когда я нажму клавишу во второй раз.

услуга за услугу
источник
Поскольку вы уже сделали тела / приспособления в форме прямоугольника, вам просто нужно повернуть тело меча на 90 градусов вправо для анимации свинга. Также вам нужно отключить столкновения тела меча, когда анимация не происходит, и не рисовать его на экране. Анимация удара - это просто более простая версия свинга, где меч имеет другой начальный угол. Разве это не правильно? Кажется довольно просто для меня. Где ты застрял?
dimitris93
Проблема в том, что меч и герой пересекаются? может быть, маленькое квадратное тело могло быть кончиком меча, чтобы оно никогда не перекрывалось. возможно отредактируйте для получения дополнительной информации
drumbumLOLcatz
@ Широ Я включил свои попытки внизу. Прямо сейчас я застрял, потому что я не знаю, как начать и остановить вращение одним нажатием клавиши.
quidproquo
Да, похоже, что ваш настоящий вопрос заключается в том, как вращать объект при нажатии клавиши
dimitris93

Ответы:

1

Кстати, я сделал именно то, что вы пытаетесь сделать. Единственная загвоздка в том, что я использовал Jbox2d, поэтому код написан на Java, но вы все равно сможете понять это, если используете C ++.

В основном вам нужно использовать суставы / моторы и все эти забавные вещи, если вы хотите заниматься качанием. Вот фрагмент того, как мой код выглядит на основе ввода ключа:

    if (myinput.mouse0) {

        agents.get(0).rightForeJoint.enableMotor(true);
        agents.get(0).rightArmJoint.enableMotor(false);    

        if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
            agents.get(0).rightForeJoint.enableMotor(false);
        }

        mouseY = Mouse.getY();
        mouseX = Mouse.getX();
        float temp = mouseY - prevPos[1];

        float temp2 = -mouseX + prevPos[0];

        temp2 *= modifier; temp2 *= 0.000026;
        temp  *= modifier; temp  *= 0.000030;

        agents.get(0).armR.applyAngularImpulse(-temp);
        agents.get(0).foreR.applyAngularImpulse(temp2); 

        prevPos[1] = mouseY;
        prevPos[0] = mouseX;

        if(temp2 < 0){
            temp2 *=-1;
        }
        if(temp < 0){
            temp *=-1;
        }
        fatigueDrain += temp2;
        fatigueDrain += temp;

    }

А затем, что касается создания оружия и тому подобного, фрагмент выглядит следующим образом.

    // RIGHTARM //
    this.rightArmDef = new RevoluteJointDef();
        this.rightArmDef.bodyA = this.torso ; this.rightArmDef.bodyB = this.armR;
        this.rightArmDef.collideConnected = false;

        torso_armL_pin = new Vec2(0.50f, +0.05f);
        local_armL_pin = new Vec2(0.14f, 0.14f);

        this.rightArmDef.localAnchorA.set(this.torso.getLocalCenter().add(torso_armL_pin));
        this.rightArmDef.localAnchorB.set(this.armR.getLocalCenter().add(local_armL_pin));

        this.rightArmDef.enableMotor = true;
        this.rightArmDef.motorSpeed = 0f;
        this.rightArmDef.maxMotorTorque =10f;

        this.rightArmDef.enableLimit = true;
        this.rightArmDef.lowerAngle = 1.2f;// * DEGTORAD;
        this.rightArmDef.upperAngle = 5;
    this.rightArmJoint = (RevoluteJoint)world.createJoint(this.rightArmDef);

Я понимаю, что здесь много чего происходит, но, вероятно, будет проще, если вы просто спросите меня, что вам нужно, и я объясню это. Если вы никогда не использовали ничего из этого, вам, вероятно, придется немного почитать.

EDIT >>

Поймите, Box2d имеет все обнаружение столкновений и физику, встроенную в свои библиотеки. Примите это к сведению, когда я говорю, что легче понять их систему, чем пытаться делать все с нуля. Если вы хотите столкновения, вы используете приборы bodydefs, если вы хотите, чтобы они вращались или двигались, вы используете суставы. Поначалу это может показаться немного сложнее, но, в конце концов, это экономит вам бесконечно больше времени на использование их методов.

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

bigcodeszzer
источник
0

Я нашел какой-то обходной путь, но я не уверен, что это хороший способ кодирования.

Когда клавиша нажата, я устанавливаю угловую скорость на 10, а затем при каждом обновлении прошу ее проверить

    if(weapon.getAngle() >= Math.PI / 2) {
        weapon.setAngularVelocity(-10);
    }
    if(weapon.getAngle() <= 0) {
        weapon.setAngularVelocity(0);
    }
услуга за услугу
источник
Внутри if(weapon.getAngle() <= 0)вы также должны вручную поставить его под конкретный угол, который вы хотите, иначе он не будет точным, и вам нужно if-elseутверждение вместо if-if. Все сводится к базовому Java-кодированию, которое не очень связано с конкретной игровой проблемой.
dimitris93
0

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

Если это так, вы можете переместить его в оператор «else» после кода, который проверяет, нажата ли клавиша.

стрекоза
источник
0

Одна вещь, которую вы могли бы сделать, - это команда, запустив метод, который создаст тело относительно позиции основного тела, используя body.getPosition.set (); установите биты фильтра, чтобы они не сталкивались, затем установите линейную скорость или приложите силу, независимо от того, что вы хотите, чтобы переместить его вперед после запуска таймера, чтобы уничтожить после x количества игровых циклов.

Или вы могли бы сделать то же самое, но вместо этого создать дистанционное соединение, объединенное с призматическим соединением только вдоль оси x, чтобы сделать внезапное движение выталкивания с соединенным столкновением ложным, чтобы он не сталкивался с основным корпусом, эта опция вероятно, работать лучше,

для атаки свингом создайте похожее тело, повернутое на половину числа пи с помощью только кончика меча, соединенного с основным корпусом, со столкновением, равным ложному, конечно, тогда вы можете приложить двигательную силу к суставу угловым импульсом к телу меча уничтожение его после достижения заданного вращения тела или наступления определенного времени,

если требуется дополнительная помощь, просто прокомментируйте ниже

Youseflapod
источник