【问题标题】:Why is my oval not moving Java为什么我的椭圆形不动 Java
【发布时间】:2013-01-10 23:05:47
【问题描述】:

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

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

    }
}

【问题讨论】:

  • 如果您正在创建游戏,请使用 Slick2D 精彩库,其中包含您需要的大部分游戏内容,例如游戏循环、opengl、音乐和动画类等。当然,除非你是在自学在 Swing 中绘画的工作原理,而不是继续当兵 :)

标签: java swing jframe paint keylistener


【解决方案1】:

几个建议:

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

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

【讨论】:

  • +1 发现很难写这个。简短而甜蜜的分析。
  • 为什么不在paint(...) 内部调用repaint()
  • @JanDvorak:因为您正在创建一个无法控制时间间隔的游戏循环,并且您将影响程序状态的代码放入 paint(...) 中,这是永远不应该做的事情.
【解决方案2】:

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

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

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

【讨论】:

  • 这是一个潜在的其他问题,是的。
  • 随时将其添加到另一个答案中。我不确定你不能给 JFrame 添加一个键监听器,我也懒得去检查了。
  • 非常感谢,这真的很有帮助。我必须改掉以大写字母开头的方法名称的习惯。谢谢
【解决方案3】:

游戏是不同的东西(尽管有些使用摇摆来显示框架)。这些是你游戏中的问题。

  • 您在paint() 内调用repaint()。它在实际完成之前安排另一个绘画事件。调用它这么多次会爆你的CPU。如果您只需要移动椭圆,只需在 keyPressed() 方法的末尾调用 repaint。

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

  • 许多游戏使用多线程。一个独立于EDT的逻辑线程,以防止CPU占用并以正常速率检测输入。

  • 避免直接渲染到帧上。仅当您想要主动渲染并创建BufferStrategy 时才推荐使用(尽管您不会使用paint 方法)。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2021-11-19
    相关资源
    最近更新 更多