J2ME 3D地图纹理小例子

MIDlet类代码如下

 public class DesertMIDlet extends MIDlet implements CommandListener{

 private Command exitCommand = new Command("Exit" , Command.EXIT, 1);
 

 protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
  // TODO Auto-generated method stub

 }

 protected void pauseApp() {
  // TODO Auto-generated method stub

 }

 

   //初始化

 protected void startApp() throws MIDletStateChangeException {
  DesertCanvas dCanvas = new DesertCanvas();
  dCanvas.addCommand(exitCommand);
  dCanvas.setCommandListener(this);
  Display.getDisplay(this).setCurrent(dCanvas);

 }

 //处理退出
 public void commandAction(Command command, Displayable displayable) {
  
  if(command == exitCommand)
  {
   try {
    destroyApp(true);
   } catch (MIDletStateChangeException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   notifyDestroyed();
  }
  
 }

 
}

 

等高地图创建的场景如果铺上纹理显得更加真是,在HeightMap类添加createTexure方法来创建纹理

HeightMap类代码如下:

 
public class HeightMap {
   
    private short[] heightMap;
    private int[] data;
 
   
    // 加载的地图大小
    private int mapWidth;
    private int mapHeight;
   
    // 四边形
    private Mesh[][] map;
    private static final String  TerrainImgFn ="/Terrain0.png" ;
    private float resolution = 0.25f;
    private int imgw, imgh; 
    private static VertexArray POSITION_ARRAY;
    private static VertexArray COLOR_ARRAY ;
    private static VertexArray TEXCOORD_ARRAY;
    private static VertexBuffer vertexBuffer;
    private static IndexBuffer indexBuffer;
    private static Appearance appearance;
    private static PolygonMode polygonmode;
    private static Texture2D texture;
    // 创建转换对象
    private Transform localTransform = new Transform();
   
  
    public HeightMap() throws IOException
    {
       
        if(resolution <= 0.0001f || resolution > 1.0f)
            throw new IllegalArgumentException("Resolution too small or too large");
       
        // 加载图片
        loadMapImage();
        createTexture();
        // 创建四边形
        createQuads();

    }
   
    public Mesh[][]getQuads(){
      return map; 
     
    }
   
    public int getMapWidth(){
      return mapWidth;
    }

    public int getMapHeight(){
      return mapHeight;
    }
   
    //创建纹理的方法
    private static void createTexture(){
         Image2D waterIm = null;
          try {
          waterIm = (Image2D)Loader.load("/SAND1.PNG")[0];
         
        }
       catch (Exception e)
       { System.out.println("Cannot make image " ); }
        texture = new Texture2D(waterIm);
         texture.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST);
         texture.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP);
    }
   
    //创建四边形的方法
    private void createQuads()
    {
        map = new Mesh[mapWidth][mapHeight];
        short[] heights = new short[4];
       
        for(int x = 0; x < (mapWidth - 1); x++)
        {
            for(int y = 0; y < (mapHeight - 1); y++)
            {
                // 设置顶点
               heights[0] = heightMap[x + y * mapWidth];
               heights[1] = heightMap[x + y * mapWidth + 1];
               heights[3] = heightMap[x + (y + 1) * mapWidth];
               heights[2] = heightMap[x + (y + 1) * mapWidth + 1];
               
                // 创建网格
                map[x][y] = createQuad(heights);
            }
        }
      }

 

    private void loadMapImage() throws IOException
    {
        // 加载地图资源
        Image img = Image.createImage(TerrainImgFn);
       
       //设定data大小
        data = new int[img.getWidth() * img.getHeight()];
       
        // 获取颜色并存在data中
        img.getRGB(data, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());
       
        imgw = img.getWidth();
        imgh = img.getHeight();
       
        // 释放
        img = null;
        System.gc();
       
        // 计算新的宽度和高度
        mapWidth = (int)(resolution * imgw);
        mapHeight = (int)(resolution * imgh);
       
        // 计算heightMap大小
        heightMap = new short[mapWidth * mapHeight];
       
        // 计算高度和宽度的位置偏移
        int xoff = imgw / mapWidth;
        int yoff = imgh / mapHeight;
       
        // 设置高度
        for(int y = 0; y < mapHeight; y++)
        {
            for(int x = 0; x < mapWidth; x++)
            {
                heightMap[x + y * mapWidth] = (short)((data[x * xoff + y * yoff * imgw] & 0x000000ff) * 10);
            }
        }       

        // 释放
        data = null;
        img = null;
        System.gc();
    }
   
   
    //在xz平面平移转换
    public void setTransform(Transform t)
    {
        for(int x = 0; x < map.length - 1; x++)
        {
            for(int y = 0; y < map[x].length - 1; y++)
            {
                localTransform.setIdentity();
               
                localTransform.postTranslate(x * 20.4f, 0.0f, (mapHeight - y) * -20.4f);
                localTransform.postScale(0.04f, 0.04f, 0.04f);
                localTransform.postMultiply(t);
                map[x][y].setTransform(localTransform);
            }
        }
    }
       
   
    public static Mesh createQuad(short[] heights)
    {
        // 四边形顶点
        short[] POINTS = {-255, heights[0], -255,
                255, heights[1], -255,
                255, heights[2], 255,
                -255, heights[3], 255};
       
      

        POSITION_ARRAY = new VertexArray(POINTS.length/3, 3, 2);
        POSITION_ARRAY.set(0, POINTS.length/3, POINTS);
       
       
        byte[] COLORS = new byte[12];
       
        short[] TEXCOORDS = {
        0,0,   1,0,
        1,1,   0,1  
        };
        TEXCOORD_ARRAY = new VertexArray(TEXCOORDS.length/2, 2, 2);
        TEXCOORD_ARRAY.set(0, TEXCOORDS.length/2, TEXCOORDS);

       
       
        vertexBuffer = new VertexBuffer();
        vertexBuffer.setPositions(POSITION_ARRAY, 1.0f, null);

        vertexBuffer.setTexCoords(0, TEXCOORD_ARRAY, 1.0f, null);
       
        int INDICES[] = new int[] {0, 1, 3, 2};
        int[] LENGTHS = new int[] {4};
       
        //创建索引缓冲
        indexBuffer = new TriangleStripArray(INDICES, LENGTHS);

       
        appearance = new Appearance();
        polygonmode = new PolygonMode();
        polygonmode.setCulling(PolygonMode.CULL_NONE);
        polygonmode.setPerspectiveCorrectionEnable(true);
        polygonmode.setShading(PolygonMode.SHADE_SMOOTH);
        appearance.setPolygonMode(polygonmode);
        createTexture();
        appearance.setTexture(0, texture);
       
        Mesh mesh = new Mesh(vertexBuffer, indexBuffer, appearance);

       
        return mesh;
    }
 

}

 

下面是屏幕控制类Canvas的代码:

public class DesertCanvas extends GameCanvas implements Runnable {

    //新建场景对象
    private World world;
    // 状态量
    public static boolean gameOver = false;
   
    // 渲染
    public static final int STRONG_RENDERING_HINTS = Graphics3D.TRUE_COLOR | Graphics3D.DITHER;
    public static final int WEAK_RENDERING_HINTS = 0;
    public static int RENDERING_HINTS = STRONG_RENDERING_HINTS;
   
   
    boolean[] key = new boolean[9];
   
   
    private Transform identity = new Transform();
   
    // 3D画笔对象
    private Graphics3D g3d = null;
   
    // 背景
    private Background back = null;
   
    // 摄像机对象
    private Camera camera = null;
    private Transform camTrans = new Transform();
   
    private HeightMap heightmap;
    private Transform t = new Transform();
    private Mesh[][] map;
   
   
    public DesertCanvas()
    {
       
        super(true);
        setFullScreenMode(true);
        g3d = Graphics3D.getInstance();    
        world = new World();
       
        createMap();
        map = heightmap.getQuads(); 
        for(int x = 0; x < heightmap.getMapWidth()-1; x++)
        {
            for(int y = 0; y < heightmap.getMapHeight()-1; y++)
            {
               world.addChild(map[x][y]);
            }
        } 
      
       
        camera = new Camera();
        float aspect = (float) getWidth() / (float) getHeight();
        camera.setPerspective(60.0f, aspect, 0.1f, 150.0f);
       camTrans.postTranslate(0.0f, 20.0f, 0.0f);
        camera.setTransform(camTrans);
        world.addChild(camera);
        world.setActiveCamera(camera);
 
        back = new Background();
        back.setColor(0);
        world.setBackground(back);
       

        Thread t = new Thread(this);
        t.start();
    }
   
   
  
    private void createMap()
    {
        try
        {
           
         heightmap = new HeightMap();       
         Transform t = new Transform();
         t.postTranslate(0.0f, -5.0f, -5.0f);
         heightmap.setTransform(t);

        
        }
        catch(Exception e)
        {
            System.out.println("Heightmap error: " + e.getMessage());
            e.printStackTrace();

        }
    }

       
    private void draw(Graphics g)
    {
       
        try
        {           
           
          g3d = Graphics3D.getInstance();
           
        
         g3d.bindTarget(g, true, RENDERING_HINTS);

         g3d.render(world);
        

        }
        catch(Exception e)
        {
          System.out.println(e.getMessage());
          System.out.println(e);
          e.printStackTrace();
        }
        finally
        {
            g3d.releaseTarget();
        }
    }

   
   
    public void run() {
        while(true) {
            try {               
               
                input();
               
              
                draw(getGraphics());
                flushGraphics();
               
               
                try{ Thread.sleep(30); } catch(Exception e) {}
            }
            catch(Exception e) {
               System.out.println(e.getMessage());
               System.out.println(e);
               e.printStackTrace();
            }
        }

    }

    protected void input()
    {
        int keys = getKeyStates();
       if((keys & GameCanvas.FIRE_PRESSED) != 0)
          camTrans.postTranslate(0.0f, 0.0f, -1.0f);
       
        if((keys & GameCanvas.UP_PRESSED) != 0)
          camTrans.postTranslate(0.0f, 1.0f, 0.0f);
       
        if((keys & GameCanvas.DOWN_PRESSED) != 0)
          camTrans.postTranslate(0.0f, -1.0f, 0.0f);
       
        if((keys & GameCanvas.LEFT_PRESSED) != 0)
         camTrans.postRotate(5, 0.0f, 1.0f, 0.0f);
       
        if((keys & GameCanvas.RIGHT_PRESSED) != 0)
         camTrans.postRotate(-5, 0.0f, 1.0f, 0.0f);
         camera.setTransform(camTrans) ;

    }

 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值