2013-04-10 133 views
2

我刚开始使用java 3-d,我试图做一个游戏,你跳到敌人获取字体。我知道除了碰撞检测之外,如何为游戏做所有事情。当敌方球接触到它时,我需要将球员球移走。我试图做一个id声明,看起来像这样if(sphere.getBounds().intersects(sphere2.getBounds()),但它在游戏开始时因为某种原因而同时触发它。我知道我可能需要使用WakeupOnCollisionEntry课程,但我不知道如何正确使用它来移除球员球。如果我将WakeupOnCollisionEntry类与objTrans.removeChild(sphere)结合使用,但我不知道如何结合使用它们,我会认为它会起作用。Java-3d碰撞检测

如果你需要看我的代码能够帮助,那就是:

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

编辑:现在我已经添加的东西,我想会的工作,如果我能使其更加准确。 我添加了这两种方法:

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

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

和我说这actionPerformed方法:

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

它还挺有效,因为它的工作文字只显示了当球员的球是靠近敌人球,当我第一次启动该程序时,它也显示出来。

有没有更好的方法来做到这一点?如果是这样,我该怎么做呢?我怎样才能让自己的方式更加准确,而不是在我启动程序时直接显示文本?

我知道它变得不准确,因为我只是将三个变量加在一起,所以即使playe和敌人互不接触,位置也可以等于position2,但我无法弄清楚如何在不同的方式。

+0

http://stackoverflow.com/questions/3232318/sphere-sphere-collision-detection-reaction可能有一个答案给你。这是简单的几何。计算中心之间的距离并检查它是否大于相加的半径。 – Dariusz 2013-04-10 12:21:17

回答

0

我很抱歉已经花了时间回到你身边。 Java3d已经建立了一些方法,似乎已经埋藏在所有知识中最黑暗的地方。我发现了一种原始的碰撞检测方法,但是很有效。

下面是一个简单的snip它的方法,可以被称为碰撞。

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

我不能充分信贷对于这一点,我没有得到它从网上的一些信息,但是我从1.2版本的Java3D的使这个版本。

+0

1)它是同一个用户,2)这不是你如何报告重复 – Dariusz 2013-04-10 12:13:49