Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的椭圆没有移动_Java_Swing_Jframe_Paint_Keylistener - Fatal编程技术网

Java 为什么我的椭圆没有移动

Java 为什么我的椭圆没有移动,java,swing,jframe,paint,keylistener,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; /** * * @

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

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();

    }
}

若干建议:

  • 不要直接在JFrame中绘制。查看绘图教程,您将看到如何在JPanel或其他JComponent的
    paintComponent(…)
    methodoverride中绘图
  • paintComponent(…)
    的第一行通常是对super方法的调用:
    super.paintComponent(g)
  • 不要在
    paint(…)
    paintComponent(…)
    内部调用
    repaint()
    。这是一种尝试制作不受控制的动画的糟糕方法
  • 改用摆动计时器
  • 不要将类命名为与核心类相同的名称,尤其不要将其命名为ActionListener,因为这将使您在需要时几乎不可能使用实际的ActionListener
  • KeyListener仅在侦听的组件可聚焦且具有焦点时才工作
  • 避免在Swing应用程序中使用KeyListener,而是使用键绑定。请搜索这个网站,因为这已经讨论了很多次,许多例子,一些我的

请查看,然后查看我使用密钥绑定和的示例代码。

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

  • 您没有覆盖任何KeyListener(或KeyAdapter)方法。您的方法名为
    KeyPressed
    ,在Java中,方法总是以小写字母开头。该方法名为
    keyPressed()
    。当您打算重写方法时,请始终使用@Override注释。这样,如果由于方法名称中有输入错误而没有输入,则会出现编译器错误:

     @Override
     public void keyPressed(KeyEvent event) {
         ...
     }
    
  • 当按下某个键时,您没有调用repaint(),因此Swing没有理由重新绘制帧


游戏是一种不同的东西(尽管有些游戏使用swing来显示画面)。这些是你比赛中的问题

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

  • 你无法控制时间。这会导致游戏在快系统上运行快,在慢系统上运行慢。尝试搜索
    游戏循环

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

  • 避免直接渲染到帧上。仅当您希望活动渲染并创建
    缓冲策略
    (尽管不使用绘制方法)时,才建议使用此方法

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

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

  • 最后,尝试搜索
    java游戏开发教程
    。有一个简单的框架可以很好地介绍这个主题。(这是一个蛇类游戏的例子)


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

+1发现编写这个很困难。简短而甜蜜的分析。为什么不在
paint(…)
中调用
repaint()
?@JanDvorak:因为你正在创建一个无法控制时间间隔的游戏循环,并且你正在将影响程序状态的代码放入
paint(…)
中,这是一个不应该做的事情。这是一个潜在的其他问题,是的。请在另一个答案中随意添加。我不确定你不能将密钥侦听器添加到JFrame,而且我懒得检查。非常感谢,这真的很有帮助。我必须改掉方法名称以大写字母开头的习惯。感谢如果您正在创建一个游戏,请使用brilliant library,其中包含了您在游戏中所需的大部分内容,如开箱即用的游戏循环、opengl、音乐和动画课程等。当然,除非您正在自学挥杆绘画的工作原理,而不是随身携带的士兵:)