KeyListener和ActionListener未注册

问题描述

我一直在研究一个使字符随键移动的Java项目,但是keyListener无法正常工作并正在注册我的动作。我用eclipse编写代码,我认为问题出在我的GamePanel,Player或KeyChecker类上。我正在使用一个指南来帮助启动此操作,因此它与另一个项目的代码相同,但是不起作用。这是我的代码:

平台游戏类:

import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;

public class Platformer {

    public static void main(String[] args) {
    
        MainFrame frame = new MainFrame();
        frame.setSize(700,700);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setTitle("Platformer");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

类GamePanel: 我曾尝试更改if语句的布局(如果这是原始问题),但它没有任何改变。我还尝试将语句更改为void,而不是public void,但这也不起作用。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;

public class GamePanel extends JPanel implements ActionListener{

    Player player;
    ArrayList<Wall> walls = new ArrayList<>();
    Timer gameTimer;
    
    public GamePanel() {
        
        player = new Player(400,300,this);
        
        makeWalls();
        
        gameTimer = new Timer();
        gameTimer.schedule(new TimerTask() {

            public void run() {
                player.set();
                repaint();  
            }
            
        },17);
    }

    public void makeWalls() {
        for (int i = 50; i < 650; i += 50) {
            walls.add (new Wall(i,600,50,50));
        }
        walls.add(new Wall(50,550,50));
        walls.add(new Wall(50,500,450,50));
        walls.add(new Wall(600,50));
        walls.add(new Wall(450,50));

    }
    
    public void paint(Graphics g) {
        
        super.paint(g);
        Graphics2D gtd = (Graphics2D) g;
        player.draw(gtd);
        for (Wall wall: walls) wall.draw(gtd);
    }
    
    public void KeyPressed(KeyEvent e) {
        if (e.getKeyChar() == 'a')player.keyLeft = true;
        if (e.getKeyChar() == 'w') player.keyUp = true;
        if (e.getKeyChar() == 's') player.keyDown = true;
        if (e.getKeyChar() == 'd') player.keyRight = true;
    }
    
    public void KeyReleased(KeyEvent e) {
        if (e.getKeyChar() == 'a') player.keyLeft = false;
        if (e.getKeyChar() == 'w') player.keyUp = false;
        if (e.getKeyChar() == 's') player.keyDown = false;
        if (e.getKeyChar() == 'd') player.keyRight = false;
    }
    
    public void actionPerformed(ActionEvent e) {
    }
    
}

职业玩家: 我也尝试过与GamePanel相同的操作,但是那也不起作用。

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Player {
    
    GamePanel panel;
    int x;
    int y;
    int width;
    int height;
    
    double xspeed;
    double yspeed;
    
    Rectangle hitBox;
    
    boolean keyRight;
    boolean keyLeft;
    boolean keyUp;
    boolean keyDown;
    
    public Player(int x,int y,GamePanel panel) {
        
        this.panel = panel;
        
        this.x = x;
        this.y = y;
        
        width = 50;
        height = 100;
        hitBox = new Rectangle(x,y,width,height);
    }
    
    public void set() {
    
        if (keyLeft && keyRight || !keyLeft && !keyRight) xspeed *= 0.8;
        else if (keyLeft && !keyRight) xspeed --;
        else if (keyRight && !keyLeft) xspeed ++;
        
        if (xspeed > 0 && xspeed < 0.75) xspeed = 0;
        if (xspeed < 0 && xspeed > - 0.75) xspeed = 0;
        
        if (xspeed > 7) xspeed = 7;
        if (xspeed < -7) xspeed = -7;
        
        if (keyUp) {
            
            hitBox.y++;
            for(Wall wall: panel.walls) {
                if (wall.hitBox.intersects(hitBox)) yspeed = -6;
            }
            hitBox.y --;            
        }
        
        yspeed += .3;
        
        hitBox.x += xspeed;
        for(Wall wall: panel.walls) {
            if (hitBox.intersects(wall.hitBox)) {
                hitBox.x-= xspeed;
                while(!wall.hitBox.intersects(hitBox)) hitBox.x += Math.signum(xspeed);
                hitBox.x -= Math.signum(xspeed);
                xspeed = 0;
                x = hitBox.x;
            }
        }
        
        hitBox.y += xspeed;
        for(Wall wall: panel.walls) {
            if (hitBox.intersects(wall.hitBox)) {
                hitBox.y-= yspeed;
                while(!wall.hitBox.intersects(hitBox)) hitBox.y += Math.signum(yspeed);
                hitBox.y -= Math.signum(yspeed);
                yspeed = 0;
                y = hitBox.y;
            }
        }
        
        x += xspeed;
        y += yspeed;
        
        hitBox.x = x;
        hitBox.y = y;       
    }
    
    public void draw(Graphics2D gtd) {
        gtd.setColor(Color.BLACK);
        gtd.fillRect(x,height);
        
    }   
}

KeyChecker类:​​

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class KeyChecker extends KeyAdapter{
    
    GamePanel panel;
    
    public KeyChecker(GamePanel panel) {
        this.panel = panel;
    }
    
    public void KeyPressed(KeyEvent e) {
        panel.KeyPressed(e);
    }
    
    public void KeyReleased(KeyEvent e) {
        panel.KeyReleased (e);
    }
}

墙类:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Wall {
    int x;
    int y;
    int width;
    int height;
    
    Rectangle hitBox;
    
    public Wall (int x,int width,int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = width;
        
        hitBox = new Rectangle(x,height);
    }
    
    public void draw(Graphics2D gtd) {
        gtd.setColor(Color.BLACK);
        gtd.drawRect(x,height);
        gtd.setColor(Color.WHITE);
        gtd.fillRect(x + 1,y + 1,width - 2,height - 2);
    }
}

MainFrame类:

import java.awt.Color;
import javax.swing.JFrame;

public class MainFrame extends JFrame{
    
    public MainFrame() {
        
        GamePanel panel = new GamePanel();
    
        panel.setLocation(0,0);
        panel.setSize(this.getSize());
        panel.setBackground(Color.LIGHT_GRAY);
        panel.setVisible(true);
        this.add(panel);
        
        addKeyListener(new KeyChecker(panel));
    }
}

谢谢您的帮助。

解决方法

KeyChecker中的功能应以小写字母开头,因此public void keyPressed和keyReleased。 另外,您应该将implements KeyListener添加到KeyChecker和GamePanel类中(在GamePanel中删除ActionListener)。 然后,添加未实现的功能。 Eclipse会要求您。

@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    
}

@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
    
}

请注意,最好@Override函数keyPressed和keyReleased,而不是创建新函数。

我尝试过,效果很好!

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...