新手想写个贪吃蛇的游戏,还有很多问题没有完善,现在遇到的问题是addkeylistener添加不上求解!

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class SnakeGame extends JFrame{


    private static final int STONE_HIGHT = 30;
    //snakeZ表示蛇的前进方向1234分别代表东南西北
    private int snakeZ=1,foodX,foodY,length=3;
    private int m[]=new int[50];
    private int n[]=new int[50];
    private JPanel panel1,panel2;
    private JButton butStart,butEsc,butStop,butResume;
    private Canvas canvas=new Canvas()
    {
        public void paint( Graphics g )
        {
            drawStone(g);            
            drawSnake(g);
            drawNet(g);
        }
    };

    public SnakeGame()
    {
        setLayout(new BorderLayout());
        setBounds(300, 100, 600, 600);
        panel1=new JPanel();
        //panel1.setBackground(Color.red);
        panel2=new JPanel();
        //panel2.setBackground(Color.green);
        butStart=new JButton("开始游戏");
        butEsc=new JButton("退出");
        butStop=new JButton("暂停");
        butResume=new JButton("继续");

        add(panel1,BorderLayout.CENTER);
        add(panel2,BorderLayout.SOUTH);
        panel1.add(canvas);
        canvas.setSize(600, 540);
        canvas.setBackground(Color.gray);
        panel2.setLayout(new GridLayout(1,4));
        panel2.add(butEsc);
        panel2.add(butResume);
        panel2.add(butStart);
        panel2.add(butStop);

        m[0]=canvas.getWidth()/2;
        n[0]=canvas.getHeight()/2;
        for(int i=1;i<length;i++)
        {
            m[i]=m[i-1]+STONE_HIGHT;
            n[i]=n[i-1];
        }        
        //***************监听事件*************************
        //开始键监听事件
        butStart.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        thread t=new thread();
                        t.start();
                    }
                });
        //退出键监听事件
        butEsc.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        System.exit(0);
                    }
                });
        //暂停键监听事件
        butStop.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        System.out.println("暂停");
                    }
                });
        //继续键监听事件
        butResume.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        System.out.println("继续");
                    }
                });
        addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e) 
            {
                System.out.println("dfdsf");
                switch(e.getKeyCode())
                {
                case KeyEvent.VK_UP:
                    if(snakeZ!=2) { snakeZ=4;System.out.println("dfdsfsd");refresh();}break;
                case KeyEvent.VK_DOWN:
                    if(snakeZ!=4) {snakeZ=2;refresh();}break;
                case KeyEvent.VK_LEFT:
                    if(snakeZ!=1) {snakeZ=3;refresh();}break;
                case KeyEvent.VK_RIGHT:
                    if(snakeZ!=3) {snakeZ=1;refresh();}break;
                }

            }    
        });
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public class thread extends Thread
    {
        public void run()
        {
            while(true)
            {
                refresh();
                try
                {
                    Thread.sleep(500);
                }
                catch(InterruptedException e)
                {

                }
            }
        }
    }


    public void drawStone(Graphics g)
    {
        g.setColor(Color.DARK_GRAY);
        g.fillRect(0, 0, STONE_HIGHT, canvas.getHeight());
        g.fillRect(0, 0, canvas.getWidth(), STONE_HIGHT);
        g.fillRect(0, canvas.getHeight()-STONE_HIGHT, canvas.getWidth(), STONE_HIGHT);
        g.fillRect(canvas.getWidth()-STONE_HIGHT, 0, canvas.getWidth(), canvas.getHeight());

    }

    public void drawNet(Graphics g)
    {
        g.setColor(Color.white);
        for(int i=0;i<canvas.getWidth()/STONE_HIGHT;i++)
            g.drawLine(i*STONE_HIGHT, 0, i*STONE_HIGHT, canvas.getHeight());
        for(int i=0;i<canvas.getHeight()/STONE_HIGHT;i++)
            g.drawLine(0, i*STONE_HIGHT, canvas.getWidth(), i*STONE_HIGHT);        
    }

    public void drawSnake(Graphics g)
    {
        g.setColor(Color.blue);
        for(int i=0;i<length;i++)
            g.fillRect(m[i], n[i], STONE_HIGHT,STONE_HIGHT);
    }

    public void refresh()
    {
        switch(snakeZ)
        {
        case 1:

            for(int i=length;i>=0;i--)
            {
                m[i+1]=m[i];
                n[i+1]=n[i];
            }
            m[0]=m[0]+STONE_HIGHT;break;
        case 2:
            for(int i=length;i>=0;i--)
            {
                int tempX=m[i];
                int tempY=n[i];
                m[i+1]=tempX;
                n[i+1]=tempY;
            }
            n[0]=n[0]-STONE_HIGHT;break;
        case 3:
            for(int i=length;i>=0;i--)
            {
                int tempX=m[i];
                int tempY=n[i];
                m[i+1]=tempX;
                n[i+1]=tempY;
            }
            m[0]=m[0]-STONE_HIGHT;break;
        case 4:
            for(int i=0;i<length-1;i++)
            {
                int tempX=m[i];
                int tempY=n[i];
                m[i+1]=tempX;
                n[i+1]=tempY;
            }
            n[0]=n[0]+STONE_HIGHT;break;
        }
        canvas.repaint();
    }

    public static void main ( String args[] )
    {
        new SnakeGame();
    }
}

1个回答

当然不可以,组件只有获得焦点之后才能监听到键盘事件,把键盘监听器放到canvas上,canvas.addKeyListener , 然后在canvas.repaint();后添加canvas.requestFocusInWindow();

你先试试看