【问题标题】:How to get an objects parameter with collision detection?如何通过碰撞检测获取对象参数?
【发布时间】:2013-11-28 12:45:48
【问题描述】:

我开始使用 jMonkey 开发游戏。 我刚刚从我自己制作的“实体”类中创建了一个对象,其中包含 3D 模型、物理等。 代码如下:

package mygame.entities;

import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;


public class Entity {

private AssetManager assetManager;
private Node rootNode;
public  Spatial model;
private Geometry object;
private String itsName;
private int life;
private boolean destroyAble;
private boolean destroyed;

public Entity(BulletAppState bas, AssetManager manager, Node rootNode, String name, int                                 lifes, boolean destroyable, float x, float y, float z) {
    itsName = name;
    life = lifes;
    destroyAble = destroyable;
    model = manager.loadModel("Models/woodlog.j3o");
    model.setLocalTranslation(x, y, z);
    model.setShadowMode(ShadowMode.Cast);
    model.setName(name);
    model.setUserData("lifes", 3);
    RigidBodyControl body = new RigidBodyControl(2);
    model.addControl(body);
    bas.getPhysicsSpace().add(body);
    rootNode.attachChild(model);   
}

public String getName() {
    return itsName;
}

public int getLife() {
    return life;
}

public void setLife(int lifes) {
    life = lifes;
}

public boolean isDestroyable() {
    return destroyAble;
}

public boolean isDestroyed() {
    if (destroyAble && life <= 0) {
        destroyed = true;
    } else {
        destroyed = false;
    }
    return destroyed;
  }
}

在 jMonkey 网站上的教程的帮助下,我设法实现了“射击”。 一条遵循我的凸轮方向的简单光线。以下是如果它与某物发生碰撞会发生什么的代码:

} else if (binding.equals("Fire") && !isPressed) {
    // 1. Reset results list.
    CollisionResults results = new CollisionResults();
    // 2. Aim the ray from cam loc to cam direction.
    Ray ray = new Ray(cam.getLocation(), cam.getDirection());
    // 3. Collect intersections between Ray and Shootables in results list.
    shootables.collideWith(ray, results);
    // 4. Print results.
    System.out.println(results.size());
    if (results.size() >= 1) {
      System.out.println(results.getCollision(0).getGeometry().getName());
      //Material material = results.getCollision(0).getGeometry().getMaterial();
      //material.setColor("Color", ColorRGBA.randomColor());
    }
  }

所以效果很好!这一行:

System.out.println(results.getCollision(0).getGeometry().getName());

显示我刚刚拍摄的那个“几何”的名称。但现在的问题是,我的对象不是几何体!而且我不知道如何实现我得到这个对象的名称。对我来说最好的方法是如果 results.getCollision(0) 会返回我的对象​​,所以我可以说“object.getName();”

有人知道我该怎么做吗?我将非常感谢任何想法:) 干杯 - 丹尼尔

【问题讨论】:

  • 你应该考虑修改你完全不清楚的标题。
  • 一旦你拍摄了这个物体,你应该会发现它的名字纹在它的耳朵上。 :-)
  • @Kiwy - 他在说什么非常清楚。 :-) :-)
  • @StephenC 不是因为“拍摄和任何东西”的所有部分都与解决方案无关。它只是在运行时找到对象的对象类,我认为这已经在 stackoverflow 上多次回答了
  • @Kiwy - Ermm ...您注意到我的 cmets 末尾的奇怪标点了吗?

标签: java collision-detection jmonkeyengine


【解决方案1】:

你可以在 Java 7 中使用类似的东西:

switch (results.getCollision(0).getClass().getName()){
case "ObjectName1":
    Code
break;
case "ObjectName2":
    Code
break;
}

或者在 Java 6 中

String objectName=results.getCollision(0).getClass().getName()){
if ("ObjectName1"==objectName){
    Code
}elseif ("ObjectName2"==objectName){
    Code
}

【讨论】:

  • 这会打印出以下内容:com.jme3.collision.CollisionResult 这对我没有帮助... :(
  • 但那是你拍摄时击中的班级的名称
  • 我不知道你的全部代码,但你可以返回对 get 对象的引用?
【解决方案2】:

选项 1,as Kiwy suggests 是给每个几何图形一个唯一的名称,并使用它来查找您的对象。选项 2 是扩展 Geometry 使其您的对象或 包含您的对象。然而,这需要使用instanceof 和强制转换。

在这个例子中,我将把 Geometry 扩展到 OwnedGeometry 以携带所有者

public class OwnedGeometry extends Geometry {

    MyClass owner;

    public  OwnedGeometry(String name, Mesh mesh,MyClass owner){
        super(name,mesh);
        this.owner=owner;
    }

    public MyClass getOwner(){
        return owner;
    }
}

这个类可以像你之前使用的 Geometry 一样使用,它只是带有额外的字段。

然后,当您收到几何图形时,您可以检索所有者

CollisionResults results = new CollisionResults();
// Aim the ray from cam loc to cam direction.
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
//Collect intersections between Ray and Shootables in results list.
shootables.collideWith(ray, results);

System.out.println(results.size());
if (results.size() >= 1) {
  Geometry closest=results.getCollision(0).getGeometry());
  if (closest instanceof OwnedGeometry){
      OwnedGeometry ownedGeometry=(OwnedGeometry)closest;
      MyClass myClass=ownedGeometry.getOwner;
      //success!
  }
}

此方法直接返回您的类,但确实需要一些不理想的 instanceof 和强制转换

【讨论】:

  • 哇,非常感谢这个很棒的答案! :) 我会尝试它是否可以这样工作。你说这不理想……有更好的解决方案吗?有一个名为 .setUserData(String, key) 的方法,我可以简单地将名称或“生命”应用于它。但它适用于 3D 模型吗?我真正的问题是,我想修改几何类型。所以我可以应用“isDestroyable”之类的东西......
  • @Pixell 这是我在自己的程序中使用的,所以我认为它是必要的,但 instanceof 经常被过度使用,所以在使用它之前,通常值得做一些健全性检查以确保。您是否要使用这些方法都取决于您的 MyClass 的复杂程度,它是否适合该框架。我正在开发一个我的世界风格的游戏,所以我想要一个完全成熟的对象在另一端(块),但如果你的对象更简单,你可以用 .setUserData(String, key)
  • 我明白了。好吧,我会尽力而为,非常感谢这个想法。我想我只需要弄清楚当比赛到达更远的体育场时哪种方式效果最好。 :)
猜你喜欢
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多