////// Inner class Message /////////
    private class Message
    {
        public static final int MOVE_UP = 1;
        public static final int MOVE_DOWN = 2;
        public static final int MOVE_LEFT = 3;
        public static final int MOVE_RIGHT = 4;
        public static final int ROTATE_CLOCK = 5; //rotate clock-wise
        public static final int ROTATE_ANTICLOCK = 6;//rotate anticlock-wise
        public Message(int action)
        {
            this.action = action;
        }
        public int getAction()
        {
            return this.action;
        }
        private int action;
    }
    //////  Inner class Queue  ///////
    //////////// fields of class Game ////////////////
    private Board m_board = new Board(); //仅由消息处理器线程访问
    private Block m_block = null; //当前存在的块
    private MessageQueue m_msgQueue = new MessageQueue(); //由消息处理器和awt线程访问
    private BlockDataPoolQueue m_blockDataPoolQueue = new BlockDataPoolQueue();
    private int m_S = 0;
    ///// method run  主消息处理处理线程
    public void run()
    {
        boolean bkdataPool[][][] ={
            {{false,false,true,false,false},
            {false,false,true,false,false},
            {false,false,true,false,false},
            {false,false,true,false,false},
            {false,false,true,false,false}},
            {{false,false,false,false,false},
            {false,true,true,true,false},
            {false,false,true,false,false},
            {false,false,true,false,false},
            {false,false,true,false,false},
            {false,false,false,false,false}},
            {{false,false,false,false,false},
            {false,false,true,false,false},
            {false,true,true,true,false},
            {false,false,true,false,false},
            {false,false,false,false,false}},
            {{false,false,false,false,false},
            {false,false,false,false,false},
            {false,true,true,true,false},
            {false,true,false,true,false},
            {false,false,false,false,false}},
            {{false,false,false,false,false},
            {false,false,false,false,false},
            {false,true,true,true,false},
            {false,false,true,false,false},
            {false,false,false,false,false}}};
            repaintRequest();
            while(true)
            {
                switch(m_S)
                {
                    case 0:
                        try
                        {
                            Thread.currentThread().sleep(50);
                        }
                        catch (InterruptedException ex)
                        {
                        }
                        break;
                    case 1:
                        Block bk1 = new Block(m_blockDataPoolQueue.getNextBlockData(),0,(BDWIDTH-BKSIZE)/2);
                        if( ! isCollided(m_board,bk1)){
                            m_block = bk1;
                            m_S = 2;
                        }else
                            m_S = 3;
                        repaintRequest();
                        break;
                    case 2:
                        Message msg;
                        synchronized(m_msgQueue) //等待新的消息
                        {
                            while(m_msgQueue.empty()){
                                try{
                                    m_msgQueue.wait();
                                }catch(InterruptedException e){
                                }
                            }
                            msg = (Message)m_msgQueue.dl();
                        }
                        Block bk2 = new Block(m_block);
                        bk2.doAction(msg.getAction());
                        if(! isCollided(m_board,bk2)){ //动作可以执行
                            m_block.doAction(msg.getAction());
                            m_S = 2;
                            repaintRequest();
                        }else if(msg.getAction()==Message.MOVE_DOWN){ //向下移动的动作不能执行
                            merge(m_board,m_block);
                            m_block = null;
                            packUpBoard(m_board);
                            m_S = 1;
                            repaintRequest();
                        }
                        break;
                    case 3:
                        try
                        {
                            Thread.currentThread().sleep(50);
                        }
                        catch (Exception ex)
                        {
                        }
                        break;
                }
            }
    }
    ///// method isClllided /////
    private boolean isCollided(final Block bk1,final Block bk2) //判断两方块是否重叠
    {
        for(int r1=0; r1<BKSIZE; r1++)
        {
            int r2 = r1+bk1.rpos-bk2.rpos;
            if(r2>=0 && r2<BKSIZE)
            {
                for(int c1=0; c1<BKSIZE; c1++)
                {
                    int c2 = c1+bk1.cpos-bk2.cpos;
                    if(c2>=0 && c2<BKSIZE)
                        if(bk1.bkdata[r1][c1] && bk2.bkdata[r2][c2])
                            return true;
                }
            }
        }
        return false;
    }
    private boolean isCollided(final Board board,final Block block) //判断某方块与某底板是否重叠
    {
        for(int i=0; i<BKSIZE; i++){
            for(int j=0; j<BKSIZE; j++){
                if(block.rpos+i>=0 && block.rpos+i<BDHEIGHT && block.cpos+j>=0 && block.cpos+j<BDWIDTH){
                    if(block.bkdata[i][j] && board.bddata[i+block.rpos][j+block.cpos])
                        return true;
                    }else if(block.bkdata[i][j])
                        return true;
            }
        }
        return false;
    }
    private void merge(Board board,final Block block) //合并board <=== block
    {
        for(int i=0; i<BKSIZE; i++)
            for(int j=0; j<BKSIZE; j++)
                if(block.rpos+i>=0 && block.rpos+i<=BDHEIGHT-1 && block.cpos+j>=0 && block.cpos+j<=BDWIDTH-1)
                    board.bddata[block.rpos+i][block.cpos+j] |= block.bkdata[i][j];
    }
    private int packUpBoard(Board board) //消去满行
    {
        int linesDeleted = 0;
        for(int i=BDHEIGHT-1; i>=0;){ //检测第i行
            boolean full = true;
            for(int j=0; j<BDWIDTH; j++){
                if(! board.bddata[i][j]){
                    full = false;
                    break;
                }
            }
            if(full){ //第i行为满行
                for(int k=i-1; k>=0; k--){
                    for(int c=0; c<BDWIDTH; c++)
                        board.bddata[k+1][c] = board.bddata[k][c];
                }
                for(int c=0; c<BDWIDTH; c++)
                    board.bddata[0][c] = false;
                linesDeleted++;
            }else
                i--;
        }
        return linesDeleted;
    }

解决方案 »

  1.   

    //Constructor
        final int X0 = 10, Y0 = 15;
        final int CELLSIZE = 12;
        public java.awt.Dimension getPreferredSize()
        {
            return new java.awt.Dimension(2*X0+CELLSIZE*BDWIDTH,2*Y0+CELLSIZE*BDHEIGHT);
        }
        public GameCanvas()
        {
            setBackground(java.awt.Color.black);
            addKeyListener(new java.awt.event.KeyAdapter(){
                public void keyPressed(java.awt.event.KeyEvent e)
                {
                    switch(e.getKeyCode()){
                        case java.awt.event.KeyEvent.VK_LEFT:
                            postMessage(new Message(Message.MOVE_LEFT));
                            break;
                        case java.awt.event.KeyEvent.VK_RIGHT:
                            postMessage(new Message(Message.MOVE_RIGHT));
                            break;
                        case java.awt.event.KeyEvent.VK_DOWN:
                            postMessage(new Message(Message.MOVE_DOWN));
                            break;
                        case java.awt.event.KeyEvent.VK_UP:
                            postMessage(new Message(Message.ROTATE_CLOCK));
                            break;
                        case java.awt.event.KeyEvent.VK_ENTER:
                            postMessage(new Message(Message.ROTATE_ANTICLOCK));
                            break;
                        case java.awt.event.KeyEvent.VK_PAGE_UP:
                            postMessage(new Message(Message.MOVE_UP));
                            break;
                        case java.awt.event.KeyEvent.VK_SPACE:
                            if(m_S==0)
                                m_S = 1;
                            break;
                        case java.awt.event.KeyEvent.VK_F1:
                            if(m_S==3){
                                m_board.clear();
                                m_S = 0;
                                repaintRequest();
                            }
                    }
                }
            });
            new Thread(){
                public void run()
                {
                    while(true){
                        try{
                            sleep(500);
                        }catch(InterruptedException e){
                        }
                        postMessage(new Message(Message.MOVE_DOWN));
                    }
                }
                }.start();
            new Thread(this).start(); //消息处理线程
        }
        public void postMessage(Message msg)
        {
            if(m_S==1 || m_S==2){
                synchronized(m_msgQueue){
                    m_msgQueue.en(msg);
                    m_msgQueue.notify();
                }
            }
        }
        public void repaintRequest()
        {
            repaint();
        }
        public void paint(java.awt.Graphics g)
        {
            //draw m_board
            g.setColor(java.awt.Color.blue);
            g.drawRect(X0,Y0,CELLSIZE*BDWIDTH-1,CELLSIZE*BDHEIGHT-1);
            switch(m_S){
                case 1:
                case 2:
                    g.setColor(java.awt.Color.yellow);
                    break;
                case 3:
                    g.setColor(java.awt.Color.lightGray);
                    break;
            }
            for(int i=0,y=Y0; i<BDHEIGHT; i++,y+=CELLSIZE){
                for(int j=0,x=X0; j<BDWIDTH; j++,x+=CELLSIZE){
                    if(m_board.bddata[i][j])
                        g.fillRect(x,y,CELLSIZE-1,CELLSIZE-1);
                }
            }
            //draw next block show
            g.setColor(java.awt.Color.lightGray);
            boolean nextBlockData[][] = m_blockDataPoolQueue.peekNextBlockData();
            for(int i=0,y=Y0; i<BKSIZE; i++,y+=CELLSIZE){
                for(int j=0,x=X0+(BDWIDTH-BKSIZE)*CELLSIZE; j<BKSIZE; j++,x+=CELLSIZE){
                    if(nextBlockData[i][j])
                        g.drawRect(x+1,y+1,CELLSIZE-1,CELLSIZE-1);
                }
            }
            //draw m_block
            if(m_S==2){
                g.setColor(java.awt.Color.red);
                for(int i=0,y=Y0+m_block.rpos*CELLSIZE; i<BKSIZE; i++,y+=CELLSIZE){
                    for(int j=0,x=X0+m_block.cpos*CELLSIZE; j<BKSIZE; j++,x+=CELLSIZE){
                        if(m_block.bkdata[i][j])
                            g.fillRect(x,y,CELLSIZE-1,CELLSIZE-1);
                    }
                }
            }
            g.setColor(java.awt.Color.red);
            g.setFont(new java.awt.Font(g.getFont().getFontName(),g.getFont().getStyle(),16));
            switch(m_S){
                case 0:
                    g.drawString("按空格键开始游戏!",50,100);
                    break;
                case 3:
                    g.drawString("游戏结束,按F1键重新开始!",20,100);
                    break;
            }
        }
      

  2.   

    private class BlockDataPoolQueue extends Queue
        {
            public BlockDataPoolQueue(){ this.currentBlockData = bkdataPool[ran.nextInt(bkdataPool.length)]; }
            public boolean[][] peekNextBlockData()
            {
                return this.currentBlockData;
            }
            public boolean[][] getNextBlockData()
            {
                boolean[][] bkd = this.currentBlockData;
                this.currentBlockData = bkdataPool[ran.nextInt(bkdataPool.length)];
                return bkd;
            }
            private boolean[][] currentBlockData = null;
            private java.util.Random ran = new java.util.Random();
            private boolean bkdataPool[][][] ={
                {{false,false,true,true,false},
                {false,false,true,false,false},
                {false,false,true,false,false},
                {false,true,true,false,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,true,true,false,false},
                {false,false,true,false,false},
                {false,false,true,true,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,false,true,false,false},
                {false,true,true,true,false},
                {false,false,true,false,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,false,false,false,false},
                {false,true,true,true,false},
                {false,false,false,true,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,true,false,false,false},
                {false,false,true,false,false},
                {false,false,false,false,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,false,false,false,false},
                {false,false,true,false,false},
                {false,false,false,false,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,true,true,false,false},
                {false,true,true,false,false},
                {false,false,false,false,false},
                {false,false,false,false,false}},
                {{false,false,false,false,false},
                {false,false,false,false,false},
                {false,true,true,true,false},
                {false,false,true,false,false},
                {false,false,false,false,false}}};
        }
        private class Queue
        {
            private Node head;
            private Node tail;
            public Queue()
            {
                head = new Node();
                tail = new Node();
                head.prev = tail.next = null;
                head.next = tail;
                tail.prev = head;
            }
            public void en(Object item)
            {
                Node q = new Node();
                q.data = item;
                q.next = tail;
                q.prev = tail.prev;
                tail.prev.next = q;
                tail.prev = q;
            }
            public Object dl()
            {
                if(! empty()){
                    Node p = head.next;
                    head.next.next.prev = head;
                    head.next = head.next.next;
                    return p.data;
                }else
                    return null;
            }
            public Object peek()
            {
                if(! empty())
                    return head.next.data;
                else
                    return null;
            }
            public boolean empty()
            {
                return (head.next==tail) || (tail.prev==head);
            }
            public void clear()
            {
                head.next = tail;
                tail.prev = head;
            }
            public int elemNum()
            {
                int num = 0;
                for(Node q=head.next; q!=tail; q=q.next)
                    num++;
                return num;
            }
            private class Node
            {
                Object data;
                Node prev;
                Node next;
            }
        }
        //inner class MessageQueue
        private class MessageQueue
        {
            private Node head;
            private Node tail;
            public MessageQueue()
            {
                head = new Node();
                tail = new Node();
                head.prev = tail.next = null;
                head.next = tail;
                tail.prev = head;
            }
            public void en(Message msg)
            {
                Node p = new Node();
                p.message = msg;
                p.next = tail;
                p.prev = tail.prev;
                tail.prev.next = p;
                tail.prev = p;
            }
            public Message dl()
            {
                if(! empty()){
                    Node p = head.next;
                    head.next.next.prev = head;
                    head.next = head.next.next;
                    return p.message;
                }else
                    return null;
            }
            public Message peek() //应先使用empty来检查
            {
                if(! empty())
                    return head.next.message;
                else
                    return null;
            }
            public boolean empty()
            {
                return (head.next==tail) || (tail.prev==head);
            }
            public void clear()
            {
                head.next = tail;
                tail.prev = head;
            }
            private class Node
            {
                Message message;
                Node prev;
                Node next;
            }
        }
    }
      

  3.   

    能不能提供文档啊
    就是多点解释,我看的好费劲啊!!
    fewer charactor!谢谢!!
      

  4.   

    同意,能发源文件吗?
    [email protected]
      

  5.   

    给点注释吧   累死了了
    [email protected]
      

  6.   

    给点注释吧
    [email protected]
      

  7.   

    谢谢楼主
    给点注释吧
    [email protected]
    再次谢谢
      

  8.   

    话说没有注释的代码是不规范的代码,呵呵,给点注释吧!
    [email protected]
      

  9.   

    好厉害!
    [email protected]
      

  10.   

    能给我一份源代码吗!谢谢,,[email protected]顶!!·!
      

  11.   

    能给我一份源代码吗!谢谢,,[email protected]
      

  12.   

    能给我一份源代码吗!谢谢
    [email protected]
      

  13.   

    我来晚了,也给我一份吧[email protected]
      

  14.   

    楼主:
        我是新手啊!楼主给我也发一份吧!单人版的和多人版的都要啊,不要说我贪心啊!
        E-mail:[email protected]
        谢了!
      

  15.   

    给一份我吧[email protected]谢谢~~~
      

  16.   

    我也想要。  
    [email protected]谢谢~~~
      

  17.   

    单人版的和多人版的我都要。  
    [email protected]谢谢~~~
      

  18.   

    我也想要啊!
    [email protected]
      

  19.   

    人气很旺啊 还没来得及看程序Mark一下 呵呵
      

  20.   

    辛苦你了!非常感谢!
    发个注释文档及源程序。
    [email protected]
      

  21.   

    辛苦你了!非常感谢!
    发个注释文档及源程序。
    [email protected]
      

  22.   

    辛苦楼主了,没来晚吧
    [email protected]
      

  23.   

    不停地发E-mail真的很烦啊,但我也想要一份,楼主,谢了
    [email protected]