Game3DManager.java

/*
 * Copyright © 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.spacemission;

import java.util.Random;

import javax.microedition.lcdui.Graphics;
import javax.microedition.m3g.*;

public class Game3DManager {

    private Graphics3D graphics3D;
    private PlayerModel playerCamera;
    private Random rnd;
    private int canvasWidth;
    private int canvasHeight;
    private int score;
    private int numberOfAliens;
    private World scene;
    private int appTime = 0;
    private int nextTimeToAnimate;
    private static final int FLOOR_LEN = 20;
    private GameStatusListener status;

    public Game3DManager(int canvasWidth, int canvasHeight) {
        this.numberOfAliens = 10;
        this.score = 0;
        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;
        this.graphics3D = Graphics3D.getInstance();
        rnd = new Random();
        scene = new World(); // create scene graph
        buildScene();
        nextTimeToAnimate = scene.animate(appTime);
    }

    public void paint(Graphics g) {
        try {
            graphics3D.bindTarget(g);
            graphics3D.render(scene);
            graphics3D.releaseTarget();
        }
        catch (IllegalStateException illegal) {
        }
    }

    private void buildScene() {
        addCamera();
        addLights();
        addBackground();
        addFloor();
        addAliens();
    }

    private void addAliens() {
        AlienModel em;
        float x, z;
        for (int i = 0; i < numberOfAliens; i++) {
            x = rndCoord();
            z = rndCoord();
            em = new AlienModel(x, z);
            scene.addChild(em.getModelGroup());
        }
    }

    private float rndCoord() {
        float f = rnd.nextFloat(); // 0.0f to 1.0f
        float coord = (f * FLOOR_LEN) - FLOOR_LEN / 2.0f;
        return coord;
    }

    private void addCamera() {
        playerCamera = new PlayerModel(canvasWidth, canvasHeight);
        scene.addChild(playerCamera.getCameraGroup());
        scene.setActiveCamera(playerCamera.getCamera());
    }

    private void addLights() {
        Light light = new Light(); // default white, directional light
        light.setIntensity(2.5f); // make it a bit brighter
        light.setOrientation(-65.0f, 1.0f, 0, 0); // pointing down and into
        scene.addChild(light);

    }

    private void addBackground() {
        Background backGnd = new Background();
        Image2D backIm = loadImage2D("/game/background.png");
        if (backIm != null) {
            backGnd.setImage(backIm);
        }
        else {
            backGnd.setColor(0x000000);
        }
        scene.setBackground(backGnd);

    }

    private void addFloor() {
        Image2D floorIm = loadImage2D("/game/floor.png");
        FloorTiles f = new FloorTiles(floorIm, FLOOR_LEN);
        scene.addChild(f.getFloorMesh());
    }

    private Image2D loadImage2D(String fn) {
        Image2D im = null;
        try {
            im = (Image2D) Loader.load(fn)[0];
        }
        catch (Exception e) {
            System.out.println("Cannot make image from " + fn);
        }
        return im;
    }

    public int updateGame() {
        try {
            appTime++;
            if (appTime >= nextTimeToAnimate) {
                nextTimeToAnimate = scene.animate(appTime) + appTime;
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        float[] pos = playerCamera.getPosition();
        int maxPos = FLOOR_LEN / 2;
        if ((-maxPos < pos[0]) && (pos[0] < maxPos) && (-maxPos < pos[2])
                && (pos[2] < maxPos)) {
            playerCamera.updatePosition();
        }
        else if (status != null) {
            status.gameOver(GameStatusListener.PLAYER_DIED);
        }

        if (numberOfAliens <= 0) {
            if (status != null) {
                status.gameOver(GameStatusListener.GAME_COMPLETED);
            }
        }
        return score;
    }

    public void setFirePressed() {
        RayIntersection ri = new RayIntersection();
        float[] camPos = playerCamera.getPosition(); // camera's current
        // position
        float[] camDir = playerCamera.getDirection(); // camera's current
        // direction

        if (scene.pick(-1, camPos[0], camPos[1], camPos[2], camDir[0],
                       camDir[1], camDir[2], ri)) { // hit something?
            Node selected = ri.getIntersected();
            if (selected instanceof Mesh) {
                Mesh m = (Mesh) selected;
                m.setAppearance(0, AlienModel.getFrozenAppearance());
                m.setPickingEnable(false);
                score += 10;
                numberOfAliens--;
            }
        }

    }

    public void setKeysPressed(boolean leftPressed, boolean rightPressed,
                               boolean upPressed, boolean downPressed) {
        playerCamera.setKeysPressed(leftPressed, rightPressed, upPressed,
                                    downPressed);
    }

    public void setGameStatusListener(GameStatusListener status) {
        this.status = status;

    }
}