【问题标题】:Java GUI : How to move a ball using WASD keys?Java GUI:如何使用 WASD 键移动球?
【发布时间】:2016-08-22 00:38:12
【问题描述】:

我想编写一个程序,用户可以通过按 WASD 键在窗口上移动球。然而,当用户按下按键时,什么也没有发生。下面是我的程序的代码,谁能告诉我有什么问题或者我该如何改进我的程序? (如果我删除 KeyListener 并将 super.x ++; 放在 ball.move() 中,球可以移动)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JApplet;
import javax.swing.JComponent;
import java.awt.geom.*;
public class MoveBall extends JApplet
{
    public final int Width =  567;
    public final int Height = 567;
    public static PaintSurface canvas;
    public void init()
    {
        canvas = new PaintSurface();
        this.setSize(Width, Height);
        this.add(canvas, BorderLayout.CENTER);
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3);
        executor.scheduleAtFixedRate(new Action(), 0L, 10L, TimeUnit.MILLISECONDS);
    }
}
class Action implements Runnable
{
    public void run() 
    {
        MoveBall.canvas.repaint();  
    }   
}
class PaintSurface extends JComponent
{   
    Ball ball = new Ball(20);
    public PaintSurface()
    {
        addKeyListener(new Listener());
    }
    public void paint(Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ball.move();
        g2.setColor(Color.GREEN);
        g2.fill(ball);
        g2.setColor(Color.BLACK);
        g2.drawString("W,A,S,D or arrow keys to move", 7, 17);
    }
}
class Ball extends Ellipse2D.Float
{
    public int xspeed, yspeed;
    public Ball(int d)
    {
        super(370,370, d,d);
    }
    public void move()
    {
        if(super.x >567)
        super.x -=567;
        if(super.x <0)
        super.x +=567;
        if(super.y >567)
            super.y -=567;
        if(super.y < 0)
            super.y +=567;
        super.x += xspeed ;
        super.y += yspeed ;
    }
}
class Listener implements KeyListener
{
    public void keyPressed(KeyEvent ev) 
    {
        if(ev.getKeyCode() == KeyEvent.VK_W)
        {   
            MoveBall.canvas.ball.xspeed = 0 ;
            MoveBall.canvas.ball.yspeed = -1 ; 
        }   
        if(ev.getKeyCode() == KeyEvent.VK_A)
        {   
            MoveBall.canvas.ball.xspeed = -1 ;
            MoveBall.canvas.ball.yspeed = 0 ; 
        }   
        if(ev.getKeyCode() == KeyEvent.VK_S)
        {   
            MoveBall.canvas.ball.xspeed = 0 ;
            MoveBall.canvas.ball.yspeed = 1 ; 
        }   
        if(ev.getKeyCode() == KeyEvent.VK_D)
        {   
            MoveBall.canvas.ball.xspeed = 1 ;
            MoveBall.canvas.ball.yspeed = 0 ; 
        }   

    }
    public void keyReleased(KeyEvent arg0){}
    public void keyTyped(KeyEvent arg0){}
}

【问题讨论】:

    标签: java swing user-interface animation keyboard


    【解决方案1】:

    然而,当用户按下按键时,什么也没有发生。

    不要使用 KeyListener。 KeyListener 仅在组件具有焦点时才有效,所以我猜您的组件没有焦点。

    改为使用Key Bindings,即使组件没有焦点,键盘也会起作用。

    有关这两种方法的更多信息,请参阅Motion Using the Keyboard。以及两种方法的工作代码。

    还有:

    1. 自定义绘画应该通过覆盖paintComponent(...) 来完成,而不是paint(...)。您应该在开始时调用 super.paintComponent(...) 。虽然在这种情况下,因为您正在扩展 JComponent,所以不会自动清除背景,因此您需要添加一个 fillRect(...) 语句来在绘制球之前绘制组件的背景。
    2. 不要将 ScheduledThreadPoolExecutor 用于动画。应在事件调度线程上更新 GUI 组件的状态。您应该使用 Swing Timer。

    看看Swing TutorialCustom PaintingHow to Use Swing Timers 上的部分可以帮助您入门。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多