3

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

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

    }
}
4

3 回答 3

11

几个建议:

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

请查看键绑定教程,然后查看我在此处此处使用键绑定的示例代码。

于 2013-01-27T13:47:35.440 回答
5

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

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

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

于 2013-01-27T13:50:51.220 回答
4

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

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

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

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

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

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

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

  • 最后尝试搜索java game development tutorials. 这里有一个简单的框架(教程),它很好地介绍了这个主题。(这是一个蛇游戏的例子)。

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

于 2013-01-27T14:17:39.283 回答