簡體   English   中英

我怎樣才能讓我的 Jump Animation 同時工作?

[英]How Can I Make My Jump Animation Work All At Once?

我在讓我的游戲角色跳躍方面遇到了一些問題。 我已經將我的跳轉 function 設置為空格鍵,但是跳轉 animation 不會一下子發生。 相反,按空格鍵會導致角色每次向上移動一點,直到達到最大跳躍高度限制。 然后,一旦它達到那個高度,按下空間會導致玩家每次向下移動一點,直到達到地面極限。 按住空格鍵的時候看起來很正常,但是一旦松開,角色就卡在了松開空格鍵的地方。 我希望通過單擊空格鍵一次完成所有序列。 我已經查看了我的代碼很長一段時間,並嘗試更改我從 JPanel 為我的 Player class 調用“act”方法的位置。 這是我的播放器 class ,其中的跳躍功能應該被分配其值:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;


public class Player {
    ImageIcon movements[];
    ImageIcon leftMove[];
    ImageIcon move[];
    ImageIcon attack;
    boolean ableAttack, canJump;
    int count, x, y, width, height;
    int fallingSpeed = 0;
    int gravity = 1;
    int jumpPower = -20;

    public Player(int count, int x, int y) {
        this.x = x;
        this.y = y;
        this.count = count;
        movements = new ImageIcon[8];
        leftMove = new ImageIcon[8];
        attack = new ImageIcon("attackRight.gif");
        this.width = 80;
        this.height = 130;
        for (int i = 0; i < 8; i++) {
            movements[i] = new ImageIcon("right_"+(i + 1) + ".png");
            leftMove[i] = new ImageIcon("go_"+(i+1)+".png");
        }
        move = movements.clone();
    }

    public void act() {
        if (isOnGround()) {
            canJump = true;
            jump();

        } else {
            canJump = false;
            fall();
        }
    }
    public void jump() {
        fallingSpeed = jumpPower;
        fall();
    }
    public void fall() {
        y += fallingSpeed;
        fallingSpeed = fallingSpeed + gravity;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public boolean isOnGround() {
        if (y > 410) 
            return true;
        return false;
    }

    public void setAttack(boolean attack) {
        ableAttack = attack;
    }

    public void setImageArrLeft() {
        move = leftMove.clone();
        attack = new ImageIcon("attack.gif");
    }
    public void setImageArrRight() {
        move = movements.clone();
        attack = new ImageIcon("attackRight.gif");
    }

    public void increaseCount() {
        count++;
    }

    public void myDraw(Graphics g) {
        if (ableAttack) {
            g.drawImage(attack.getImage(), x, y, width + 30, height + 10, null);
        } 
        else {
            g.drawImage(move[count % 8].getImage(), x, y, width, height, null);
        }   
    }
}

然后,在我的 JPanel class 中,我在我的 keyPressed 方法下調用 Player class 中的 act() 方法,從 KeyListener 接口檢查 VK_ENTER:

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

public class MyPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener, KeyListener{
    int mouseX, mouseY, x = 100, y = 420;
    Timer timer;
    ImageIcon background = null;
    Player p;
    
    public MyPanel() {
        timer = new Timer(60, this);
        p = new Player((int)(Math.random() * 8), x, y);
        background = new ImageIcon("battlefield1.png");
        addKeyListener(this);
        setFocusable(true);
    }
    
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(background.getImage(), 0, 0, 1375, 750, null);
        p.myDraw(g);
        repaint();
    }
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==timer) {
        }
    }

    public void mouseClicked(MouseEvent me) {}
    public void mouseEntered(MouseEvent me) {}
    public void mouseExited(MouseEvent me) {}
    public void mousePressed(MouseEvent me) {}
    public void mouseReleased(MouseEvent me) {}
    public void mouseDragged(MouseEvent me) {}
    public void mouseMoved(MouseEvent e) {}

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            p.increaseCount();
            if (x < 1300)
                x += 10;
            p.setX(x);
            p.setImageArrRight();
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            p.increaseCount();
            if (x > 0) 
                x -= 5;
            p.setX(x);
            p.setImageArrLeft();
        }
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            p.setAttack(true);
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            p.act();
        } 
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        p.setAttack(false);

    }
}

您需要更好地了解 animation(通常),尤其是游戲循環。

Swing 使用被動渲染方法,因此您需要設置一個“游戲循環”來更新游戲的 state,同時考慮到用戶給出的任何輸入,然后安排重繪。

這意味着,您不能在KeyListener中更新播放器的 state,而是需要設置一個 state 允許“游戲循環”更新整體 Z9ED39E2EA931586B6A985A6942EF573。

這是一個非常基本的例子......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new MyPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener, KeyListener {

        int mouseX, mouseY, x = 100, y = 420;
        Timer timer;
        Player p;

        public MyPanel() {
            timer = new Timer(60, this);
            p = new Player((int) (Math.random() * 8), x, y);
            setBackground(Color.BLUE);
            addKeyListener(this);
            setFocusable(true);
        }

        @Override
        public void addNotify() {
            super.addNotify();
            timer.start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            timer.stop();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 800);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            p.myDraw(g);
        }

        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == timer) {
                p.update();
                repaint();
            }
        }

        public void mouseClicked(MouseEvent me) {
        }

        public void mouseEntered(MouseEvent me) {
        }

        public void mouseExited(MouseEvent me) {
        }

        public void mousePressed(MouseEvent me) {
        }

        public void mouseReleased(MouseEvent me) {
        }

        public void mouseDragged(MouseEvent me) {
        }

        public void mouseMoved(MouseEvent e) {
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                p.increaseCount();
                if (x < 1300) {
                    x += 10;
                }
                p.setX(x);
                p.setImageArrRight();
            }
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                p.increaseCount();
                if (x > 0) {
                    x -= 5;
                }
                p.setX(x);
                p.setImageArrLeft();
            }
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                p.setAttack(true);
            }
            if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                p.act();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
            p.setAttack(false);

        }
    }

    public class Player {

        boolean ableAttack, canJump;
        int count, x, y, width, height;
        int fallingSpeed = 0;
        int gravity = 1;
        int jumpPower = -20;

        private boolean isJumping = false;

        public Player(int count, int x, int y) {
            this.x = x;
            this.y = y;
            this.count = count;
            width = 10;
            height = 10;
        }

        public void act() {
            if (isOnGround()) {
                jump();
//                canJump = true;
//                jump();
//
//            } else {
//                canJump = false;
//                fall();
            }
        }

        public void jump() {
            isJumping = true;
            fallingSpeed = jumpPower;
            fall();
        }

        public void fall() {
            y += fallingSpeed;
            fallingSpeed = fallingSpeed + gravity;
        }

        public void setX(int x) {
            this.x = x;
        }

        public void setY(int y) {
            this.y = y;
        }

        public boolean isOnGround() {
            if (y > 410) {
                return true;
            }
            return false;
        }

        public void setAttack(boolean attack) {
            ableAttack = attack;
        }

        public void setImageArrLeft() {
        }

        public void setImageArrRight() {
        }

        public void increaseCount() {
            count++;
        }

        public void update() {
            if (isJumping) {
                if (!isOnGround()) {
                    fall();
                } else {
                    isJumping = false;
                }
            }
        }

        public void myDraw(Graphics g) {
            g.setColor(Color.RED);
            g.fillRect(x, y, width, height);
        }
    }
}

就個人而言,我會使用Key Bindings over KeyListener ,因為它將解決鍵盤焦點的直接問題並提供更可配置的方法。

這意味着“輸入狀態”將獨立於玩家,並且游戲循環將負責控制玩家 state 基於游戲 state

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM