Задержка между нажатием клавиши и возникновением анимации игрока (KeyListener, Java) - PullRequest
0 голосов
/ 07 апреля 2020

Я новичок в переполнении стека, поэтому, пожалуйста, извините, если я сделаю какие-либо ошибки.

Я пишу java игру с движущимся игроком, который анимирован, однако, когда я нажимаю клавиши для перемещения указанного игрока (W, A, S и D), игрок останавливается, немного ждет, затем ходит нормально. Это как ш ..... wwwwwwwwwwwwwwwwwwww, где. означает, что игрок не двигается.

Я искал много решений, но ни одно из них по какой-то причине не работает. Даже когда я использую сеттеры для настройки анимации ... происходит то же самое.

Мой код неверен? Я что-то пропустил?

Вот класс с плеером и KeyListener. Что-то не так?

import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;


class Play extends JPanel implements KeyListener, ActionListener{
JFrame playFrame = new JFrame("Play");

int xPos = 295;
int yPos= 215;

int xWorld = 0;
int yWorld = 0;

int worldSizeX = 640;
int worldSizeY = 480; 

boolean w, a, s, d, shift, esc, b;

Font font;

private BufferedImage[] walkingDown = {Sprite.getSprite(0,0), Sprite.getSprite(1,0), Sprite.getSprite(2,0), Sprite.getSprite(3,0)};
private BufferedImage[] walkingDownLeft = {Sprite.getSprite(0,1), Sprite.getSprite(1,1), Sprite.getSprite(2,1), Sprite.getSprite(3,1)};
private BufferedImage[] walkingDownRight = {Sprite.getSprite(0,2), Sprite.getSprite(1,2), Sprite.getSprite(2,2), Sprite.getSprite(3,2)};
private BufferedImage[] walkingUp = {Sprite.getSprite(0,5), Sprite.getSprite(1,5), Sprite.getSprite(2,5), Sprite.getSprite(3,5)};
private BufferedImage[] walkingUpLeft = {Sprite.getSprite(0,6), Sprite.getSprite(1,6), Sprite.getSprite(2,6), Sprite.getSprite(3,6)};
private BufferedImage[] walkingUpRight = {Sprite.getSprite(0,7), Sprite.getSprite(1,7), Sprite.getSprite(2,7), Sprite.getSprite(3,7)};
private BufferedImage[] walkingLeft = {Sprite.getSprite(0,3), Sprite.getSprite(1,3), Sprite.getSprite(2,3), Sprite.getSprite(3,3)};
private BufferedImage[] walkingRight = {Sprite.getSprite(0,4), Sprite.getSprite(1,4), Sprite.getSprite(2,4), Sprite.getSprite(3,4)};
private BufferedImage[] standing = {Sprite.getSprite(0,0)};

private Animation walkDown = new Animation(walkingDown, 12);
private Animation walkDownLeft = new Animation(walkingDownLeft, 12);
private Animation walkDownRight = new Animation(walkingDownRight, 12);
private Animation walkUp = new Animation(walkingUp, 12);
private Animation walkUpLeft = new Animation(walkingUpLeft, 12);
private Animation walkUpRight = new Animation(walkingUpRight, 12);
private Animation walkLeft = new Animation(walkingLeft, 12);
private Animation walkRight = new Animation(walkingRight, 12);
private Animation stand = new Animation(standing, 12);

private BufferedImage[] rollingDown = {Sprite.getSprite(0,8), Sprite.getSprite(1,8), Sprite.getSprite(2,8), Sprite.getSprite(3,8)};
private BufferedImage[] rollingDownLeft = {Sprite.getSprite(0,9), Sprite.getSprite(1,9), Sprite.getSprite(2,9), Sprite.getSprite(3,9)};
private BufferedImage[] rollingDownRight = {Sprite.getSprite(0,10), Sprite.getSprite(1,10), Sprite.getSprite(2,10), Sprite.getSprite(3,10)};
private BufferedImage[] rollingUp = {Sprite.getSprite(0,13), Sprite.getSprite(1,13), Sprite.getSprite(2,13), Sprite.getSprite(3,13)};
private BufferedImage[] rollingUpLeft = {Sprite.getSprite(0,14), Sprite.getSprite(1,14), Sprite.getSprite(2,14), Sprite.getSprite(3,14)};
private BufferedImage[] rollingUpRight = {Sprite.getSprite(0,15), Sprite.getSprite(1,15), Sprite.getSprite(2,15), Sprite.getSprite(3,15)};
private BufferedImage[] rollingLeft = {Sprite.getSprite(0,11), Sprite.getSprite(1,11), Sprite.getSprite(2,11), Sprite.getSprite(3,11)};
private BufferedImage[] rollingRight = {Sprite.getSprite(0,12), Sprite.getSprite(1,12), Sprite.getSprite(2,12), Sprite.getSprite(3,12)};

private Animation rollDown = new Animation(rollingDown, 12);
private Animation rollDownLeft = new Animation(rollingDownLeft, 12);
private Animation rollDownRight = new Animation(rollingDownRight, 12);
private Animation rollUp = new Animation(rollingUp, 12);
private Animation rollUpLeft = new Animation(rollingUpLeft, 12);
private Animation rollUpRight = new Animation(rollingUpRight, 12);
private Animation rollLeft = new Animation(rollingLeft, 12);
private Animation rollRight = new Animation(rollingRight, 12);

private Animation animation = stand;

Timer timer = new Timer(12, this);

public Play(){
    playFrame.setPreferredSize(new Dimension(640,480));
    playFrame.pack();
    playFrame.setResizable(false);
    playFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    playFrame.setLocationRelativeTo(null);

    addKeyListener(this);
    setFocusable(true);

    timer.start();

    playFrame.setVisible(true);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;

    setBackground(Color.CYAN);

    g2d.setColor(Color.GREEN);
    g2d.fillRect(xWorld,yWorld, 640,480);

    g2d.drawImage(animation.getSprite(), xPos, yPos, null);

    if(esc == true){
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0,0, 640,480);

        try{
            font = Font.createFont(Font.TRUETYPE_FONT, new File("pixelated/pixelated.ttf"));
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("pixelated/pixelated.ttf")));
        }catch(IOException|FontFormatException e){
        }

        g2d.setFont(font.deriveFont(80f));
        g2d.setColor(Color.WHITE);
        g2d.drawString("Paused", 205,80);

        g2d.setFont(font.deriveFont(30f));
        g2d.drawString("To resume, press W, A, S or D", 150,150);

        g2d.drawString("Or", 305,240);

        g2d.drawString("Press ESCAPE + B to go back to MainMenu <--", 40,320);

        if(esc == true && w == true){
            esc = false;
        }
        if(esc == true && a == true){
            esc = false;
        }
        if(esc == true && s == true){
            esc = false;
        }
        if(esc == true && d == true){
            esc = false;
        }
    }
}

public void keyPressed(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_W) w = true;
    if(e.getKeyCode() == KeyEvent.VK_A) a = true;
    if(e.getKeyCode() == KeyEvent.VK_S) s = true;
    if(e.getKeyCode() == KeyEvent.VK_D) d = true;
    if(e.getKeyCode() == KeyEvent.VK_SHIFT) shift = true;
    if(e.getKeyCode() == KeyEvent.VK_ESCAPE) esc = true;
    if(e.getKeyCode() == KeyEvent.VK_B) b = true;

    //walking
    if(w == true){      
        yWorld = yWorld+1;

        animation = walkUp;
        animation.start();

        repaint();
    }
    if(a == true){
        xWorld = xWorld+1;

        animation = walkLeft;
        animation.start();

        repaint();
    } 
    if(s == true){
        yWorld = yWorld-1;

        animation = walkDown;
        animation.start();

        repaint();
    }
    if(d == true){
        xWorld = xWorld-1;

        animation = walkRight;
        animation.start();

        repaint();
    }

    if(w==true && a==true){
        yWorld = yWorld+1;
        xWorld = xWorld+1;

        animation = walkUpLeft;
        animation.start();
    }       
    if(w==true && d==true){
        yWorld = yWorld+1;
        xWorld = xWorld-1;

        animation = walkUpRight;
        animation.start();
    }       
    if(s==true && a==true){
        yWorld = yWorld-1;
        xWorld = xWorld+1;

        animation = walkDownLeft;
        animation.start();
    }       
    if(s==true && d==true){
        yWorld = yWorld-1;
        xWorld = xWorld-1;

        animation = walkDownRight;
        animation.start();
    }

    //rolling
    if(w==true && shift==true){
        yWorld = yWorld+5;

        animation = rollUp;
        animation.start();

        repaint();
    }
    if(a==true && shift==true){
        xWorld = xWorld+5;

        animation = rollLeft;
        animation.start();

        repaint();
    }
    if(s==true && shift==true){
        yWorld = yWorld-5;

        animation = rollDown;
        animation.start();

        repaint();
    }
    if(d==true && shift==true){
        xWorld = xWorld-5;

        animation = rollRight;
        animation.start();

        repaint();
    }

    if(w==true && a==true &&shift==true){
        yWorld = yWorld+1;
        xWorld = xWorld+1;

        animation = rollUpLeft;
        animation.start();
    }       
    if(w==true && d==true &&shift==true){
        yWorld = yWorld+1;
        xWorld = xWorld-1;

        animation = rollUpRight;
        animation.start();
    }       
    if(s==true && a==true &&shift==true){
        yWorld = yWorld-1;
        xWorld = xWorld+1;

        animation = rollDownLeft;
        animation.start();
    }       
    if(s==true && d==true &&shift==true){
        yWorld = yWorld-1;
        xWorld = xWorld-1;

        animation = rollDownRight;
        animation.start();
    }

    if(esc == true && b == true){
        esc = false;

        playFrame.setVisible(false);

        new MainMenu();
    }
}

public void keyReleased(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_W) w = false;
    if(e.getKeyCode() == KeyEvent.VK_A) a = false;
    if(e.getKeyCode() == KeyEvent.VK_S) s = false;
    if(e.getKeyCode() == KeyEvent.VK_D) d = false;
    if(e.getKeyCode() == KeyEvent.VK_SHIFT) shift = false;
    if(e.getKeyCode() == KeyEvent.VK_B) b = false;

    if(w == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(a == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(s == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(d == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(shift == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }
}

public void keyTyped(KeyEvent e){
}

public void actionPerformed(ActionEvent e){     
    animation.update();

    if(yPos < yWorld){
        yWorld = yPos;
        yPos = yWorld;
    }
    if(xPos < xWorld){
        xWorld = xPos;
        xPos = xWorld;
    }       
    if((yPos+64) > (yWorld+worldSizeY)){
        yWorld = yPos-worldSizeY+64;
        yPos = (yWorld+worldSizeY)-64;
    }
    if((xPos+64) > (xWorld+worldSizeX)){
        xWorld = xPos-worldSizeX+64;
        xPos = (xWorld+worldSizeX)-64;  
    }
  }
}

1 Ответ

1 голос
/ 08 апреля 2020

когда я нажимаю клавиши для перемещения указанного игрока (W, A, S и D), игрок останавливается, немного ждет, затем идет нормально.

Это связано с тем, что «частота повторения» клавиатуры контролируется настройкой вашей ОС. Не полагайтесь на ОС для генерации событий.

Вместо этого вы должны использовать Swing Timer для планирования событий. Когда клавиша:

  1. нажата, вы запускаете таймер.
  2. выпущен, вы останавливаете таймер.

Также вы должны использовать «Связывание клавиш», а не KeyListener.

Прочитайте разделы из учебника по Swing на :

  1. Как использовать таймеры качания
  2. Как использовать привязки клавиш

для получения дополнительной информации по этим понятиям.

Вы также можете проверить: Движение с помощью клавиатуры . Пример Keyboard Animation включает два приведенных выше предложения. Кроме того, метод рисования только для живописи. Вы НЕ должны:

  1. читать файл шрифта
  2. устанавливать значения свойств

Вы не можете контролировать, когда вызывается метод paintComponent (), поэтому Вы должны рисовать только текущее состояние вашего класса. Вам нужны другие методы для изменения состояния ваших переменных.

...