A simple shooting game : Game « 3D « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java » 3D » GameScreenshots 
A simple shooting game

/*
Essential Java 3D Fast

Ian Palmer

Publisher: Springer-Verlag

ISBN: 1-85233-394-4

*/

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Enumeration;

import javax.media.j3d.Alpha;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Bounds;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Locale;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.PositionInterpolator;
import javax.media.j3d.Switch;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.View;
import javax.media.j3d.ViewPlatform;
import javax.media.j3d.VirtualUniverse;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnElapsedTime;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix3d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;

/**
 * This application demonstrates a number of things in the implementation of a
 * simple shooting game. The object of the the game is to shoot a duck that
 * repeatedly moves across the screen from left to right. There are two duck
 * models, one for the 'live' duck and one for the 'dead' one. These are loaded
 * from 'duck.obj' and 'deadduck.obj' files. The 'gun' is built from primitives.
 * The duck and the ball that is used to shoot the duck use interpolators for
 * their animation. The gun uses key board input to aim and fire it, and
 * collision detection is used to 'kill' the duck.
 
 @author I.J.Palmer
 @version 1.0
 */
public class SimpleGame extends Frame implements ActionListener {
  protected Canvas3D myCanvas3D = new Canvas3D(null);

  protected Button exitButton = new Button("Exit");

  protected BoundingSphere bounds = new BoundingSphere(new Point3d(0.00.0,
      0.0)100.0);

  /** Switch that is used to swap the duck models */
  Switch duckSwitch;

  /** Alpha used to drive the duck animation */
  Alpha duckAlpha;

  /** Used to drive the ball animation */
  Alpha ballAlpha;

  /** Used to move the ball */
  PositionInterpolator moveBall;

  /** Used to rotate the gun */
  TransformGroup gunXfmGrp = new TransformGroup();

  /**
   * This builds the view branch of the scene graph.
   
   @return BranchGroup with viewing objects attached.
   */
  protected BranchGroup buildViewBranch(Canvas3D c) {
    BranchGroup viewBranch = new BranchGroup();
    Transform3D viewXfm = new Transform3D();
    Matrix3d viewTilt = new Matrix3d();
    viewTilt.rotX(Math.PI / -6);
    viewXfm.set(viewTilt, new Vector3d(0.010.010.0)1.0);
    TransformGroup viewXfmGroup = new TransformGroup(viewXfm);
    ViewPlatform myViewPlatform = new ViewPlatform();
    PhysicalBody myBody = new PhysicalBody();
    PhysicalEnvironment myEnvironment = new PhysicalEnvironment();
    viewXfmGroup.addChild(myViewPlatform);
    viewBranch.addChild(viewXfmGroup);
    View myView = new View();
    myView.addCanvas3D(c);
    myView.attachViewPlatform(myViewPlatform);
    myView.setPhysicalBody(myBody);
    myView.setPhysicalEnvironment(myEnvironment);
    return viewBranch;
  }

  /**
   * This adds some lights to the content branch of the scene graph.
   
   @param b
   *            The BranchGroup to add the lights to.
   */
  protected void addLights(BranchGroup b) {
    Color3f ambLightColour = new Color3f(0.5f0.5f0.5f);
    AmbientLight ambLight = new AmbientLight(ambLightColour);
    ambLight.setInfluencingBounds(bounds);
    Color3f dirLightColour = new Color3f(1.0f1.0f1.0f);
    Vector3f dirLightDir = new Vector3f(-1.0f, -1.0f, -1.0f);
    DirectionalLight dirLight = new DirectionalLight(dirLightColour,
        dirLightDir);
    dirLight.setInfluencingBounds(bounds);
    b.addChild(ambLight);
    b.addChild(dirLight);
  }

  /**
   * This builds the gun geometry. It uses box and cylinder primitives and
   * sets up a transform group so that we can rotate the gun.
   */
  protected BranchGroup buildGun() {
    BranchGroup theGun = new BranchGroup();
    Appearance gunApp = new Appearance();
    Color3f ambientColour = new Color3f(0.5f0.5f0.5f);
    Color3f emissiveColour = new Color3f(0.0f0.0f0.0f);
    Color3f specularColour = new Color3f(1.0f1.0f1.0f);
    Color3f diffuseColour = new Color3f(0.5f0.5f0.5f);
    float shininess = 20.0f;
    gunApp.setMaterial(new Material(ambientColour, emissiveColour,
        diffuseColour, specularColour, shininess));
    TransformGroup init = new TransformGroup();
    TransformGroup barrel = new TransformGroup();
    Transform3D gunXfm = new Transform3D();
    Transform3D barrelXfm = new Transform3D();
    barrelXfm.set(new Vector3d(0.0, -2.00.0));
    barrel.setTransform(barrelXfm);
    Matrix3d gunXfmMat = new Matrix3d();
    gunXfmMat.rotX(Math.PI / 2);
    gunXfm.set(gunXfmMat, new Vector3d(0.00.00.0)1.0);
    init.setTransform(gunXfm);
    gunXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    gunXfmGrp.addChild(new Box(1.0f1.0f0.5f, gunApp));
    barrel.addChild(new Cylinder(0.3f4.0f, gunApp));
    gunXfmGrp.addChild(barrel);
    theGun.addChild(init);
    init.addChild(gunXfmGrp);
    return theGun;
  }

  /**
   * Creates the duck. This loads the two duck geometries from the files
   * 'duck.obj' and 'deadduck.obj' and loads these into a switch. The access
   * rights to the switch are then set so we can write to this switch to swap
   * between the two duck models. It also creates a transform group and an
   * interpolator to move the duck.
   
   @return BranchGroup with content attached.
   */
  protected BranchGroup buildDuck() {
    BranchGroup theDuck = new BranchGroup();
    duckSwitch = new Switch(0);
    duckSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);

    ObjectFile f1 = new ObjectFile();
    ObjectFile f2 = new ObjectFile();
    Scene s1 = null;
    Scene s2 = null;
    try {
      s1 = f1.load("duck.obj");
      s2 = f2.load("deadduck.obj");
    catch (Exception e) {
      System.exit(1);
    }

    TransformGroup duckRotXfmGrp = new TransformGroup();
    Transform3D duckRotXfm = new Transform3D();
    Matrix3d duckRotMat = new Matrix3d();
    duckRotMat.rotY(Math.PI / 2);
    duckRotXfm.set(duckRotMat, new Vector3d(0.00.0, -30.0)1.0);
    duckRotXfmGrp.setTransform(duckRotXfm);
    duckRotXfmGrp.addChild(duckSwitch);

    duckSwitch.addChild(s1.getSceneGroup());
    duckSwitch.addChild(s2.getSceneGroup());

    TransformGroup duckMovXfmGrp = new TransformGroup();
    duckMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    duckMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    duckMovXfmGrp.addChild(duckRotXfmGrp);

    duckAlpha = new Alpha(-100300000);
    Transform3D axis = new Transform3D();
    PositionInterpolator moveDuck = new PositionInterpolator(duckAlpha,
        duckMovXfmGrp, axis, -30.0f30.0f);
    moveDuck.setSchedulingBounds(bounds);
    theDuck.addChild(moveDuck);
    theDuck.addChild(duckMovXfmGrp);
    return theDuck;
  }

  /**
   * This builds the ball that acts as the bullet for our gun. The ball is
   * created from a sphere primitive, and a transform group and interpolator
   * are added so that we can 'fire' the bullet.
   
   @return BranchGroup that is the root of the ball branch.
   */
  protected BranchGroup buildBall() {
    BranchGroup theBall = new BranchGroup();

    Appearance ballApp = new Appearance();
    Color3f ambientColour = new Color3f(1.0f0.0f0.0f);
    Color3f emissiveColour = new Color3f(0.0f0.0f0.0f);
    Color3f specularColour = new Color3f(1.0f1.0f1.0f);
    Color3f diffuseColour = new Color3f(1.0f0.0f0.0f);
    float shininess = 20.0f;
    ballApp.setMaterial(new Material(ambientColour, emissiveColour,
        diffuseColour, specularColour, shininess));

    Sphere ball = new Sphere(0.2f, ballApp);

    TransformGroup ballMovXfmGrp = new TransformGroup();
    ballMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    ballMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    ballMovXfmGrp.addChild(ball);
    theBall.addChild(ballMovXfmGrp);

    ballAlpha = new Alpha(10050000);
    Transform3D axis = new Transform3D();
    axis.rotY(Math.PI / 2);
    moveBall = new PositionInterpolator(ballAlpha, ballMovXfmGrp, axis,
        0.0f50.0f);
    moveBall.setSchedulingBounds(bounds);
    theBall.addChild(moveBall);

    return theBall;

  }

  /**
   * This puts all the content togther. It used the three 'build' functions to
   * create the duck, the gun and the ball. It also creates the two behaviours
   * from the DuckBehaviour and GunBehaviour classes. It then puts all this
   * together.
   
   @return BranchGroup that is the root of the content.
   */
  protected BranchGroup buildContentBranch() {
    BranchGroup contentBranch = new BranchGroup();
    Node theDuck = buildDuck();
    contentBranch.addChild(theDuck);
    Node theBall = buildBall();
    contentBranch.addChild(theBall);
    DuckBehaviour hitTheDuck = new DuckBehaviour(theDuck, duckSwitch,
        duckAlpha, bounds);
    GunBehaviour shootTheGun = new GunBehaviour(ballAlpha, moveBall,
        gunXfmGrp, bounds);
    contentBranch.addChild(hitTheDuck);
    contentBranch.addChild(shootTheGun);
    contentBranch.addChild(buildGun());
    addLights(contentBranch);
    return contentBranch;
  }

  /** Exit the application */
  public void actionPerformed(ActionEvent e) {
    dispose();
    System.exit(0);
  }

  public SimpleGame() {
    VirtualUniverse myUniverse = new VirtualUniverse();
    Locale myLocale = new Locale(myUniverse);
    myLocale.addBranchGraph(buildViewBranch(myCanvas3D));
    myLocale.addBranchGraph(buildContentBranch());
    setTitle("Duck Shoot!");
    setSize(400400);
    setLayout(new BorderLayout());
    add("Center", myCanvas3D);
    exitButton.addActionListener(this);
    add("South", exitButton);
    setVisible(true);

  }

  public static void main(String[] args) {
    SimpleGame sg = new SimpleGame();
  }

}
/**
 * This is used in the SimpleGame application. It defines the behaviour for the
 * duck, which is the target in the shooting game. If something collides with
 * the duck, it swaps a switch value to 'kill' the duck The duck is revived when
 * it's alpha value passes through zero.
 
 @author I.J.Palmer
 @version 1.0
 */

class DuckBehaviour extends Behavior {
  /** The shape that is being watched for collisions. */
  protected Node collidingShape;

  /** The separate criteria that trigger this behaviour */
  protected WakeupCriterion[] theCriteria;

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

  /** The switch that is used to swap the duck shapes */
  protected Switch theSwitch;

  /** The alpha generator that drives the animation */
  protected Alpha theTargetAlpha;

  /** Defines whether the duck is dead or alive */
  protected boolean dead = false;

  /**
   * This sets up the data for the behaviour.
   
   @param theShape
   *            Node that is to be watched for collisions.
   @param sw
   *            Switch that is used to swap shapes.
   @param a1
   *            Alpha that drives the duck's animation.
   @param theBounds
   *            Bounds that define the active region for this behaviour.
   */
  public DuckBehaviour(Node theShape, Switch sw, Alpha a1, Bounds theBounds) {
    collidingShape = theShape;
    theSwitch = sw;
    theTargetAlpha = a1;
    setSchedulingBounds(theBounds);
  }

  /**
   * This sets up the criteria for triggering the behaviour. It creates an
   * collision crtiterion and a time elapsed criterion, OR's these together
   * and then sets the OR'ed criterion as the wake up condition.
   */
  public void initialize() {
    theCriteria = new WakeupCriterion[2];
    theCriteria[0new WakeupOnCollisionEntry(collidingShape);
    theCriteria[1new WakeupOnElapsedTime(1);
    oredCriteria = new WakeupOr(theCriteria);
    wakeupOn(oredCriteria);
  }

  /**
   * This is where the work is done. If there is a collision, then if the duck
   * is alive we switch to the dead duck. If the duck was already dead then we
   * take no action. The other case we need to check for is when the alpha
   * value is zero, when we need to set the duck back to the live one for its
   * next traversal of the screen. Finally, the wake up condition is set to be
   * the OR'ed criterion again.
   */
  public void processStimulus(Enumeration criteria) {
    while (criteria.hasMoreElements()) {
      WakeupCriterion theCriterion = (WakeupCriterioncriteria
          .nextElement();
      if (theCriterion instanceof WakeupOnCollisionEntry) {
        //There'sa collision so if the duck is alive swap
        //it to the dead one
        if (dead == false) {
          theSwitch.setWhichChild(1);
          dead = true;
        }
      else if (theCriterion instanceof WakeupOnElapsedTime) {
        //If there isn't a collision, then check the alpha
        //value and if it's zero, revive the duck
        if (theTargetAlpha.value() 0.1) {
          theSwitch.setWhichChild(0);
          dead = false;
        }
      }

    }
    wakeupOn(oredCriteria);
  }
}

/**
 * This is used in the SimpleGame application. It defines a behaviour that
 * allows a 'gun' to be rotated when left and right cursor keys are pressed and
 * then a ball is 'fired' when the space bar is pressed. The 'firing' is
 * achieved by setting the start time of an interpolator to the current time.
 
 @author I.J.Palmer
 @version 1.0
 */

class GunBehaviour extends Behavior {
  /** The separate criteria that trigger this behaviour */
  protected WakeupCriterion theCriterion;

  /** The alpha that is used to 'fire' the ball */
  protected Alpha theGunAlpha;

  /** Used to animate the ball */
  protected PositionInterpolator theInterpolator;

  /** Used to calculate the current direction of the gun */
  protected int aim = 0;

  /** This is used to rotate the gun */
  protected TransformGroup aimXfmGrp;

  /** Used to aim the ball */
  protected Matrix3d aimShotMat = new Matrix3d();

  /** Used to aim the gun */
  protected Matrix3d aimGunMat = new Matrix3d();

  /** Used to define the ball's direction */
  protected Transform3D aimShotXfm = new Transform3D();

  /** Used to define the gun's direction */
  protected Transform3D aimGunXfm = new Transform3D();

  /**
   * Set up the data for the behaviour.
   
   @param a1
   *            Alpha that drives the ball's animation.
   @param pi
   *            PositionInterpolator used for the ball.
   @param gunRotGrp
   *            TransformGroup that is used to rotate the gun.
   @param theBounds
   *            Bounds that define the active region for this behaviour.
   */
  public GunBehaviour(Alpha a1, PositionInterpolator pi,
      TransformGroup gunRotGrp, Bounds theBounds) {
    theGunAlpha = a1;
    theInterpolator = pi;
    setSchedulingBounds(theBounds);
    aimXfmGrp = gunRotGrp;
  }

  /**
   * This sets up the criteria for triggering the behaviour. We simple want to
   * wait for a key to be pressed.
   */
  public void initialize() {
    theCriterion = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
    wakeupOn(theCriterion);
  }

  /**
   * This is where the work is done. This identifies which key has been
   * pressed and acts accordingly: left key cursor rotate left, right cursor
   * key rotate right, spacebar fire.
   
   * @criteria Enumeration that represents the trigger conditions.
   */
  public void processStimulus(Enumeration criteria) {
    while (criteria.hasMoreElements()) {
      WakeupCriterion theCriterion = (WakeupCriterioncriteria
          .nextElement();
      if (theCriterion instanceof WakeupOnAWTEvent) {
        AWTEvent[] triggers = ((WakeupOnAWTEventtheCriterion)
            .getAWTEvent();
        //Check if it's a keyboard event
        if (triggers[0instanceof KeyEvent) {
          int keyPressed = ((KeyEventtriggers[0]).getKeyCode();
          if (keyPressed == KeyEvent.VK_LEFT) {
            //It's a left key so move the turret
            //and the aim of the gun left unless
            //we're at our maximum angle
            if (aim < 8)
              aim += 1;
            System.out.println("Left " + aim);
            aimShotMat.rotY(((aim / 32.00.5* Math.PI);
            aimGunMat.rotZ(((aim / -32.0)) * Math.PI);
            aimShotXfm.setRotation(aimShotMat);
            aimGunXfm.setRotation(aimGunMat);
            aimXfmGrp.setTransform(aimGunXfm);
            theInterpolator.setAxisOfTranslation(aimShotXfm);
          else if (keyPressed == KeyEvent.VK_RIGHT) {
            //It's the right key so do the same but rotate right
            if (aim > -8)
              aim -= 1;
            System.out.println("Right " + aim);
            aimShotMat.rotY(((aim / 32.00.5* Math.PI);
            aimGunMat.rotZ(((aim / -32.0)) * Math.PI);
            aimGunXfm.setRotation(aimGunMat);
            aimShotXfm.setRotation(aimShotMat);
            aimXfmGrp.setTransform(aimGunXfm);
            theInterpolator.setAxisOfTranslation(aimShotXfm);
          else if (keyPressed == KeyEvent.VK_SPACE) {
            //It's the spacebar so reset the start time
            //of the ball's animation
            theGunAlpha.setStartTime(System.currentTimeMillis());
          }
        }
      }
    }
    wakeupOn(theCriterion);
  }
}



           
       
Related examples in the same category
1. Game: four by fourGame: four by four
2. Tick Tock PickingTick Tock Picking
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.