简体   繁体   English

Java-3d碰撞检测

[英]Java-3d collision detection

I have just started to use java 3-d and Im trying to make a game where you jump on enemies to get ponts. 我刚刚开始使用Java 3-d和Im尝试制作一个游戏,让您跳到敌人身上来获得点滴。 I know how to do everything for the game except the collision detection. 除了碰撞检测,我知道如何为游戏做所有事情。 I need the player ball to be removed when the enemy ball touches it. 我需要在敌人的球碰到时将其移走。 I have tried to do a id statement that looks like this if(sphere.getBounds().intersects(sphere2.getBounds()) but that trigers it at the same time as the game starts for some reason. I know that I probably need to use the WakeupOnCollisionEntry class but I don't know how to properly use it to remove the player ball. I would think that it would work if I used the WakeupOnCollisionEntry class in conjunction with objTrans.removeChild(sphere) but I have no idea how to use them in conjunction with each others. 我试图做一个类似if(sphere.getBounds().intersects(sphere2.getBounds())的id语句,但是由于某种原因,它在游戏开始的同时触发了它。我知道我可能需要使用WakeupOnCollisionEntry类,但是我不知道如何正确地使用它来删除球员球,我想如果我将WakeupOnCollisionEntry类与objTrans.removeChild(sphere)结合使用将是WakeupOnCollisionEntry将它们彼此结合使用。

If you need to see my code to be able to help, here it is: 如果您需要查看我的代码才能提供帮助,则为:

package Game;

import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.vecmath.*;

public class PAPITest extends JFrame implements ActionListener,KeyListener{
    private TransformGroup objTrans,objTrans2;
    private Transform3D trans = new Transform3D();
    private BranchGroup objRoot;
    private Sphere sphere, sphere2;
    private float x, dx, height = 0.0f, sign = 1.0f, xloc = 0.0f;
    private Timer timer;

    public BranchGroup createSceneGraph(){
        objRoot = new BranchGroup();
        objTrans = new TransformGroup();
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(objTrans);
        sphere = new Sphere(0.25f);
        sphere.setCollidable(true);
        objTrans = new TransformGroup();
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        Transform3D pos1 = new Transform3D();
        pos1.setTranslation(new Vector3f(0.0f,0.0f,0.0f));
        objTrans.setTransform(pos1);
        objTrans.addChild(sphere);
        objRoot.addChild(objTrans);
        BoundingSphere bounds = new BoundingSphere
                (new Point3d(0.0,0.0,0.0),100.0);
        Color3f light1Color = new Color3f(0.2f,1.0f,1.0f);
        Vector3f light1Direction = new Vector3f(+4.0f,-7.0f,-12.0f);
        DirectionalLight light1 = new DirectionalLight
                (light1Color,light1Direction);
        light1.setInfluencingBounds(bounds);
        objRoot.addChild(light1);
        Color3f ambientColor = new Color3f(1.0f,1.0f,1.0f);
        AmbientLight ambientLightNode = new AmbientLight(ambientColor);
        ambientLightNode.setInfluencingBounds(bounds);
        objRoot.addChild(ambientLightNode);         
        return objRoot;
    }

    public BranchGroup createSceneGraph2(){
        objRoot = new BranchGroup();
        objTrans2 = new TransformGroup();
        objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(objTrans2);
        sphere2 = new Sphere(0.25f);
        sphere2.setCollidable(true);
        objTrans2 = new TransformGroup();
        objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        Transform3D pos1 = new Transform3D();
        pos1.setTranslation(new Vector3f(0.0f,0.0f,0.0f));
        objTrans2.setTransform(pos1);
        objTrans2.addChild(sphere2);
        objRoot.addChild(objTrans2);
        return objRoot;
    }

    public PAPITest(){
        setLayout(new BorderLayout());
        setTitle("PAPI");
        setVisible(true);
        setSize(505,525);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
        Canvas3D c = new Canvas3D(config);
        add("Center",c);
        c.addKeyListener(this);
        c.setSize(500,500);
        timer = new Timer(100,this);
        timer.start();
        BranchGroup scene = createSceneGraph();
        BranchGroup scene2 = createSceneGraph2();
        SimpleUniverse u = new SimpleUniverse(c);
        u.getViewingPlatform().setNominalViewingTransform();
        u.addBranchGraph(scene);
        u.addBranchGraph(scene2);
        for(float i = 0; i < .10f; i++){
            x = 1.5f;
            dx = -.05f;
        }
    }

    public void keyPressed(KeyEvent e){
        if(e.getKeyChar() == 'd'){
            xloc = xloc + .1f;
        }

        if(e.getKeyChar() == 'a'){
            xloc = xloc - .1f;
        }
    }

    public void keyReleased(KeyEvent e){

    }

    public void keyTyped(KeyEvent e){

    }

    public void actionPerformed(ActionEvent e){
        height += .1f * sign;
        if(Math.abs(height * 2) >= 1)
            sign = -1.0f * sign;
        if(height < -.4f){
          trans.setScale(new Vector3d(1.0,.8,1.0));
        }else{
          trans.setScale(new Vector3d(1.0,1.0,1.0));
        }
        trans.setTranslation(new Vector3f(xloc,height - .15f,0.0f));
        objTrans.setTransform(trans);
        if(height < -.4f){
          trans.setScale(new Vector3d(1.0,1.0,1.0));
        }
        trans.setTranslation(new Vector3f(x += dx,-.7f,0.0f));
        objTrans2.setTransform(trans);
    }

    public static void main(String[] args){
        System.out.println("Program Started");
        PAPITest pt = new PAPITest();
        pt.addKeyListener(pt);
    }
}

Edit: Now I have added something that I think would work if I could make it more accurate. 编辑:现在,我添加了一些我认为可以使它更准确的东西。 I added these two methods: 我添加了以下两种方法:

public void getSpherePosition(){
        positionX = (int) xloc;
        positionY = (int) height;
        position = positionX + positionY;
    }

    public void getSphere2Position(){
        positionX2 = (int) x;
        positionY2 = (int) -.7f;
        position2 = positionX2 + positionY2;
    }

and I added this in the actionPerformed method: 并将其添加到actionPerformed方法中:

        getSpherePosition();
        getSphere2Position();
        if(position == position2){
            System.out.println("It Worked");
        }

It kinda works because the It Worked text only show up when the player ball is near the enemy ball, it also show up when I first start the program. 之所以可以使用它,是因为“已完成工作”文本仅在玩家球靠近敌方球时显示,而在我第一次启动程序时也显示。

Is there a better way to do it on? 有更好的方法吗? If so how do I do it on that way? 如果是这样,我该怎么做? And how can I make my way be more accurate and not show the text directly when I start the program? 启动程序时,如何使自己的方式更准确并且不直接显示文本?

I know that it becomess unaccurate because I just plused the three variables together, so position can equals position2 even if the playe and enemy don't touch each other, but I can't figure out how to do it in a different way. 我知道它变得不准确,因为我只是将这三个变量加在一起,所以即使播放器和敌人没有碰到一起,位置也可以等于position2,但是我不知道该怎么做。

I am sorry for the time it has taken to get back to you. 很抱歉花时间与您联系。 Java3d has built in methods that seem to have been buried in to the darkest of all knowledge. Java3d内置了似乎埋藏在所有知识中最黑暗的方法。 I found a method of collision detection that is crude, but works. 我发现了一种冲突检测方法,该方法很粗糙,但是可以工作。

Here is a simple snip it for a method that can be called upon to give collision. 这是一个简单的剪裁,它是一种可以调用以产生碰撞的方法。

import java.util.Enumeration;
import javax.media.j3d.Behavior;
import javax.media.j3d.Bounds;
import javax.media.j3d.Node;
import javax.media.j3d.Shape3D;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnCollisionExit;
import javax.media.j3d.WakeupOnCollisionMovement;
import javax.media.j3d.WakeupOr;



/**
 *
 * @author sawyera.2016
 */
 public class Coll extends Behavior {
 /** The separate criteria used to wake up this beahvior. */
 protected WakeupCriterion[] theCriteria;

 /** The OR of the separate criteria. */
 protected WakeupOr oredCriteria;

 /** The shape that is watched for collision. */
  protected Shape3D collidingShape;

  /**
    * @param theShape
   *            Shape3D that is to be watched for collisions.
   * @param theBounds
   *            Bounds that define the active region for this behaviour
   */
  public Coll(Shape3D theShape, Bounds theBounds) {
   collidingShape = theShape;
   setSchedulingBounds(theBounds);
    }


  /**
   * This creates an entry, exit and movement collision criteria. These are
   * then OR'ed together, and the wake up condition set to the result.
   */
  public void initialize() {
    theCriteria = new WakeupCriterion[3];
    theCriteria[0] = new WakeupOnCollisionEntry(collidingShape);
    theCriteria[1] = new WakeupOnCollisionExit(collidingShape);
    theCriteria[2] = new WakeupOnCollisionMovement(collidingShape);
    oredCriteria = new WakeupOr(theCriteria);
    wakeupOn(oredCriteria);
  }

  /**
   * Where the work is done in this class. A message is printed out using the
   * userData of the object collided with. The wake up condition is then set
   * to the OR'ed criterion again.
   */
  public void processStimulus(Enumeration criteria) {
    WakeupCriterion theCriterion = (WakeupCriterion) criteria.nextElement();
    if (theCriterion instanceof WakeupOnCollisionEntry) {
      Node theLeaf = ((WakeupOnCollisionEntry) theCriterion)
          .getTriggeringPath().getObject();
      System.out.println("Collided with " + theLeaf.getUserData());
    } else if (theCriterion instanceof WakeupOnCollisionExit) {
      Node theLeaf = ((WakeupOnCollisionExit) theCriterion)
          .getTriggeringPath().getObject();
      System.out.println("Stopped colliding with  "
      + theLeaf.getUserData());
    } else {
      Node theLeaf = ((WakeupOnCollisionMovement) theCriterion)
      .getTriggeringPath().getObject();
  System.out.println("Moved whilst colliding with "
      + theLeaf.getUserData());
    }
    wakeupOn(oredCriteria);
  }
}

I cannot take full credit for this, i did get some information about it from the web however i made this version from a 1.2 version of java3d. 我不能完全相信这一点,但确实从Web上获得了一些有关它的信息,但是我是从1.2版本的Java3d制作的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM