⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shootingbehaviour.java

📁 JME引擎的一个应用
💻 JAVA
字号:
package Shooter3D;


// ShootingBehaviour.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* The gun cone and laser beam are rotated to point at the placed
   clicked on the checkboard. Then a FireBeam thread is created
   to move ('fire') the beam at the location, and display an explosion.
 */

import java.lang.Math;
import javax.vecmath.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;


public class ShootingBehaviour extends PickMouseBehavior 
{
  // initial orientation of firing cone: straight up
  private static final Vector3d UPVEC = new Vector3d(0.0, 1.0, 0.0);

  private Point3d startPt;
  private boolean firstRotation, finishedShot;
  private double shootAngle;

  private ExplosionsClip explsClip;
  private LaserBeam laser;
  private GunTurret gun;

  // for repeated calculations
  private AxisAngle4d rotAxisAngle = new AxisAngle4d();
  private Vector3d clickVec = new Vector3d();
  private Vector3d axisVec = new Vector3d();


  public ShootingBehaviour(Canvas3D canvas, BranchGroup root, Bounds bounds,
				Point3d sp, ExplosionsClip ec, LaserBeam lb, GunTurret g) 
  {
    super(canvas, root, bounds);
    setSchedulingBounds(bounds);

    pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO);
       // allows PickIntersection objects to be returned

    startPt = sp;  // location of the gun cone
    explsClip = ec;
    laser = lb;
    gun = g;

	firstRotation = true;   // to signal the undoing of previous rotations
    finishedShot = true;    // when true, we can fire another beam
  } // end of ShootingBehaviour()



  public void updateScene(int xpos, int ypos) 
  /* This method is called when something is picked.
     Only the floor is pickable, so obtain the intersect pt, rotate
     the gun cone and laser beam to point at it, then fire the beam.
  */
  {
    if (finishedShot) {   // previous shot has finished
	  pickCanvas.setShapeLocation(xpos, ypos);

	  Point3d eyePos = pickCanvas.getStartPosition();  // the viewer location

	  PickResult pickResult = null;
	  pickResult = pickCanvas.pickClosest();

	  if (pickResult != null) {
        // pickResultInfo(pickResult);

		PickIntersection pi = 
		    pickResult.getClosestIntersection(startPt);  
   			// get intercesection closest to the gun cone	
		Point3d intercept = pi.getPointCoordinatesVW();

        rotateToPoint(intercept);    // rotate the cone and beam
        double turnAngle = calcTurn(eyePos, intercept);

        finishedShot = false;
        new FireBeam(intercept, this, laser, explsClip, turnAngle).start();
					// fire the beam and show the explosion
      }
    }
  } // end of updateScene()


  private void pickResultInfo(PickResult pr)
  // used for checking PickResult values
  {
    // get picked node (should be a Shape3D)
	Shape3D shape = (Shape3D) pr.getNode(PickResult.SHAPE3D);
    if (shape != null)
      System.out.println("Shape3D: " + shape);
    else
      System.out.println("No Shape3D found");

    SceneGraphPath path = pr.getSceneGraphPath();   // path excludes locale & terminal
    if (path != null) {
      int pathLen = path.nodeCount();
      if (pathLen == 0)
        System.out.println("Empty path");
      else {
        for (int i=0; i < pathLen; i++) {
          Node node = path.getNode(i); 
          if (node instanceof Shape3D)
            System.out.print(i + ". Shape3D: " + node);
          else {
            System.out.println(i + ". Node: " + node);
            String name = (String) node.getUserData();
            if (name != null)
              System.out.println(name);
          }
        }
      }
    }
    else
      System.out.println("Path is null");
  }  // end of pickResultInfo()



  private void rotateToPoint(Point3d intercept)
  /* Turn the gun and beam cylinder to point at the point where the 
     mouse was clicked.
  */
  { if (!firstRotation) {   // undo previous rotations to gun and beam
      axisVec.negate();
      rotAxisAngle.set( axisVec, shootAngle );
      gun.makeRotation(rotAxisAngle);
      laser.makeRotation(rotAxisAngle);
    }

	clickVec.set( intercept.x-startPt.x, intercept.y-startPt.y, 
						intercept.z-startPt.z);   
	clickVec.normalize();
	axisVec.cross( UPVEC, clickVec);
    // System.out.println("axisVec: " + axisVec);

    shootAngle = UPVEC.angle(clickVec);
	// shootAngle = Math.acos( UPVEC.dot(clickVec));
    // System.out.println("shootAngle: " + shootAngle);

    rotAxisAngle.set(axisVec, shootAngle);     // build rotation
    // System.out.println("rotAxisAngle: " + rotAxisAngle);

    gun.makeRotation(rotAxisAngle);
    laser.makeRotation(rotAxisAngle);

    firstRotation = false;
  } // end of rotateToPoint()



  private double calcTurn(Point3d eyePos, Point3d intercept)
  /* Calculate the angle to turn the explosion image around the
     y-axis, so that it is facing towards the eye position.
     The image is not rotated around the x- or z- axes.
  */
  {  double zDiff = eyePos.z - intercept.z;
     double xDiff = eyePos.x - intercept.x;
     // System.out.println("zDiff: " + zDiff + "; xDiff: " + xDiff);

     double turnAngle = Math.atan2(xDiff, zDiff);
     // System.out.println("turnAngle: " + turnAngle);
     return turnAngle;
  } // end of calcAngle()


  public void setFinishedShot()
  /* Called by the FireBeam thread when it has moved the laser beam
     to its destination. The beam has been reset and this method is
     called to allow a new firing. */
  { finishedShot = true; }


} // end of ShootingBehaviour class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -