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

📄 life3d.java

📁 j2me 3D demo,是关于手机开发3D游戏的一个小demo,供参考
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                    float y = ((j * 2) - CUBESIZE) * 0.5f;                    for (int k = 0; k < CUBESIZE; k++) {                        float z = ((k * 2) - CUBESIZE) * 0.5f;                        Mesh m = new Mesh(vertexBuffer, iba, appa);                        m.setTranslation(x, y, z);                        rootGroup.addChild(m);                        // This test gives a 1 in 4 chance of being alive at the start                        currentState[index] = (rand.nextInt() > 0x40000000) ? (byte)1 : (byte)0;                        cells[index++] = m;                    }                }            }            // Attach to display            myDisplay.setCurrent(myCanvas);            // Force a repaint so that we get the update loop started.            myCanvas.repaint();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     *        If cell[i] is alive, this increments the "live neighbor" count         *        on all the neighboring cells. This is more efficient than counting         *        the neighboring cells for each cell, because there are likely to be         *        fewer live cells than dead cells.         *         *        The cube wraps around, so that the neighbor to the right of a cell         *        in the last row is in fact in the first row. The same happens with         *        columns and planes. We speed things up here by using bit operations         *        to effect this wrapping (which is why CUBESIZE must be a power of 2)         *        and we also unroll the loop.     */    public void updateNeighbours(int i) {        if (currentState[i] != 0) {            int ix0 = (i - STEPX) & MASKX;            int iy0 = (i - STEPY) & MASKY;            int iz0 = (i - STEPZ) & MASKZ;            int ix1 = (i) & MASKX;            int iy1 = (i) & MASKY;            int iz1 = (i) & MASKZ;            int ix2 = (i + STEPX) & MASKX;            int iy2 = (i + STEPY) & MASKY;            int iz2 = (i + STEPZ) & MASKZ;            ++nextState[ix0 | iy0 | iz0];            ++nextState[ix0 | iy0 | iz1];            ++nextState[ix0 | iy0 | iz2];            ++nextState[ix0 | iy1 | iz0];            ++nextState[ix0 | iy1 | iz1];            ++nextState[ix0 | iy1 | iz2];            ++nextState[ix0 | iy2 | iz0];            ++nextState[ix0 | iy2 | iz1];            ++nextState[ix0 | iy2 | iz2];            ++nextState[ix1 | iy0 | iz0];            ++nextState[ix1 | iy0 | iz1];            ++nextState[ix1 | iy0 | iz2];            ++nextState[ix1 | iy1 | iz0];            //!		++nextState[ix1|iy1|iz1];            ++nextState[ix1 | iy1 | iz2];            ++nextState[ix1 | iy2 | iz0];            ++nextState[ix1 | iy2 | iz1];            ++nextState[ix1 | iy2 | iz2];            ++nextState[ix2 | iy0 | iz0];            ++nextState[ix2 | iy0 | iz1];            ++nextState[ix2 | iy0 | iz2];            ++nextState[ix2 | iy1 | iz0];            ++nextState[ix2 | iy1 | iz1];            ++nextState[ix2 | iy1 | iz2];            ++nextState[ix2 | iy2 | iz0];            ++nextState[ix2 | iy2 | iz1];            ++nextState[ix2 | iy2 | iz2];        }    }    /**     *        Works out current alive/dead state based on neighbour count.     *        If a cell is alive, it will die of loneliness if it has at fewer than     *        minSurvive neighbors, but if it has more than maxSurvive neighbors it     *        will die of overcrowding. If a cell has between minBirth and maxBirth     *        neighbours, and it is currently dead, a new cell is born in that position.     */    public void updateState(int i) {        byte count = nextState[i];        nextState[i] = 0;        if (currentState[i] == 0) {            currentState[i] = ((count >= minBirth) && (count <= maxBirth)) ? (byte)1 : (byte)0;        } else {            currentState[i] = ((count >= minSurvive) && (count <= maxSurvive)) ? (byte)1 : (byte)0;        }        // After calculating the new state, set the appropriate rendering enable for the        // cell object in the world, so we can see it. We take advantage of this test to        // count the current live population, too.        if (currentState[i] != 0) {            cells[i].setRenderingEnable(true);            ++population;        } else {            cells[i].setRenderingEnable(false);        }    }    /**     * On pause, simply shut everything down.     */    public void pauseApp() {        myRefreshTask.cancel();        myRefreshTask = null;        // Release resources.        myWorld = null;    }    /**     * On exit, simply shut everything down     */    public void destroyApp(boolean unconditional) throws MIDletStateChangeException {        myRefreshTimer.cancel();        myRefreshTimer = null;        myRefreshTask = null;        // Release resources.        myWorld = null;        myCanvas = null;    }    /**     *        MIDlet paint method.     *     *         This is called back from the inner Canvas class. It renders the current state of the     *        cells, then updates them and schedules another update.     */    public void paint(Graphics g) {        // We are not fully initialised yet; just return.        if ((myCanvas == null) || (myWorld == null)) {            return;        }        // If this was a scheduled update, cancel the timer task that caused it.        if (myRefreshTask != null) {            myRefreshTask.cancel();            myRefreshTask = null;        }        // Render the world to our Graphics (the screen) using the m3g class Graphics3D        // Note the use of try/finally to ensure that the Graphics3D always releases        // the target no matter what happens.        Graphics3D myGraphics3D = Graphics3D.getInstance();        myGraphics3D.bindTarget(g);        try {            myGraphics3D.render(myWorld);        } finally {            myGraphics3D.releaseTarget();        }        // Draw information about the pattern: its name, the number of generations,        // and the number of live cells.        g.setColor(0xFFFFFFFF);        g.drawString(generations + " : " + population, 0, 10, Graphics.LEFT | Graphics.TOP);        g.drawString(patternName, 0, 0, Graphics.LEFT | Graphics.TOP);        // Always rotate slowly. We set the orientation of rootGroup to achieve this,        // rotating it about its local Y (vertical) axis.        angle += 1.0f;        rootGroup.setOrientation(angle, 0.0f, 1.0f, 0.0f);        // This deals with the speed setting. We have a countdown that is set to        // an initial value of "delay", and when it reaches 0, we update the cells.        // This allows us to keep rotating the view, even if generation is paused.        if (--delayCount <= 0) {            delayCount = delay;            ++generations;            // Garbage collect regularly            System.gc();            // Now calculate next frame            // Update all the cells            for (int i = 0; i < NUMCELLS; i++)                updateNeighbours(i);            population = 0;            for (int i = 0; i < NUMCELLS; i++)                updateState(i);            // If all the cells have died out, restart with a random state.            if (population == 0) {                loadRandomState();            }        }        // And schedule another repaint. This uses the Java timers to schedule        // another repaint in 50 milliseconds. This is more efficient than doing        // it immediately, and limits the frame rate to 20 frames/second. It also        // allows other applications some time!        myRefreshTask = new RefreshTask();        myRefreshTimer.schedule(myRefreshTask, 50);    }    /**     *        This loads the cell state from a string stored in the pattern library.     *        Each live cell is represented in the string using a triplet of characters     *        showing its x, y and z position. For example, the string "000" represents         *        a single live cell at the extreme bottom front right corner.     */    private void loadStateFromString(String positions) {        clear();        for (int i = 0; i < positions.length(); i += 3) {            int xx = (positions.charAt(i + 0) - '0') & (CUBESIZE - 1);            int yy = (positions.charAt(i + 1) - '0') & (CUBESIZE - 1);            int zz = (positions.charAt(i + 2) - '0') & (CUBESIZE - 1);            currentState[(((xx * CUBESIZE) + yy) * CUBESIZE) + zz] = 1;        }    }    /**     *        Clears the cell array to all dead.     */    private void clear() {        for (int i = 0; i < NUMCELLS; i++)            currentState[i] = 0;        generations = 0;    }    /**     *        Loads the cell array with a random state, with approximately 25%     *        of the cells alive.     */    private void loadRandomState() {        patternName = "Random";        for (int i = 0; i < NUMCELLS; i++)            currentState[i] = (rand.nextInt() > 0x40000000) ? (byte)1 : (byte)0;        generations = 0;    }    /**     *        Handle commands.     *        Currently, the only command enabled is "Exit" - this just     *        destroys the MIDlet immediately.     */    public void commandAction(Command cmd, Displayable disp) {        if (cmd == exitCommand) {            try {                destroyApp(false);                notifyDestroyed();            } catch (Exception e) {                e.printStackTrace();            }        }    }    /**     *        Handles key presses.     *         This is called back from the inner Canvas class, and implements     *        the behavior of the various keys outlined in the class summary.     */    public void keyPressed(int keyCode) {        switch (keyCode) {        // 0,1,2,3 are speed keys.        // 0: Pause - set a very long delay until the next update        case Canvas.KEY_NUM0:            delay = 1000000;            delayCount = 1000000;            break;        // 1: Full speed - set no delay until next update        case Canvas.KEY_NUM1:            delay = 0;            delayCount = 0;            break;        // 2: Speed up - if not already at full speed, decrease delay        case Canvas.KEY_NUM2:            if (delay > 0) {                delay--;            }            delayCount = 0;            break;        // 3: Slow down - if not already at minimum speed, increase delay        case Canvas.KEY_NUM3:            if (delay < 20) {                delay++;            }            delayCount = 0;            break;        // 4,5 are pattern keys        // 4: Select and load previous pattern in library. If at the        // start of the library, or using a random pattern, will start        // again at the last pattern.        case Canvas.KEY_NUM4:            pattern--;            if (pattern < 0) {                pattern = patternLibrary.length - 1;            }            patternName = patternLibrary[pattern][0];            loadStateFromString(patternLibrary[pattern][1]);            break;        // 5: Select and load next pattern in library. If at the        // end of the library, or using a random pattern, will start        // again at the first pattern.        case Canvas.KEY_NUM5:            pattern++;            if (pattern >= patternLibrary.length) {                pattern = 0;            }            patternName = patternLibrary[pattern][0];            loadStateFromString(patternLibrary[pattern][1]);            break;        // *: Loads a random state        case Canvas.KEY_STAR:            loadRandomState();            break;        }    }    /**    * Inner TimerTask-derived class for refreshing the view.    */    private class RefreshTask extends TimerTask {        public void run() {            // Get the canvas to repaint itself.            myCanvas.repaint();        }    }    /**     * Inner Canvas-derived class for handling canvas events.     */    private class CallbackCanvas extends Canvas {        Life3D mymidlet;        /**         * Construct a new canvas         */        CallbackCanvas(Life3D midlet) {            mymidlet = midlet;        }        /**         * Initialize self.         */        void init() {        }        /**         * Cleanup and destroy.         */        void destroy() {        }        /**         * Ask mymidlet to paint itself         */        protected void paint(Graphics g) {            mymidlet.paint(g);        }        protected void keyPressed(int keyCode) {            mymidlet.keyPressed(keyCode);        }    }}

⌨️ 快捷键说明

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