import java.util.Random;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Graphics;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;public class TetrisMidlet extends MIDlet{private GameCanvas gameCanvas = null;private Display dis = null;public TetrisMidlet(){long[] shapes = {0x88c002e06220e80l, 0x8e02260e200c88l, 0x8c8004e02620e40l, 0xcc00cc00cc00ccl, 0x6c08c4006c08c4l, 0xc604c800c604c8l, 0x8888000f8888000fl};Shape player = new Shape(shapes[0]);GameRound round = new GameRound(shapes, player, (byte)32, (byte)15, (byte)7, (byte) 7);GameCanvas panel = new GameCanvas(round, player);gameCanvas = new GameCanvas(round,player);dis = Display.getDisplay(this);}protected void destroyApp(boolean arg0) throws MIDletStateChangeException{}protected void pauseApp(){}protected void startApp() throws MIDletStateChangeException{System.out.println("11111");dis.setCurrent(gameCanvas);gameCanvas.repaint();}class GameCanvas extends Canvas implements Runnable{public static final int VK_UP = -1;public static final int VK_DOWN = -2;public static final int VK_LEFT = -3;public static final int VK_RIGHT = -4;public static final int VK_FIRE = -5;public static final int VK_SOFT2 = -7;private GameRound round;private Shape player;public GameCanvas(GameRound round, Shape player){//super(false);setFullScreenMode(true);this.round = round; this.player = player; new Thread(this).start();}public void paint(Graphics g){ //清屏 g.setColor(-1);g.fillRect(0, 0, 800, 480);g.setColor(0);g.drawRect(0, 0, 799, 479);round.show(g);player.show(g);}public void run(){long taken = System.currentTimeMillis();long keyTaken = System.currentTimeMillis(); while(true) { if(System.currentTimeMillis() - taken > 1000) { taken = System.currentTimeMillis(); keyEvent(VK_DOWN); } if(System.currentTimeMillis() - keyTaken > 50 && keepKeyCode != Integer.MAX_VALUE) { keyTaken = System.currentTimeMillis(); keyEvent(keepKeyCode); } repaint(); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }}public void keyPressed(int keycode) { keepKeyCode = keycode; }protected void keyReleased(int keyCode) {keepKeyCode = Integer.MAX_VALUE; }int keepKeyCode = Integer.MAX_VALUE;public void keyEvent(int keycode){switch(keycode) { case VK_DOWN: round.moveDown(); break; case VK_LEFT: round.moveLeft(); break; case VK_RIGHT: round.moveRight(); break; case VK_UP: round.moveUp(); break; case VK_FIRE: byte oldleft = player.getBoundsLeft(); byte oldright = player.getBoundsRight(); player.nextFrame(); if(round.collide(0, 0)) { player.prevFrame(); } else {if(player.getX() < 0){player.setX((byte)(player.getX() + (oldleft - player.getBoundsLeft())));}else if(player.getX() > 31- 3){player.setX((byte)(player.getX() - (oldright - player.getBoundsRight())));}} break; case VK_SOFT2: System.exit(0); break;}}}private static class GameRound{private final byte GAME_ROUND_WIDTH;private final byte GAME_ROUND_HEIGHT;private final byte GAME_TILE_WIDTH;private final byte GAME_TILE_HEIGHT;private final long[] SHAPES;private final int[] GAME_DATA;private Shape player;private Random ran = new Random(); public GameRound(long[] shapes, Shape player, byte width, byte height, byte twidth, byte theight) { //初始化游戏区域的宽和高 //该宽高并不是实际的宽高 //而是指横、纵格子的数量 GAME_ROUND_WIDTH = width; GAME_ROUND_HEIGHT = height; //初始化每个格子的宽和高 GAME_TILE_WIDTH = twidth; GAME_TILE_HEIGHT = theight; SHAPES = shapes; this.player = player; GAME_DATA = new int[GAME_ROUND_HEIGHT]; GAME_DATA[GAME_ROUND_HEIGHT - 2] = 0xaaaaaaaa; GAME_DATA[GAME_ROUND_HEIGHT - 1] = -1; } public void show(Graphics g) { g.setColor(0xFFFFFF);g.fillRect(0, 0, 800, 480);g.setColor(0xFF0000);g.drawRect(0, 0, 799, 479);//渲染数据区 for (int i = 0; i < GAME_ROUND_WIDTH; i++) { for (int j = 0; j < GAME_ROUND_HEIGHT; j++) { if(((GAME_DATA[j] >> GAME_ROUND_WIDTH-1-i) & 1) == 1) g.setColor(0xFF0000); else g.setColor(0x00FF00); g.fillRect(i * GAME_TILE_WIDTH, j * GAME_TILE_HEIGHT, GAME_TILE_WIDTH, GAME_TILE_HEIGHT); g.setColor(0x000000); g.drawRect(i * GAME_TILE_WIDTH, j * GAME_TILE_HEIGHT, GAME_TILE_WIDTH, GAME_TILE_HEIGHT); } } } public void moveDown() { if(player.getY() < 14 - 3 + player.getBoundsButtom()) { if(!collide(0,1)) player.y++; else shapeDown(); } else shapeDown(); } public void moveUp() { if(!collide(0, -1)) { player.y--; } } public void moveLeft() { if(player.getX() > 0 - player.getBoundsLeft()) { if(!collide(-1,0)) player.x--; } } public void moveRight() { if(player.getX() < 31 - 3 + player.getBoundsRight()) { if(!collide(+1,0)) player.x++; } } public boolean collide(int x, int y) { int a,b; for (int shift = player.getBoundsButtom(); shift < 4; shift++) { if(player.getX() < 0)a = (((((int)player.getFrameData() << (16 + ((3 - shift) << 2) - (player.getX() + x)))) & 0xf0000000));elsea = (((((int)player.getFrameData() << (16 + ((3 - shift) << 2)))) & 0xf0000000) >>> player.getX() + x); b = (GAME_DATA[player.getY() + 3 - shift + y]); if( (a & b) != 0) { return true; } } return false; } public void shapeDown() { int down = 0; if(player.getY() >= 12) down = player.getY()+3; else down = player.getY() + 3; for (int shift = player.getBoundsButtom(); shift < 4; shift++) { if(player.getX() > -1) GAME_DATA[down-shift] |= (((((int)player.getFrameData() << (16 + ((3 - shift) << 2)))) & 0xf0000000) >>> player.getX()); else GAME_DATA[down-shift] |= (((((int)player.getFrameData() << (16 + ((3 - shift) << 2) - player.getX()))) & 0xf0000000)); } for (int i = GAME_DATA.length - 1; i >= 0; i--) { if(GAME_DATA[i] == -1) { int[] tmp = new int[i]; System.arraycopy(GAME_DATA, 0, tmp, 0, tmp.length); System.arraycopy(tmp, 0, GAME_DATA, 1, tmp.length); } } randomShape(); } public void randomShape() { player.initShape(SHAPES[Math.abs(ran.nextInt() % 7)], (byte)(Math.abs(ran.nextInt() % 4))); } }private static class Shape{private long data;private byte curr_frame;private short frame_data;private byte bounds_left;private byte bounds_right;private byte bounds_buttom;private byte x;private byte y;public Shape(long data) { this(data, (byte)0); }public Shape(long data, byte curr_frame) { initShape(data, curr_frame); }public void initShape(long data, byte curr_frame){this.data = data; setCurrentFrame(curr_frame); initBounds(); setX((byte)14); setY((byte)0);}public short getFrameData(){return this.frame_data;}public void show(Graphics g){for (int shift = 0; shift < 4; shift++) { for (int bit = 0; bit < 4; bit++) { if((((frame_data >> ((3 - shift) << 2)) >> (3 - bit)) & 1) == 1) { g.setColor(0x0000FF); g.fillRect((x + bit) * 7, (y+shift) * 7, 7, 7); } }}g.setColor(0xFFFF00);g.drawRect(x * 7 + 1, y * 7 + 1, 28, 28);}public void nextFrame(){setCurrentFrame(++curr_frame > 3 ? 0 : curr_frame);initBounds();}public void prevFrame(){setCurrentFrame(--curr_frame < 0 ? 3 : curr_frame);initBounds();}private void setCurrentFrame(byte curr_frame){this.curr_frame = curr_frame;this.frame_data = (short) (data >> ((3 - curr_frame) << 4));}private void initBounds(){bounds_left = 0;if((frame_data & 0x8888) == 0){if((frame_data & 0x4444) == 0){if((frame_data & 0x2222) == 0)bounds_left = 3;elsebounds_left = 2;}elsebounds_left = 1;}bounds_right = 0;A:if((frame_data & 0x1111) == 0){if((frame_data & 0x2222) == 0){if((frame_data & 0x4444) == 0){bounds_right = 3;break A;}bounds_right = 2;break A;}bounds_right = 1;}bounds_buttom = 0;A:if((frame_data & 0x000f) == 0){if((frame_data & 0x00f0) == 0){if((frame_data & 0x0f00) == 0){bounds_buttom = 3;break A;}bounds_buttom = 2;break A;}bounds_buttom = 1;}}public byte getBoundsLeft(){return bounds_left;}public byte getBoundsRight(){return bounds_right;}public byte getBoundsButtom(){return bounds_buttom;}public byte getX() { return x; }public void setX(byte x) { this.x = x; }public byte getY() { return y; }public void setY(byte y) { this.y = y; }}}