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

📄 life3d.java

📁 手机的资源有限
💻 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, Font.SIZE_LARGE, 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 + -