2016-04-27 69 views
-1

私はWASDキーを押して、ユーザーがウィンドウ上でボールを動かすことができるプログラムを書きたいと思っています。しかし、ユーザーがキーを押すと何も起こりません。ベローは私のプログラムのコードです、誰が何が間違っているのか教えてもらえますか?Java GUI:WASDキーを使用してボールを移動する方法は?

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){} 
} 

答えて

4

しかし、ユーザープレスキー;(私はのKeyListenerを削除し、super.x ++置けば、ボールが移動することができますball.move()で)、何も起こりません。

KeyListenerを使用しないでください。 KeyListenerは、コンポーネントにフォーカスがある場合にのみ機能するため、コンポーネントにフォーカスがないと推測されます。

代わりにKey Bindingsを使用すると、コンポーネントにフォーカスがない場合でもキーボードは機能します。

両方のアプローチの詳細については、Motion Using the Keyboardを参照してください。両方のアプローチの作業コードだけでなく、

また:

  1. カスタムペイントは(...)ペイントない、paintComponent(...)をオーバーライドすることによって行われるべきです。最初にsuper.paintComponent(...)を呼び出す必要があります。この場合、JComponentを拡張しているため、背景が自動的に消去されないため、ボールを塗る前にコンポーネントの背景を塗りつぶすためにfillRect(...)ステートメントを追加する必要があります。
  2. アニメーションにScheduledThreadPoolExecutorを使用しないでください。 GUIコンポーネントの状態の更新は、Event Dispatch Threadで行う必要があります。あなたはスイングタイマーを使用する必要があります。

Swing Tutorialをご覧ください。開始するにはCustom PaintingHow to Use Swing Timersのセクションがあります。

関連する問題