J2ME 3D地图纹理小例子

    技术2022-05-20  58

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

        }

     }

     


    最新回复(0)