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