Обнаружение Столкновений Jmonkey


Я новичок в программировании Jmonkey, и я хотел бы задать вопрос о взаимодействии столкновений, поскольку мой код, похоже, находит столкновения, возможно, с местностью,и я не знаю, как это решить. Моя цель-игрок как первое лицо, которое будет обнаружено, если он столкнется с призрачным контролем врага, чтобы отобразить сообщение в качестве вывода. Мой код отображает столкновение continues, а затем аварийно завершает работу...

package test;

//imports...

public class test extends SimpleApplication
implements ActionListener,PhysicsTickListener{
    private MotionPath path;
    private MotionPath path2;
    private MotionTrack motionTrack;
    private MotionTrack motionTrack2;
    private AnimChannel channel2;
    private AnimControl control2;
    private AnimControl control3;
    private AnimChannel channel3;
    private BulletAppState bulletAppState;
    private RigidBodyControl landscape;
    private CharacterControl player;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
    private TerrainQuad terrain;
    private Material mat_terrain;
    private GhostControl ghost;
    static test app;
    Material matMarker;
    public static void main(String[] args) {
        app = new test();
        app.start();

    }
    float displacement=60;
    int score = 0;
    int robotHealth=0;
    Geometry mark;
    Node shootables;
    Node pickUpObject1;
    BitmapText hudText;
    @Override
    public void simpleInitApp() {

        createScene();
        enemies();
        pickUptype1();
        initCrossHairs(); // a "+" in the middle of the screen to help aiming
        initKeys();       // load custom key mappings
        initMark();       // a red sphere to mark the hit



        hudText = new BitmapText(guiFont, false);
        hudText.setSize(guiFont.getCharSet().getRenderedSize());      // font size
        hudText.setColor(ColorRGBA.Red);                             // font color

        hudText.setLocalTranslation(600, 700, 0); // position
        guiNode.attachChild(hudText);


        DirectionalLight sun2 = new DirectionalLight();
        sun2.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        int width = settings.getWidth();           //width is the width of the gui
        int height = settings.getHeight();         //height is the height of the gui
    }


    protected Geometry makeCube(String name, float x, float y, float z) {
        Box box = new Box(new Vector3f(x, y, z), 3f, 3f, 3f);
        Geometry cube = new Geometry(name, box);

        Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        Texture tex_ml = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
        mat1.setTexture("ColorMap", tex_ml);
        cube.setMaterial(mat1);

        return cube;
    }

    private PhysicsSpace getPhysicsSpace() {
        return bulletAppState.getPhysicsSpace();
    }

    /**
    * This is the main event loop--walking happens here.
    * We check in which direction the player is walking by interpreting
    * the camera direction forward (camDir) and to the side (camLeft).
    * The setWalkDirection() command is what lets a physics-controlled player walk.
    * We also make sure here that the camera moves with player.
    */
    @Override
    public void simpleUpdate(float tpf) {
        hudText.setText("SCORE n" + "    " + score);// the text
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left)  { walkDirection.addLocal(camLeft); }
        if (right) { walkDirection.addLocal(camLeft.negate()); }
        if (up)    { walkDirection.addLocal(camDir); }
        if (down)  { walkDirection.addLocal(camDir.negate()); }


        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());
        path.setCycle(true); // Make path a complete circuit
        path2.setCycle(true);
        motionTrack.setLoopMode(LoopMode.Loop);
        motionTrack2.setLoopMode(LoopMode.Loop);

    }

    public Node robot(){

        Node monster = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
        monster.scale(1.5f, 1.5f, 1.5f);
        monster.rotate(0.0f, -3.0f, 0.0f);
        // Create a appropriate physical shape for it

        return monster;
    }


    public void createScene(){

        /** Set up Physics */
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        //bulletAppState.getPhysicsSpace().enableDebug(assetManager);

        flyCam.setMoveSpeed(100);
        setUpKeys();


        terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());


        /** 6. Add physics: */
        // We set up collision detection for the scene by creating a
        // compound collision shape and a static RigidBodyControl with mass zero.*/
        CollisionShape terrainShape =
        CollisionShapeFactory.createMeshShape((Node) terrain);
        landscape = new RigidBodyControl(terrainShape, 0);
        terrain.addControl(landscape);


        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
        player = new CharacterControl(capsuleShape, 0.05f);
        player.setJumpSpeed(20);
        player.setFallSpeed(30);
        player.setGravity(30);
        player.setPhysicsLocation(new Vector3f(145f, -28f, 10f));
        player.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
        player.addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);


        setUpLight();
        rootNode.attachChild(SkyFactory.createSky( assetManager,
        "Textures/Sky/Bright/BrightSky.dds", false));
    }


    public void enemies(){

        shootables = new Node("Shootables");
        rootNode.attachChild(shootables);


        Node Robot1 = robot();
        Node Robot2 = robot();


        CapsuleCollisionShape capsule = new CapsuleCollisionShape(4f, 10f);
        RigidBodyControl robot1Cap = new RigidBodyControl(capsule, 0.01f);

        Robot1.addControl(robot1Cap);


        getPhysicsSpace().add(robot1Cap);

        bulletAppState.getPhysicsSpace().add(robot1Cap);
        bulletAppState.getPhysicsSpace().enableDebug(assetManager);

        robot1Cap.setMass(100f);
        robot1Cap.setKinematic(true);

        CapsuleCollisionShape capsule2 = new CapsuleCollisionShape(4f, 10f);
        RigidBodyControl robot2Cap = new RigidBodyControl(capsule, 0.01f);

        Robot2.addControl(robot2Cap);

        getPhysicsSpace().add(robot2Cap);

        bulletAppState.getPhysicsSpace().add(robot2Cap);
        bulletAppState.getPhysicsSpace().enableDebug(assetManager);

        robot2Cap.setMass(100f);
        robot2Cap.setKinematic(true);

        ghost = new GhostControl(
        new BoxCollisionShape(new Vector3f(8f,8f,8f)));  // a box-shaped ghost
        Robot1.addControl(ghost);

        ghost.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
        ghost.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01);


        getPhysicsSpace().add(ghost);

        getPhysicsSpace().addTickListener(this);

        control2 = Robot1.getControl(AnimControl.class);
        channel2 = control2.createChannel();
        channel2.setAnim("Walk");

        control3 = Robot2.getControl(AnimControl.class);
        channel3 = control3.createChannel();
        channel3.setAnim("Walk");
        path = new MotionPath();

        path.addWayPoint(new Vector3f(500f,-83f,3f));
        path.addWayPoint(new Vector3f(350f,-79f, 3f));
        path.enableDebugShape(assetManager,rootNode);

        // Initialize our motionTrack object
        motionTrack = new MotionTrack(Robot1, path);

        motionTrack.setDirectionType(MotionTrack.Direction.Path);
        // Enable the motionTrack
        motionTrack.setEnabled(true);


        path2 = new MotionPath();



        path2.addWayPoint(new Vector3f(180f,-50f,-100f));
        path2.addWayPoint(new Vector3f(200f, -55f, -30f));
        path2.enableDebugShape(assetManager,rootNode);

        // Initialize our motionTrack object
        motionTrack2 = new MotionTrack(Robot2, path2);
        motionTrack2.setDirectionType(MotionTrack.Direction.Path);
        // Enable the motionTrack
        motionTrack2.setEnabled(true);

        shootables.attachChild(Robot1);
        shootables.attachChild(Robot2);


    }

    public void physicsTick(PhysicsSpace space, float f) {
        if (ghost.getOverlappingObjects().size() > 0) {
            final Vector3f bPoint = ghost.getPhysicsLocation();
            try {
                app.enqueue(new Callable<Boolean>() {
                    public Boolean call() throws Exception {
                        app.addMarker(bPoint);
                        return true;
                    }
                });
            } catch (Exception ex) {
            }
        }
    }


    public void pickUptype1(){
        pickUpObject1 = new Node("pickUpObject1");
        rootNode.attachChild(pickUpObject1);


        Node cube1 = new Node();
        cube1.attachChild(makeCube("the Deputy", 220f, -63f, -150f));
        Node cube2 = new Node();
        cube2.attachChild(makeCube("the Deputy2", 410f, -89f, -270f));


        RigidBodyControl floor_phy = new RigidBodyControl(0.0f);
        cube1.addControl(floor_phy);

        RigidBodyControl floor_phy2 = new RigidBodyControl(0.0f);
        cube2.addControl(floor_phy2);
        bulletAppState.getPhysicsSpace().add(floor_phy);
        bulletAppState.getPhysicsSpace().add(floor_phy2);
        pickUpObject1.attachChild(cube1);
        pickUpObject1.attachChild(cube2);
    }


}
1 2

1 ответ:

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

Вы должны использовать getOverlappingObjects (), чтобы получить список объектов, с которыми он сталкивается, а затем проверить этот список на представление символов в физическом пространстве.

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

public Boolean call() throws Exception

Также плохо спроектирована функция ваших врагов. Функции предпочтительно должны быть небольшими и определенно должны выполнять только одну цель, в то время как ваша функция создает узел с перестрелками, создает двух врагов и настраивает элементы управления.

Создание узла и присоединение его к корневому узлу должно быть в конструкторе или инициализировать функцию, которая вызывается рядом с началом. А потом ты ... должна быть функция, называемая чем-то вроде addEnemy, которая добавляет одного врага. Например:

/*
* adds an enemy and returns a reference to that enemy
*/
Spatial addEnemy()
{
    //Characters are spatials typically in JMonkey
    Spatial enemy=new Spatial(); 
    CapsuleCollisionShape collisionShape=new CapsuleCollisionShape(4.0f, 10.0f);
    CharacterControl characterControl = new CharacterControl(collisionShape, stepHeight);

    enemy.addControl(characterControl);
    getPhysicsSpaceState(characterControl);
    shootables.attachChild(enemy);
}

Теперь вы заметили, что это действительно по-другому, не так ли?

Ну в Jmonkey символы используют пространственные объекты (класс, производный от node), а также они не используют физику твердого тела, такие вещи, как рельеф слишком ухабистый, вместо этого они используют элементы управления символами, и они держат их вертикально, чтобы они не опрокидывались и позволяли вам задавать направление ходьбы и направление обзора. Управление персонажем также дает доступ к форме столкновения, которую вы можете запустить, сталкивается с on, чтобы получить, когда элементы управления символов сталкиваются друг с другом.

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

У игрока есть:

CharacterControl
//to send keyboard input to the character controller to move it
KeyboardControl 
GunControl

Тогда как ИИ имеет

CharacterControl
//does path planning to get a route and steers character control along it
RouteController  
GunControl
//AI to determine where/if I want to walk, what to shoot at, where to aim
BehaviourControl

Вы должны много делить чтобы упростить его обслуживание, изучите больше о том, как работает API JMonkey, посмотрев на примеры, а также изучите, как работает объектно-ориентированный дизайн и как структурировать вещи, чтобы их было легко читать и легко поддерживать. Если вам интересно, книга clean code by Robert C Martin-это отличное руководство по чистому поддерживаемому стилю кодирования:)

Любые вопросы, не стесняйтесь задавать