2

I started working on a game with jMonkey. I just created an object from the class "Entity" I made myself which holds an 3D Model, Physics and so on. Here is the code:

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;
  }
}

With help from the tutorial on the jMonkey website I managed to implement the "shooting". A simple ray that follows my cam direction. Here is the code for what happens if it collides with something:

} 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());
    }
  }

So that works just fine! This line:

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

displays the name of that "Geometry" i just shot. But the problem now is, that my object is not a Geometry! And I dont know how I can implement that I get the name of this object anyway. The best way for me would be if the results.getCollision(0) would return my object so I could just say "object.getName();"

Does anyone know how I can do that? I would be very grateful for any ideas :) cheers - Daniel

Dawesign
  • 643
  • 1
  • 7
  • 25
  • you should consider to modifiy your title which is absolutly not clear. – Kiwy Nov 28 '13 at 12:52
  • Once you've shot the object, you should find its name tattooed on its ear. :-) – Stephen C Nov 28 '13 at 12:52
  • @Kiwy - It is perfectly clear what he is talking about. :-) :-) – Stephen C Nov 28 '13 at 12:53
  • @StephenC Not it is not because all the part where "shoot and what ever" as nothing to do with the solution. it's just about finding the object class of an object at runtime, which has already been answer several time on stackoverflow I think – Kiwy Nov 28 '13 at 12:56
  • 1
    @Kiwy - Ermm ... did you notice the strange punctuation at the end of my comments? – Stephen C Nov 28 '13 at 12:58
  • @StephenC I didn't indeed... :D – Kiwy Nov 28 '13 at 12:59

2 Answers2

0

You can use something like this in Java 7:

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

or that in Java 6

String objectName=results.getCollision(0).getClass().getName()){
if ("ObjectName1"==objectName){
    Code
}elseif ("ObjectName2"==objectName){
    Code
}
Kiwy
  • 340
  • 2
  • 10
  • 43
0

Option 1, as Kiwy suggests is to give each geometry a unique name and use that to look up your object. Option 2 is to extend Geometry such that it either is your object or contains your object. This requires some use of instanceof and casting however.

In this example I shall extend Geometry to OwnedGeometry to carry the owner along with it

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;
    }
}

This class can be used exactly as you used Geometry previously, it just carries that extra field around with it.

Then, when you recieve your geometry you can retrieve the owner

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!
  }
}

This method gives you your class back directly, but does require a little instanceof and casting which is non ideal

Community
  • 1
  • 1
Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
  • Wow thanks a lot for this great answer! :) I'll try if it works that way. You said that this is non ideal... Is there a better solution? There is a method called .setUserData(String, key) with that I could simply apply the name or the "lifes" to it. But would it work with the 3D model? My real problem is, that I want to modify the Geometry kind of. So I can apply things like "isDestroyable"... – Dawesign Nov 28 '13 at 13:52
  • @Pixell This is what I use in my own program so I think its a necessary evil, but often instanceof is overused so before using it it's often worth doing a little sanity check just to make sure. Whether you want to use those methods all depend on how complex your MyClass is, if it would fit within that framework. I am working on a minecraft style game so I wanted a fully fledged object out the other end (the chunk) but if your objects are simpler you may get away with .setUserData(String, key) – Richard Tingle Nov 28 '13 at 13:54
  • I see. Well, I'll try my best and thanks a lot for this idea. I guess I just have to figure out which way works the best when the game reached a further stadium. :) – Dawesign Nov 28 '13 at 14:16