为什么我的椭圆形不移动Java

时间:2013-01-27 13:45:13

标签: java swing jframe paint keylistener

我正在写一个像游戏一样的小蛇,我正在实现关键事件监听器,所以当按下箭头键时它会监听它增加或减少框架中椭圆的位置。以下是我的代码,您认为发生了什么?我试着谷歌搜索可能的解决方案,但我结果是空的。

package snakegame;

import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

/**
 *
 * @author PlaixHax0r
 */
public class SnakeGame extends JFrame{

    int x, y;

    public class ActionListener extends KeyAdapter{
        public void KeyPressed(KeyEvent a){

            int KeyCode = a.getKeyCode();

            if(KeyCode == KeyEvent.VK_RIGHT){
                x++;
            }

            if(KeyCode == KeyEvent.VK_LEFT){
                x--;
            }

            if(KeyCode == KeyEvent.VK_DOWN){
                y++;
            }

            if(KeyCode == KeyEvent.VK_UP){
                y--;
            }


        }

        public void KeyReleased(KeyEvent a){

        }

    }



    public SnakeGame(){
        addKeyListener(new ActionListener());
        setTitle("Snake 1.0");
        setVisible(true);
        setSize(500, 500);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        x=150;
        y=150;

    }

    public void paint(Graphics g){
        g.drawString("Welcome to Snake Empire", 180, 50);
        g.fillOval(x, y, 15, 15);

        repaint();
    }


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

    }
}

3 个答案:

答案 0 :(得分:11)

一些建议:

  • 不要直接在JFrame中绘制。查看绘图教程,您将看到在JPanel或其他JComponent的paintComponent(...)方法覆盖中绘制。
  • paintComponent(...)的第一行通常是对超级方法的调用:super.paintComponent(g)
  • 请勿在{{1​​}}或repaint()内拨打paint(...)。这是尝试不受控制的动画的不好方法。
  • 改为使用Swing Timer。
  • 不要将类命名为核心类,特别是不要将其命名为ActionListener,因为这将使您几乎不可能在需要时使用实际的ActionListener。
  • KeyListeners仅在收听的组件具有焦点且具有焦点时才起作用。
  • 避免将KeyListeners与Swing应用程序一起使用,而是使用Key Bindings。请搜索此网站,因为已经多次讨论过这个问题,有些是我的。

请查看Key Bindings Tutorial,然后查看我使用密钥绑定herehere的示例代码。

答案 1 :(得分:5)

我看到的问题,除了气垫船看到的问题外:

  • 您没有覆盖任何KeyListener(或KeyAdapter)方法。您的方法名为KeyPressed,方法始终以Java中的小写字母开头。该方法名为keyPressed()。当您打算覆盖方法时,始终使用@Override注释。这样,当你没有因为你的方法名称中有拼写错误时,你会得到一个编译器错误:

     @Override
     public void keyPressed(KeyEvent event) {
         ...
     }
    
  • 按下某个键时你没有调用repaint(),所以Swing没有理由重新绘制你的帧。

答案 2 :(得分:4)

游戏是不同的东西(虽然有些人使用swing来显示框架)。这些是你游戏中的问题。

  • 您正在repaint()内拨打paint()。它会在实际完成之前安排另一个绘制事件。多次调用它会破坏你的cpu。如果您只需要移动椭圆形,只需在keyPressed()方法的末尾调用重绘。

  • 你无法控制时间。这导致您的游戏在快速系统上快速运行而在慢速系统上运行缓慢。尝试搜索game loops

  • 许多游戏都使用多线程。与EDT分开的逻辑线程,以防止CPU占用并以正常速率检测输入。

  • 避免直接渲染到帧上。建议仅在您需要活动渲染并创建BufferStrategy时(尽管您不会使用绘制方法)。

  • 您没有使用双缓冲。它会导致游戏闪烁。

  • 切勿直接在输入状态下更改对象的位置。只需改变它们的特定速度,并在更新时简单地将它们添加到位置(也使用负速度),以确保仅定期更新对象。

  • 最后尝试搜索java game development tutorials。有一个简单的框架here (tutorial),可以很好地介绍这个主题。 (这是一个蛇游戏的例子)。

摆脱java中的.NET命名约定(使用大写字母开始方法名称)