2013-04-10 2 views
2

Я только начал использовать java 3-d и Im, пытаясь сделать игру, где вы прыгаете на врагов, чтобы получить понты. Я знаю, как сделать все для игры, кроме обнаружения столкновения. Мне нужно, чтобы мяч игрока удалялся, когда вражеский мяч касался его. Я попытался сделать заявление 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); 
    } 
} 

Edit: Теперь я добавил то, что я думаю, что будет работать, если я мог бы сделать его более точным. я добавил эти два метода:

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

Это своего рода работает, потому что он работал только текст появляется, когда игрок мяч находится рядом с вражеским мяч , он также появляется при первом запуске программы.

Есть ли лучший способ сделать это? Если да, то как мне это сделать? И как я могу сделать свой путь более точным и не показывать текст непосредственно при запуске программы?

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

+0

http://stackoverflow.com/questions/3232318/sphere-sphere-collision-detection-reaction может иметь для вас ответ. Это простая геометрия. Рассчитайте расстояние между центрами и проверьте, больше ли это суммированных радиусов. – Dariusz

ответ

0

Прошу прощения за то, что он принял вас, чтобы вернуться к вам. Java3d имеет встроенные методы, которые, похоже, были зарыты в самое темное из всех знаний. Я нашел метод обнаружения столкновений, который является сырым, но работает.

Вот простой снип это для метода, который может быть призван дать столкновение.

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

Я не могу взять полный кредит на это, я действительно получил некоторую информацию об этом из Интернета, однако я сделал эту версию из версии JAVA3D 1.2.

+0

1) это тот же пользователь, 2) это не то, как вы сообщаете дубликаты – Dariusz