全位运算实现的俄罗斯方块 J2ME版

来源:互联网 发布:nba历届常规赛mvp数据 编辑:程序博客网 时间:2024/06/11 11:08
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;        }}}