The player model is implemented with the PlayerModel class, and the alien model with the AlienModel class.
The most important part of the PlayerModel class is the camera that represents the player's view. This camera is used when the MIDlet is to be drawn on the screen.
To implement the player model:
In the PlayerModel class constructor, initialize the camera and group, and set them up so that they are ready to use.
public PlayerModel(int width, int height) { cam = new Camera(); float aspectRatio = ((float) width) / ((float) height); cam.setPerspective(70.0f, aspectRatio, 0.1f, 50.0f); cam.postRotate(-2.0f, 1.0f, 0, 0); // apply x-axis rotations to camera // transGroup handles both camera translation and y-axis rotations transGroup = new Group(); // no initial rotation trans.postTranslate(X_POS, Y_POS, Z_POS); transGroup.setTransform(trans); transGroup.addChild(cam); // store initial rotation yAngle = 0.0f; }
Use the updatePosition and updateRotation methods to keep the camera in the right place and looking in the right direction.
public void updatePosition() { if (upPressed || downPressed) { updateMove(); } else if (leftPressed || rightPressed) { updateRotation(); } } // ... private void updateRotation() { if (leftPressed) { // rotate left around the y-axis rotTrans.postRotate(ANGLE_INCR, 0, 1.0f, 0); yAngle += ANGLE_INCR; } else { // rotate right around the y-axis rotTrans.postRotate(-ANGLE_INCR, 0, 1.0f, 0); yAngle -= ANGLE_INCR; } // angle values are modulo 360 degrees if (yAngle >= 360.0f) { yAngle -= 360.0f; } else if (yAngle <= -360.0f) { yAngle += 360.0f; } // apply the y-axis rotation to transGroup storePosition(); trans.setIdentity(); trans.postTranslate(xCoord, yCoord, zCoord); trans.postRotate(yAngle, 0, 1.0f, 0); transGroup.setTransform(trans); }
The AlienModel class creates VertexBuffer , IndexBuffer , and Appearance objects, and combines them into a Mesh object that represents an alien.
To implement the alien model:
Use the makeGeometry method to return the VertexBuffer.
private static VertexBuffer makeGeometry() { // create vertices short[] verts = getVerts(); VertexArray va = new VertexArray(verts.length / 3, 3, 2); va.set(0, verts.length / 3, verts); // create normals byte[] norms = getNormals(); VertexArray normArray = new VertexArray(norms.length / 3, 3, 1); normArray.set(0, norms.length / 3, norms); // create texture coordinates short[] tcs = getTexCoordsRev(); VertexArray texArray = new VertexArray(tcs.length / 2, 2, 2); texArray.set(0, tcs.length / 2, tcs); float[] pbias = {(1.0f / 255.0f), (1.0f / 255.0f), (1.0f / 255.0f)}; VertexBuffer vertexB = new VertexBuffer(); vertexB.setPositions(va, (2.0f / 255.0f), pbias); // scale, bias vertexB.setNormals(normArray); vertexB.setTexCoords(0, texArray, (1.0f / 255.0f), null); return vertexB; } // end of makeGeometry()
In the AlienModel class constructor, combine the objects into a Mesh object.
public AlienModel(float xCoord, float zCoord) { model = new Mesh(vb, ib, app); model.setTranslation(xCoord + 0.25f, 0.25f, zCoord + 0.25f); model.scale(0.5f, 0.5f, 0.5f); model.setPickingEnable(true); // so can fire a pick ray at it // translation group for the model transGroup = new Group(); transGroup.addChild(model); transGroup.addAnimationTrack(setUpAnimation()); }
To make the aliens move around, use a KeyframeSequence object. This is used to establish the key frames for the animation and make it move around in a circle. The translateFrames method sets up a KeyframeSequence with 8 frames, each frame taking 10 time units. Then the coordinates are set up to describe a circle of the 0.5f radius, centered in the origin on the XZ plane. A spline is used to interpolate between the points to create the circular movement.
private KeyframeSequence translateFrames() { KeyframeSequence ks = new KeyframeSequence(8, 3, KeyframeSequence.SPLINE); // move clockwise in a circle; // each frame is separated by 10 sequence time units ks.setKeyframe(0, 0, new float[]{-0.5f, 0.0f, 0.0f}); ks.setKeyframe(1, 10, new float[]{-0.3536f, 0.0f, 0.3536f}); ks.setKeyframe(2, 20, new float[]{0.0f, 0.0f, 0.5f}); ks.setKeyframe(3, 30, new float[]{0.3536f, 0.0f, 0.3536f}); ks.setKeyframe(4, 40, new float[]{0.5f, 0.0f, 0.0f}); ks.setKeyframe(5, 50, new float[]{0.3536f, 0.0f, -0.3536f}); ks.setKeyframe(6, 60, new float[]{0.0f, 0.0f, -0.5f}); ks.setKeyframe(7, 70, new float[]{-0.3536f, 0.0f, -0.3536f}); ks.setDuration(80); // one cycle takes 80 sequence time units ks.setValidRange(0, 7); ks.setRepeatMode(KeyframeSequence.LOOP); return ks; }
Use the setUpAnimation method to create the AnimationController and AnimationTrack objects to which the alien model can be attached.
private AnimationTrack setUpAnimation() { // creation animation controller AnimationController animController = new AnimationController(); animController.setActiveInterval(0, 0); // creation translation animation track KeyframeSequence transKS = translateFrames(); AnimationTrack transTrack = new AnimationTrack(transKS, AnimationTrack.TRANSLATION); transTrack.setController(animController); return transTrack; }