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

📄 carcanvas.java

📁 一个j2me的3d游戏实例
💻 JAVA
字号:
package game.entities;


import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.m3g.*;

import game.terrain.*;

public class CarCanvas extends Canvas 
{
  public Transform tr_camera = new Transform();
  
  public static float matrix[]=new float[16];                     
  public static Transform transform=new Transform();      

  public static float vecRight[]={0.0f, 0.0f, 0.0f};      
  private static float vecUp[]={0.0f, 0.0f, 0.0f};        
  public static float vecAt[]={0.0f, 0.0f, 0.0f};         

  private Graphics3D iG3D;
     
  Light light1 = new Light();
  
  private MainMIDlet parent;
  private Timer timer = new Timer();
  public static World scene;
  Background bg = new Background();
  
  private static Car car;
  Camera uvnCamera ;
  Camera nosecam ;
  Camera backcam;
  Camera sidecam;
  int x, y;

  private MobileBackground mobileBackGnd;
  
  private Group floorGroup;
  
  private HeightMap hm;
  
  public int size = 100;
  

  //构造函数,载入场景
  public CarCanvas( MainMIDlet top )
  {
	this.setFullScreenMode(true);
    parent = top;
    iG3D = iG3D.getInstance();    
    load();
  }
  
  //载入3D模型,对camera进行设定
  public void load()
  {
    scene =  new World();
    addTerrainFloor();
    addBackground();
    addCarGroup();
    addLights();
    setCarCamera();
    setUVNCamera();
    Repainter repaint = new Repainter();
    timer.schedule(repaint,0,50);
  }
  
  private void addCarGroup()
  {
    car = new Car( getWidth(), getHeight());
    
    //设置可移动背景
    car.addBackGround(mobileBackGnd);
    
    //设置汽车要跟随的地形
    car.addCollisionGroup(floorGroup);
    car.setParent(this);
    scene.addChild( car.getCameraGroup() );
    
    //设置当前活动摄像机为car的NoseCamera
    scene.setActiveCamera( car.getNoseCamera() );
  }

  private void addLights()
  {
    light1.setMode( Light.AMBIENT );
    light1.setIntensity( 2 );
    Transform trLight1 =  new Transform();
    trLight1.postTranslate(0,100,0);
    light1.setTransform(trLight1);
    scene.addChild(light1);
  }
  
  private void addTerrainFloor() 
  {
	  try {
		hm = new HeightMap("/res/heightmap.png", 0.3f, 40);
		setTerrainGroup(hm);
	} catch (IOException e) {
		e.printStackTrace();
	}
  }
  
  private void setTerrainGroup( HeightMap hm )
  {	  
	  floorGroup = hm.getTerrainGroup();
	  scene.addChild(floorGroup);
  }
  
  private void addBackground()
  {    
	Image2D backIm = loadImage("/res/clouds.png");
    mobileBackGnd = new MobileBackground(backIm, getWidth(), getHeight());
    scene.setBackground( mobileBackGnd.getBackground() );
  }  
  
  private void setCarCamera()
  {
	  nosecam = car.getNoseCamera();
	  backcam = car.getBackCamera();
	  sidecam = car.getSideCamera();
  }
  
  private void setUVNCamera()
  {
	  uvnCamera = new Camera();
	  
	  uvnCamera.setTranslation(0,10,0);

	  uvnCamera.setPerspective(60.0f,((float)getWidth()/(float)getHeight()),0.5f,1000);
	  
	  Group camGroup = new Group();
	  
	  camGroup.addChild(uvnCamera);
	  
	  scene.addChild(camGroup);
  }

  //响应键盘,按下键盘时对视角或者汽车的外观进行变换
  protected void keyPressed(int keyCode){
    int gameAction = getGameAction(keyCode);
    
    System.out.println("gameAction = " + gameAction);
    
    if (gameAction == 8){
      if (scene.getActiveCamera() == car.getBackCamera())
        scene.setActiveCamera(uvnCamera);
      else if (scene.getActiveCamera() == uvnCamera)
        scene.setActiveCamera(car.getNoseCamera());
      else if (scene.getActiveCamera() == nosecam)
        scene.setActiveCamera(sidecam);
      else
        scene.setActiveCamera(car.getBackCamera());

    }else if( keyCode == Canvas.KEY_NUM0 )
      parent.notifyDestroyed();
    System.gc();
    car.pressedKey(gameAction);
  }

  //释放键盘
  protected void keyReleased(int keyCode){
    int gameAction = getGameAction(keyCode);
    car.releasedKey(gameAction);
  }

  //渲染场景中载入的物体
  protected void paint(Graphics g)
  {
    
    iG3D.bindTarget(g, true, 0);
    try {
    	iG3D.render(scene); 
    }
    catch(Exception e){}
    finally { iG3D.releaseTarget(); }
  }

     //载入纹理
     private Image2D loadImage(String fn)
     // load the image stored in fn
     { Image2D im = null;
       try {
          im = (Image2D)Loader.load(fn)[0];
       }
       catch (Exception e)
       { System.out.println("Cannot make image from " + fn); }
       return im;
     }  

  //多线程类,对场景不断重绘
  class Repainter extends TimerTask
  {
    public void run(){
      repaint();
     
      car.update();
      
      if (scene.getActiveCamera() == uvnCamera){
    	  
        float up[] = new float[3];
        up[0] = 0;
        up[1] = 1;
        up[2] = 0;
        float f[] = new float[3];
        f[0] = 0;
        f[1] = 10;
        f[2] = 0;
        CarCanvas.nodeLookAt(uvnCamera, f, car.getPosition(), up, null);
      }
    }
  }


  public static void nodeLookAt(Node node, float pos[], float lookAt[], float up[], float outAt[])
  {	   
	  //vecAt    = n     (z轴)
	  //vecRight = v     (x轴)
	  //vecUp    = u     (y轴)
	  //postion-camera,求出n,vecAt
      vectorSub(lookAt, pos, vecAt);
      vectorNormalize(vecAt);

      // 叉乘,n*u求出v,vecRight
      vectorCrossProduct(vecAt, up, vecRight);
      vectorNormalize(vecRight);

      // 叉乘,v*n求出u,vecUp
      vectorCrossProduct(vecRight, vecAt, vecUp);

      matrix[0]=vecRight[0];
      matrix[1]=vecUp[0];
      matrix[2]=-vecAt[0];
      matrix[3]=0.0f;

      matrix[4]=vecRight[1];
      matrix[5]=vecUp[1];
      matrix[6]=-vecAt[1];
      matrix[7]=0.0f;

      matrix[8]=vecRight[2];
      matrix[9]=vecUp[2];
      matrix[10]=-vecAt[2];
      matrix[11]=0.0f;

      matrix[12]=0.0f;
      matrix[13]=0.0f;
      matrix[14]=0.0f;
      matrix[15]=1.0f;

      transform.set(matrix);                             
      node.setTransform(transform);                        
      node.setTranslation(pos[0], pos[1], pos[2]);
      
       if(outAt!=null) {
          outAt[0]=vecAt[0];
          outAt[1]=vecAt[1];
          outAt[2]=vecAt[2];
      }
  }


  public static void vectorSub(float vec1[], float vec2[], float vecOut[])
  {
      vecOut[0]=vec1[0]-vec2[0];
      vecOut[1]=vec1[1]-vec2[1];
      vecOut[2]=vec1[2]-vec2[2];
  }


  public static float vectorNormalize(float v[])
  {
      float len=(float)Math.sqrt((v[0]*v[0])+(v[1]*v[1])+(v[2]*v[2]));

      if(len>0.0f) {
          float rSq=1/len;

          v[0]*=rSq;
          v[1]*=rSq;
          v[2]*=rSq;
      }

      return len;
  }


  public static void vectorCrossProduct(float vec1[], float vec2[], float vecOut[])
  {
      if(vecOut==vec1||vecOut==vec2) {

          float fX=(vec1[1]*vec2[2])-(vec1[2]*vec2[1]);
          float fY=(vec1[2]*vec2[0])-(vec1[0]*vec2[2]);

          vecOut[2]=(vec1[0]*vec2[1])-(vec1[1]*vec2[0]);
          vecOut[1]=fY;
          vecOut[0]=fX;
      }
      else {
          vecOut[0]=(vec1[1]*vec2[2])-(vec1[2]*vec2[1]);
          vecOut[1]=(vec1[2]*vec2[0])-(vec1[0]*vec2[2]);
          vecOut[2]=(vec1[0]*vec2[1])-(vec1[1]*vec2[0]);
      }
  }
}

⌨️ 快捷键说明

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