import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.applet.*;public class GreedSnake1 extends JFrame implements ActionListener,KeyListener
{
JFrame mainFrame;//定义主窗口
Canvas paintCanvas;//定义空白面板
JLabel labelScore;//计分牌
Font font;
JButton startButton,stopButton,helpButton,returnButton,aboutButton,musicButton;
SnakeModel snakeModel=null;//蛇
public static final int canvasWidth=250;//面板宽
public static final int canvasHeight=250;//面板高
public static final int nodeWidth=8;//点的宽
public static final int nodeHeight=8;//点的高public GreedSnake1()
{
//设置界面元素
mainFrame=new JFrame("§贪吃蛇§");//新建主窗口,名叫"GreedSnake"
Container rq=mainFrame.getContentPane();//在主窗口中定义容器rq
//rq.addKeyListener(this);//增加主窗口中的键盘监听
paintCanvas=new Canvas();//新建空白矩形区域
paintCanvas.setSize(canvasWidth+1,canvasHeight+1);//
paintCanvas.addKeyListener(this);//增加矩形区域中的键盘监听
rq.add(paintCanvas,BorderLayout.WEST);//在容器中增加矩形区域,用BorderLayout布局,设置在西面WEST
JPanel panelScore=new JPanel();//新建面板
panelScore.setLayout(new BorderLayout());//设置面板为BorderLayout布局
labelScore=new JLabel("得分:",JLabel.CENTER);
labelScore.setForeground(Color.red);
panelScore.add(labelScore,BorderLayout.NORTH);
JPanel panelButton=new JPanel();//新建面板
panelScore.add(panelButton,BorderLayout.CENTER);//将按钮面板添加到分数面板
panelButton.setLayout(new GridLayout(6,1));//设置面板为BorderLayout布局
JPanel start=new JPanel();
panelButton.add(start);
JPanel stop=new JPanel();
panelButton.add(stop);
JPanel help=new JPanel();
panelButton.add(help);
JPanel retur=new JPanel();
panelButton.add(retur);
JPanel about=new JPanel();
panelButton.add(about);
JPanel music=new JPanel();
panelButton.add(music);
font=new Font("楷体_GB2312",Font.BOLD,16);
startButton=new JButton("开始");
startButton.setFont(font);
startButton.setForeground(Color.blue);
startButton.addActionListener(this);
start.add(startButton);stopButton=new JButton("暂停");
stopButton.setFont(font);
stopButton.setForeground(Color.blue);
stopButton.addActionListener(this);
stop.add(stopButton);
helpButton=new JButton("帮助");
helpButton.setFont(font);
helpButton.setForeground(Color.blue);
helpButton.addActionListener(this);
help.add(helpButton);
returnButton=new JButton("反馈");
returnButton.setFont(font);
returnButton.setForeground(Color.blue);
returnButton.addActionListener(this);
retur.add(returnButton);
aboutButton=new JButton("关于");
aboutButton.setFont(font);
aboutButton.setForeground(Color.blue);
aboutButton.addActionListener(this);
about.add(aboutButton);
rq.add(panelScore,BorderLayout.EAST);//
mainFrame.pack();//设置窗口的大小,以适合其子组件的首选大小和布局
mainFrame.setResizable(false);//不能随意改变窗口大小
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭操作
mainFrame.setVisible(true);//窗口可见
begin();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("开始"))
{
 begin();
 startButton.setLabel("重来");
}
else if(e.getActionCommand().equals("重来"))
{
    stopButton.setLabel("暂停");
    snakeModel.running=false;
    begin();
}
else if(e.getActionCommand().equals("暂停"))
{
snakeModel.running=false;
stopButton.setLabel("继续");
    }
    else if(e.getActionCommand().equals("继续"))
{
//////////////snakeModel.running=true;///////////////////////
stopButton.setLabel("暂停");
}
else if(e.getActionCommand().equals("帮助"))
{
JOptionPane.showMessageDialog(null,"玩家手则:"+"\n开始和重来:按“开始”按钮或Enter键;"+
"\n暂停:按“暂停”按钮或space空格键;"+"\n运动方向:按←、↑、→、↓;"+"\n运动速度:PgUp键,加速;PgDn键,减速.");
}
else if(e.getActionCommand().equals("反馈"))
{
JOptionPane.showInputDialog("请您对本游戏提出宝贵的见意:");

}
else if(e.getActionCommand().equals("关于"))
{
JOptionPane.showMessageDialog(null,"欢迎光临!J家。"+"\n本游戏的制作人:jj");
}
}
//class KeyBoard implements KeyListener{
public void keyPressed(KeyEvent e)//KeyPressed方法
{
int keyCode=e.getKeyCode();//接收并定义键盘按键 
if(snakeModel.running) switch(keyCode)//选择语句
{
case KeyEvent.VK_UP://按↑键
snakeModel.changeDirection(SnakeModel.UP);//改变蛇的运动方向
break;//跳出选择语句,重新选择
case KeyEvent.VK_DOWN://按↓键
snakeModel.changeDirection(SnakeModel.DOWN);
break;
case KeyEvent.VK_LEFT://按←键
snakeModel.changeDirection(SnakeModel.LEFT);
break;
case KeyEvent.VK_RIGHT://按→键
snakeModel.changeDirection(SnakeModel.RIGHT);
break;
case KeyEvent.VK_PAGE_UP://按PgUp键
snakeModel.speedUp();//加速
break;
case KeyEvent.VK_PAGE_DOWN://按PgDn键
snakeModel.speedDown();//减速
break;
case KeyEvent.VK_SPACE://按space空格键
snakeModel.changePauseState();//暂停或继续
break;
default://除肯定条件以外的,同else
}
if(keyCode==KeyEvent.VK_R || keyCode==KeyEvent.VK_ENTER)//按ENTER或R,重新开始
{
snakeModel.running=false;//蛇的运动停止
begin();//游戏开始,放置贪吃蛇
}
}
public void keyReleased(KeyEvent e)//释放某个键时调用此方法
{
}
public void keyTyped(KeyEvent e)//键入某个键时调用此方法(当按下键然后又释放该键时发生此事件)
{
}
//----------------------------------------------------------------------
//repaint():绘制游戏界面(包括蛇和食物)
//----------------------------------------------------------------------
public void repaint()
{
Graphics g=paintCanvas.getGraphics();//在矩形区域中添加Graphics类//draw background
g.setColor(Color.black);//背景色为黑色
g.fillRect(0,0,canvasWidth,canvasHeight);//填充范围
g.setColor(Color.blue);//蛇的颜色为青蓝色
LinkedList na=snakeModel.nodeArray;//通过点,将蛇的身体保存Iterator it=na.iterator(); 
while(it.hasNext())
{
Node n=(Node)it.next();
drawNode(g,n);
}
// draw the food
g.setColor(Color.orange);//食物为黄色
Node n=snakeModel.food;drawNode(g,n);
updateScore();//改变计分牌
//update,调用paint(g),重写此方法,以防止不必要的清除背景调用
}
//----------------------------------------------------------------------
//drawNode():绘画某一结点(蛇身或食物)
//----------------------------------------------------------------------
private void drawNode(Graphics g,Node n)
{
g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,nodeHeight-1);//
}
//----------------------------------------------------------------------
//updateScore():改变计分牌
//----------------------------------------------------------------------
public void updateScore()
{
String s="得分: "+snakeModel.score;
labelScore.setText(s);//设置计分牌分数
font=new Font("楷体_GB2312",Font.BOLD,16);
labelScore.setFont(font);
}
//----------------------------------------------------------------------
//begin():游戏开始,放置贪吃蛇
//----------------------------------------------------------------------
void begin()
{
if(snakeModel==null||!snakeModel.running)
{
snakeModel=new SnakeModel(this,canvasWidth/nodeWidth,this.canvasHeight/nodeHeight);
(new Thread(snakeModel)).start();
}
}
//----------------------------------------------------------------------
//main():主函数
//----------------------------------------------------------------------
public static void main(String[] args)
{
GreedSnake1 gs=new GreedSnake1();
}
}

解决方案 »

  1.   

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    import java.applet.*;public class GreedSnake1 extends JFrame implements ActionListener,KeyListener
    {
    JFrame mainFrame;//定义主窗口
    Canvas paintCanvas;//定义空白面板
    JLabel labelScore;//计分牌
    Font font;
    JButton startButton,stopButton,helpButton,returnButton,aboutButton,musicButton;
    SnakeModel snakeModel=null;//蛇
    public static final int canvasWidth=250;//面板宽
    public static final int canvasHeight=250;//面板高
    public static final int nodeWidth=8;//点的宽
    public static final int nodeHeight=8;//点的高public GreedSnake1()
    {
    //设置界面元素
    mainFrame=new JFrame("§贪吃蛇§");//新建主窗口,名叫"GreedSnake"
    Container rq=mainFrame.getContentPane();//在主窗口中定义容器rq
    //rq.addKeyListener(this);//增加主窗口中的键盘监听
    paintCanvas=new Canvas();//新建空白矩形区域
    paintCanvas.setSize(canvasWidth+1,canvasHeight+1);//
    paintCanvas.addKeyListener(this);//增加矩形区域中的键盘监听
    rq.add(paintCanvas,BorderLayout.WEST);//在容器中增加矩形区域,用BorderLayout布局,设置在西面WEST
    JPanel panelScore=new JPanel();//新建面板
    panelScore.setLayout(new BorderLayout());//设置面板为BorderLayout布局
    labelScore=new JLabel("得分:",JLabel.CENTER);
    labelScore.setForeground(Color.red);
    panelScore.add(labelScore,BorderLayout.NORTH);
    JPanel panelButton=new JPanel();//新建面板
    panelScore.add(panelButton,BorderLayout.CENTER);//将按钮面板添加到分数面板
    panelButton.setLayout(new GridLayout(6,1));//设置面板为BorderLayout布局
    JPanel start=new JPanel();
    panelButton.add(start);
    JPanel stop=new JPanel();
    panelButton.add(stop);
    JPanel help=new JPanel();
    panelButton.add(help);
    JPanel retur=new JPanel();
    panelButton.add(retur);
    JPanel about=new JPanel();
    panelButton.add(about);
    JPanel music=new JPanel();
    panelButton.add(music);
    font=new Font("楷体_GB2312",Font.BOLD,16);
    startButton=new JButton("开始");
    startButton.setFont(font);
    startButton.setForeground(Color.blue);
    startButton.addActionListener(this);
    start.add(startButton);stopButton=new JButton("暂停");
    stopButton.setFont(font);
    stopButton.setForeground(Color.blue);
    stopButton.addActionListener(this);
    stop.add(stopButton);
    helpButton=new JButton("帮助");
    helpButton.setFont(font);
    helpButton.setForeground(Color.blue);
    helpButton.addActionListener(this);
    help.add(helpButton);
    returnButton=new JButton("反馈");
    returnButton.setFont(font);
    returnButton.setForeground(Color.blue);
    returnButton.addActionListener(this);
    retur.add(returnButton);
    aboutButton=new JButton("关于");
    aboutButton.setFont(font);
    aboutButton.setForeground(Color.blue);
    aboutButton.addActionListener(this);
    about.add(aboutButton);
    rq.add(panelScore,BorderLayout.EAST);//
    mainFrame.pack();//设置窗口的大小,以适合其子组件的首选大小和布局
    mainFrame.setResizable(false);//不能随意改变窗口大小
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭操作
    mainFrame.setVisible(true);//窗口可见
    begin();
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void actionPerformed(ActionEvent e){
    if(e.getActionCommand().equals("开始"))
    {
     begin();
     startButton.setLabel("重来");
    }
    else if(e.getActionCommand().equals("重来"))
    {
        stopButton.setLabel("暂停");
        snakeModel.running=false;
        begin();
    }
    else if(e.getActionCommand().equals("暂停"))
    {
    snakeModel.running=false;
    stopButton.setLabel("继续");
        }
        else if(e.getActionCommand().equals("继续"))
    {
    //////////////snakeModel.running=true;///////////////////////
    stopButton.setLabel("暂停");
    }
    else if(e.getActionCommand().equals("帮助"))
    {
    JOptionPane.showMessageDialog(null,"玩家手则:"+"\n开始和重来:按“开始”按钮或Enter键;"+
    "\n暂停:按“暂停”按钮或space空格键;"+"\n运动方向:按←、↑、→、↓;"+"\n运动速度:PgUp键,加速;PgDn键,减速.");
    }
    else if(e.getActionCommand().equals("反馈"))
    {
    JOptionPane.showInputDialog("请您对本游戏提出宝贵的见意:");

    }
    else if(e.getActionCommand().equals("关于"))
    {
    JOptionPane.showMessageDialog(null,"欢迎光临!J家。"+"\n本游戏的制作人:jj");
    }
    }
    //class KeyBoard implements KeyListener{
    public void keyPressed(KeyEvent e)//KeyPressed方法
    {
    int keyCode=e.getKeyCode();//接收并定义键盘按键 
    if(snakeModel.running) switch(keyCode)//选择语句
    {
    case KeyEvent.VK_UP://按↑键
    snakeModel.changeDirection(SnakeModel.UP);//改变蛇的运动方向
    break;//跳出选择语句,重新选择
    case KeyEvent.VK_DOWN://按↓键
    snakeModel.changeDirection(SnakeModel.DOWN);
    break;
    case KeyEvent.VK_LEFT://按←键
    snakeModel.changeDirection(SnakeModel.LEFT);
    break;
    case KeyEvent.VK_RIGHT://按→键
    snakeModel.changeDirection(SnakeModel.RIGHT);
    break;
    case KeyEvent.VK_PAGE_UP://按PgUp键
    snakeModel.speedUp();//加速
    break;
    case KeyEvent.VK_PAGE_DOWN://按PgDn键
    snakeModel.speedDown();//减速
    break;
    case KeyEvent.VK_SPACE://按space空格键
    snakeModel.changePauseState();//暂停或继续
    break;
    default://除肯定条件以外的,同else
    }
    if(keyCode==KeyEvent.VK_R || keyCode==KeyEvent.VK_ENTER)//按ENTER或R,重新开始
    {
    snakeModel.running=false;//蛇的运动停止
    begin();//游戏开始,放置贪吃蛇
    }
    }
    public void keyReleased(KeyEvent e)//释放某个键时调用此方法
    {
    }
    public void keyTyped(KeyEvent e)//键入某个键时调用此方法(当按下键然后又释放该键时发生此事件)
    {
    }
    //----------------------------------------------------------------------
    //repaint():绘制游戏界面(包括蛇和食物)
    //----------------------------------------------------------------------
    public void repaint()
    {
    Graphics g=paintCanvas.getGraphics();//在矩形区域中添加Graphics类//draw background
    g.setColor(Color.black);//背景色为黑色
    g.fillRect(0,0,canvasWidth,canvasHeight);//填充范围
    g.setColor(Color.blue);//蛇的颜色为青蓝色
    LinkedList na=snakeModel.nodeArray;//通过点,将蛇的身体保存Iterator it=na.iterator(); 
    while(it.hasNext())
    {
    Node n=(Node)it.next();
    drawNode(g,n);
    }
    // draw the food
    g.setColor(Color.orange);//食物为黄色
    Node n=snakeModel.food;drawNode(g,n);
    updateScore();//改变计分牌
    //update,调用paint(g),重写此方法,以防止不必要的清除背景调用
    }
    //----------------------------------------------------------------------
    //drawNode():绘画某一结点(蛇身或食物)
    //----------------------------------------------------------------------
    private void drawNode(Graphics g,Node n)
    {
    g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,nodeHeight-1);//
    }
    //----------------------------------------------------------------------
    //updateScore():改变计分牌
    //----------------------------------------------------------------------
    public void updateScore()
    {
    String s="得分: "+snakeModel.score;
    labelScore.setText(s);//设置计分牌分数
    font=new Font("楷体_GB2312",Font.BOLD,16);
    labelScore.setFont(font);
    }
    //----------------------------------------------------------------------
    //begin():游戏开始,放置贪吃蛇
    //----------------------------------------------------------------------
    void begin()
    {
    if(snakeModel==null||!snakeModel.running)
    {
    snakeModel=new SnakeModel(this,canvasWidth/nodeWidth,this.canvasHeight/nodeHeight);
    (new Thread(snakeModel)).start();
    }
    }
    //----------------------------------------------------------------------
    //main():主函数
    //----------------------------------------------------------------------
    public static void main(String[] args)
    {
    GreedSnake1 gs=new GreedSnake1();
    }
    }
      

  2.   

    这是后面一段的,应该没问题的,主要是上面一段?
    class Node//Node类是保存每个位置的信息
    {
    int x;
    int y;
    Node(int x,int y)
    {
    this.x=x;
    this.y=y;
    }
    }
    //----------------------------------------------------------------------
    //SnakeModel:贪吃蛇模型
    //----------------------------------------------------------------------
    class SnakeModel implements Runnable//SnakeModel实现Runnable
    {
    GreedSnake1 gs;
    boolean[][] matrix;// 界面数据保存在matrix[][]数组里
    LinkedList nodeArray=new LinkedList();
    Node food;
    int maxX;//最大宽度
    int maxY;//最大长度
    int direction=2;//方向默认为UP
    boolean running=false;//运动状态
    int timeInterval=200;// 间隔时间(速度)
    double speedChangeRate=0.75;// 速度改变程度
    boolean paused=false;// 游戏状态
    int score=0;
    int countMove=0;
    // UP和DOWN是偶数,RIGHT和LEFT是奇数
    public static final int UP=2;
    //FINAL:public static final int (FINAL)
    //表示 final 修饰符的 int 值
    public static final int DOWN=4;
    public static final int LEFT=1;
    public static final int RIGHT=3;
    //----------------------------------------------------------------------
    //GreedModel():初始化界面
    //----------------------------------------------------------------------
    public SnakeModel(GreedSnake1 gs,int maxX,int maxY)
    {
    this.gs=gs;
    this.maxX=maxX;
    this.maxY=maxY;
    matrix=new boolean[maxX][];//定义数组的行的值
    for(int i=0;i<maxX;++i)
    {
    matrix[i]=new boolean[maxY];//定义数组的列的值
    Arrays.fill(matrix[i],false);// 没有蛇和食物的地区置false
    /////////////////////////////////////////////////////////
    //Arrays类包含用来操作数组(比如排序和搜索)的各种方法
    //此类还包含一个允许将数组作为列表来查看的静态工厂
    //java.util   类Arrays
    ///////////////////////////////////////////////////////// 
    }
    //初始化贪吃蛇
    int initArrayLength=maxX>20 ? 10 : maxX/2;
    for(int i=0;i<initArrayLength;++i)
    {
    int x=maxX/2+i;
    int y=maxY/2;
    nodeArray.addLast(new Node(x,y));//最后的点的位置
    matrix[x][y]=true;//蛇身位置,true
    }
    food=createFood();
    matrix[food.x][food.y]=true;//食物处置true
    }
    //----------------------------------------------------------------------
    //changeDirection():改变运动方向
    //----------------------------------------------------------------------
    public void changeDirection(int newDirection)
    {
    if(direction%2!=newDirection%2)// 避免冲突
    {
    direction=newDirection;
    }
    }
    //----------------------------------------------------------------------
    //moveOn():贪吃蛇运动函数
    //----------------------------------------------------------------------
    public boolean moveOn()//moveOn(),用来更新蛇的位置,对于当前方向,把头部位置进行相应改变
    {
    Node n=(Node)nodeArray.getFirst();
    int x=n.x;
    int y=n.y;
    switch(direction)
    {
    case UP:
    y--;
    break;
    case DOWN:
    y++;
    break;
    case LEFT:
    x--;
    break;
    case RIGHT:
    x++;
    break;
    }
    if((0<=x&&x<maxX)&&(0<=y&&y<maxY))
    {
    if(matrix[x][y])// 吃到食物或者撞到身体
    {
    if(x==food.x&&y==food.y)// 吃到食物
    {
    nodeArray.addFirst(food);// 在头部加上一结点
    //计分规则:碰到food,加3分
    score+=3;
    food=createFood();
    matrix[food.x][food.y]=true;
    return true;
    }
    else return false;// 撞到身体
    }
    else//什么都没有碰到
    {
    nodeArray.addFirst(new Node(x,y));// 加上头部
    matrix[x][y]=true;
    n=(Node)nodeArray.removeLast();// 去掉尾部
    matrix[n.x][n.y]=false;
    countMove++;
    return true;
    }
    }
    return false;//越界(撞到墙壁)
    }
    //----------------------------------------------------------------------
    //run():贪吃蛇运动线程
    //----------------------------------------------------------------------
    public void run()
    {
    running=true;
    while(running)
    {
    try//接受监视的程序块,在此区域内发生的异常由catch中指定的程序处理
    {
    Thread.sleep(timeInterval);//Thread.sleep(),sleep已重载,将当前线程,阻塞指定的毫秒数
    }catch(Exception e)
    ////////////////////////////////////////////////////////////////////////////////////////
    //try{
    //   接受监视的程序块,在此区域内发生的异常由catch中指定的程序处理
    //    }
    //catch(要处理的异常类型和标识符){
    //    捕获一个异常并进行异常处理
    //    }
    //http://msdn2.microsoft.com/zh-cn/library/system.exception(VS.80).aspx
    ////////////////////////////////////////////////////////////////////////////////////////
    {
    break;
    }
    if(!paused)//不停顿
    {
    if(moveOn())// 未结束
    {
    gs.repaint();
    }
    else//游戏结束
    {
    JOptionPane.showMessageDialog(null,"HAHA,笨蛋,你输了!~",
    "『游戏结束』",JOptionPane.INFORMATION_MESSAGE);
    break;
    }
    }
    }
    running=false;
    }
    //----------------------------------------------------------------------
    //createFood():生成食物及放置地点
    //----------------------------------------------------------------------
    private Node createFood()
    {
    int x=0;
    int y=0;
    do
    {
    Random r=new Random();//此类的实例用于生成伪随机数流(java.util 类Random)
    x=r.nextInt(maxX);
    y=r.nextInt(maxY);
    }while(matrix[x][y]);
    return new Node(x,y);
    }
    //----------------------------------------------------------------------
    //speedUp():加快蛇运动速度
    //----------------------------------------------------------------------
    public void speedUp()
    {
    timeInterval*=speedChangeRate;
    }
    //----------------------------------------------------------------------
    //speedDown():放慢蛇运动速度
    //----------------------------------------------------------------------
    public void speedDown()
    {
    timeInterval/=speedChangeRate;
    }
    //----------------------------------------------------------------------
    //changePauseState(): 改变游戏状态(暂停或继续)
    //----------------------------------------------------------------------
    public void changePauseState()
    {
    paused=!paused;
    }
    }
      

  3.   

    LZ不要着急,你的代码问题不大,慢慢检查一遍,给你2个建议去Check:
    1.除非你需要知道按下键盘上某个键的时间,或者是否按下组合键了,才需要用public void keyPressed(KeyEvent e)的方法,否则就用keyTyped去截取事件就行了。
    2.建议你去试试第2段程序中的Canvas对象是否获得了键盘焦点,用isFocusable()去测试,如果没有就setFocusable()去添加焦点
    另:keyListener和ActionListener是没有冲突的