如何使用KeyListener来移动矩形。

huangapple go评论66阅读模式
英文:

How to use KeyListener for moving Rectangles

问题

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class f3 extends JPanel implements ActionListener, KeyListener {

    static JFrame frame;
    static Timer t;
    static int x, y, velx, vely, c;

    f3(){
        t = new Timer(5, this);
        x = 0;
        y = 0;
        velx = 0;
        vely = 0;

        frame = new JFrame();

        frame.addKeyListener(this);
        frame.setFocusable(true);
        frame.setFocusTraversalKeysEnabled(false);
        frame.setSize(500, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);

        frame.setVisible(true);
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 50, 30);

        t.start();
    }

    public void actionPerformed(ActionEvent e) {

        x = x + velx;
        y = y + vely;
        repaint();

    }

    public void keyPressed(KeyEvent e) {
        c = e.getKeyCode();

        if(c == KeyEvent.VK_RIGHT) {
            velx = 1;
            vely = 0;
        }

        if(c == KeyEvent.VK_LEFT) {
            velx = -1;
            vely = 0;
        }

        if(c == KeyEvent.VK_UP) {
            velx = 0;
            vely = -1;
        }

        if(c == KeyEvent.VK_DOWN) {
            velx = 0;
            vely = 1;
        }
    }

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

    public static void main(String args[]) {
       new f3();
    }
}
英文:

I am trying to move a rectangle while the key is pressed and to stop it on release like the game "Snake". As reference I followed this tutorial.

I tried to adjust a few things in my code:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;    
public class f3 extends JPanel implements ActionListener, KeyListener { 
static JFrame frame;
static Timer t;
static int x, y, velx, vely, c;
f3(){
t = new Timer(5, this);
x = 0;
y = 0;
velx = 0;
vely = 0;
frame = new JFrame();
frame.addKeyListener(this);
frame.setFocusable(true);
frame.setFocusTraversalKeysEnabled(false);
frame.setSize(500,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(x, y, 50, 30);
t.start();
}
public void actionPerformed(ActionEvent e) {
x = x + velx;
y = y + vely;
repaint();
}
public void keyPressed(KeyEvent e) {
c = e.getKeyCode();
if(c == KeyEvent.VK_RIGHT) {
velx = 1;
vely = 0;
}
if(c == KeyEvent.VK_LEFT) {
velx = -1;
vely = 0;
}
if(c == KeyEvent.VK_UP) {
velx = 0;
vely = -1;
}
if(c == KeyEvent.VK_DOWN) {
velx = 0;
vely = 1;
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public static void main(String args[]) {
new f3();
}
}

答案1

得分: 1

velxvely 的值是在触发按键事件后进行设置的。因为在这里使用了一个 Timer,GUI 将会持续更新,因为 actionPerformed 会被重复触发。

移除这个 Timer,然后将 keyPressed 中的变化部分放到这个形式中,你将会得到期望的结果。

public void keyPressed(KeyEvent e){

   if(e.getKeyCode() == KeyEvent.VK_RIGHT){
      velx = 1;
      vely = 0;
      x = x + velx;
      y = y + vely;
      repaint();
   }     

}
英文:

The value of velx and vely are set after a key event is triggered. Since you are using a Timer here, the GUI will continuously update because actionPerformed is repeatedly triggered.

Remove the Timer, then put the change section of keyPressed to this form and you will get a desired result.

public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
velx = 1;
vely = 0;
x = x + velx;
y = y + vely;
repaint();
}     
}

答案2

得分: 0

由于velxvely表示移动的速度(与例如每次将玩家移动一个空间不同),因此在释放与该轴关联的特定键时,您还需要确保keyReleased将相应的速度返回到0。

英文:

Since velx and vely indicate the velocity of the movement (as opposed to moving the player one space at a time, for instance), you will want to also ensure keyReleased returns the appropriate velocity to 0 when the specific key associated with that axis is released.

答案3

得分: 0

你没有 keyReleased 方法的处理程序,在这里你应该将速度设置为零,如下所示:

    public void keyReleased(KeyEvent e) {
        velx = 0;
        vely = 0;
    }
英文:

You do not have a handler for keyReleased method, where you should set velocities to zero as such:

public void keyReleased(KeyEvent e) {
velx = 0;
vely = 0;
}

huangapple
  • 本文由 发表于 2020年9月3日 09:06:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63715398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定