Java 如何在游戏中实现物理引擎跳跃

Java 如何在游戏中实现物理引擎跳跃,java,game-physics,Java,Game Physics,我需要使用一个物理引擎或类似的东西来实现一个向下抛物线跳跃的游戏,我有。现在,向上箭头只会使角色浮动,但我需要他跳跃 这是我的密码: import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHin

我需要使用一个物理引擎或类似的东西来实现一个向下抛物线跳跃的游戏,我有。现在,向上箭头只会使角色浮动,但我需要他跳跃

这是我的密码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class Level extends JPanel {
    public static String chicken = "chicken.gif";
    public static String chicken2 = "chicken2.gif";
    private static final int PREF_W = 1440;
    private static final int PREF_H = 500;
    private static final int TIMER_DELAY = 20;
    private static final String KEY_DOWN = "key down";
    private static final String KEY_RELEASE = "key release";
    public static final int TRANSLATE_SCALE = 3;
    public static final String back = "back.gif";
    public static final String corn = "corn.gif";
    private EnumMap<Direction, Boolean> dirMap = new EnumMap<Level.Direction, Boolean>(
            Direction.class);
    private BufferedImage image = null;
    private BufferedImage image2 = null;
    private BufferedImage image3 = null;
    private static int imgX = 20;
    private static int imgY = 320;
    private static Random rand = new Random();
    private static int cImgX = rand.nextInt(1420) + 10;
    private static int cImgY = 335;
    private static int cornCounter = 0;
    private static String Counter = Integer.toString(cornCounter);
    private static final Font BG_STRING_FONT = new Font(Font.SANS_SERIF,
            Font.BOLD, 32);
    private int bgStringX;

    public Level() {
        for (Direction dir : Direction.values()) {
            dirMap.put(dir, Boolean.FALSE);
        }
        try {
            File bback = new File(back);
            image2 = ImageIO.read(bback);
            File ccorn = new File(corn);
            image3 = ImageIO.read(ccorn);
            File img = new File(chicken);
            image = ImageIO.read(img);
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Timer(TIMER_DELAY, new TimerListener()).start();

        // here we set up our key bindings
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = getInputMap(condition);
        ActionMap actionMap = getActionMap();
        for (final Direction dir : Direction.values()) {

            // for the key down key stroke
            KeyStroke keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0,
                    false);
            inputMap.put(keyStroke, dir.name() + KEY_DOWN);
            actionMap.put(dir.name() + KEY_DOWN, new AbstractAction() {

                @Override
                public void actionPerformed(ActionEvent arg0) {
                    dirMap.put(dir, true);
                }
            });

            // for the key release key stroke
            keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0, true);
            inputMap.put(keyStroke, dir.name() + KEY_RELEASE);
            actionMap.put(dir.name() + KEY_RELEASE, new AbstractAction() {

                @Override
                public void actionPerformed(ActionEvent arg0) {
                    dirMap.put(dir, false);
                }
            });
        }
        FontMetrics fontMetrics = getFontMetrics(BG_STRING_FONT);
        int w = fontMetrics.stringWidth(Counter);

        bgStringX = (PREF_W - w) / 2;
    }

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


    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        if (image != null) {
            g.drawImage(image2, 0, 0, this);
            validate();
            g.drawImage(image3, cImgX, cImgY, this);
            validate();
            g.drawImage(image, imgX, imgY, this);
            validate();
        }

        g.setFont(BG_STRING_FONT);
        g.setColor(Color.BLACK);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.drawString(Counter, bgStringX, 190);
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (Direction dir : Direction.values()) {
                if (dirMap.get(dir)) {
                    imgX += dir.getX() * TRANSLATE_SCALE;
                    imgY += dir.getY() * TRANSLATE_SCALE;

                    //System.out.println(imgY);

                    if(imgX >= 188 && imgX <= 380) {
                        if(imgY <= 190 && imgY >= 199) {
                            imgY = 194;
                        }
                    }


                    if (imgX >= (cImgX - 10) && imgX <= (cImgX + 10)) {
                        cImgX = rand.nextInt(1420) + 10;
                        repaint();
                        validate();
                        cornCounter += 1;
                        Counter = Integer.toString(cornCounter);
                        //System.out.println(cornCounter);
                        repaint();
                        validate();
                    }

                    if(imgX <= -60) {
                        imgX = 1373;
                        repaint();
                        validate();
                    }
                    else if(imgX >= 1442) {
                        imgX = 1;
                        repaint();
                        validate();
                    }


                    if(imgY >= 320) {
                        imgY = 320;
                    }
                    else if(imgY <= 1) {
                        imgY = 1;
                    }

                }
            }
            repaint();
        };
    }


    enum Direction {

        Up(KeyEvent.VK_UP, 0, -1),
        Left(KeyEvent.VK_A, -1, 0), Right(KeyEvent.VK_D, 1, 0),
        LeftA(KeyEvent.VK_LEFT, -1, 0), RightA(KeyEvent.VK_RIGHT, 1, 0),
        Down(KeyEvent.VK_DOWN, 0, 1);

        private int keyCode;
        private int x;
        private int y;

        private Direction(int keyCode, int x, int y) {
            this.keyCode = keyCode;
            this.x = x;
            this.y = y;
        }

        public int getKeyCode() {
            return keyCode;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

    }

    private static void createAndShowGui() {
        Level mainPanel = new Level();

        JFrame frame = new JFrame("Cockadoodle Duty: Awakening");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGui();
            }
        });
    }
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Font;
导入java.awt.FontMetrics;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.event.*;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.EnumMap;
导入java.util.Random;
导入javax.imageio.imageio;
导入javax.swing.*;
@抑制警告(“串行”)
公共类级扩展JPanel{
公共静态字符串chicken=“chicken.gif”;
公共静态字符串chicken2=“chicken2.gif”;
专用静态最终整数预值W=1440;
专用静态最终int PREF_H=500;
专用静态最终int定时器_延迟=20;
私有静态最终字符串KEY\u DOWN=“KEY DOWN”;
私有静态最终字符串KEY_RELEASE=“KEY RELEASE”;
公共静态最终int翻译_比例=3;
公共静态最终字符串back=“back.gif”;
公共静态最终字符串corn=“corn.gif”;
私有EnumMap dirMap=新EnumMap(
方向(类别),;
私有缓冲区映像=空;
private BuffereImage image2=null;
private BuffereImage image3=null;
专用静态int imgX=20;
专用静态int imgY=320;
私有静态随机兰德=新随机();
私有静态int-cImgX=rand.nextInt(1420)+10;
私有静态int-cImgY=335;
专用静态计数器=0;
私有静态字符串计数器=整数.toString(cornCounter);
私有静态最终字体BG\u字符串\u字体=新字体(Font.SANS\u SERIF,
Font.BOLD,32);
私有int bgStringX;
公共级别(){
for(Direction dir:Direction.values()){
dirMap.put(dir,Boolean.FALSE);
}
试一试{
文件bback=新文件(返回);
image2=ImageIO.read(bback);
文件ccorn=新文件(corn);
image3=ImageIO.read(ccorn);
文件img=新文件(鸡肉);
图像=图像读取(img);
}捕获(IOE异常){
e、 printStackTrace();
}
新定时器(定时器延迟,新定时器延迟()).start();
//这里我们设置了密钥绑定
int condition=JComponent.WHEN在聚焦窗口中;
InputMap InputMap=getInputMap(条件);
ActionMap ActionMap=getActionMap();
对于(最终方向dir:Direction.values()){
//对于向下键笔划
击键击键=击键.getKeyStroke(dir.getKeyCode(),0,
假);
inputMap.put(击键,dir.name()+向下键);
actionMap.put(dir.name()+向下键,新建AbstractAction()){
@凌驾
已执行的公共无效操作(操作事件arg0){
dirMap.put(dir,true);
}
});
//对于键释放键笔划
击键=击键.getKeyStroke(dir.getKeyCode(),0,true);
inputMap.put(击键,目录名()+按键释放);
actionMap.put(dir.name()+KEY_RELEASE,new AbstractAction()){
@凌驾
已执行的公共无效操作(操作事件arg0){
dirMap.put(dir,false);
}
});
}
FontMetrics FontMetrics=getFontMetrics(BG_字符串_字体);
int w=fontMetrics.stringWidth(计数器);
bgStringX=(PREF_W-W)/2;
}
@凌驾
公共维度getPreferredSize(){
返回新维度(PREF_W,PREF_H);
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
如果(图像!=null){
g、 drawImage(图像2,0,0,this);
验证();
g、 drawImage(image3、cImgX、cImgY、this);
验证();
g、 drawImage(图像、imgX、imgY、this);
验证();
}
g、 setFont(BG_字符串_字体);
g、 设置颜色(颜色为黑色);
g2.setRenderingHint(RenderingHints.KEY\u TEXT\u抗锯齿,
RenderingHints.VALUE\u TEXT\u ANTIALIAS\u ON);
g、 抽绳(计数器,bgStringX,190);
}
私有类TimerListener实现ActionListener{
@凌驾
已执行的公共无效操作(操作事件e){
for(Direction dir:Direction.values()){
if(dirMap.get(dir)){
imgX+=dir.getX()*平移刻度;
imgY+=dir.getY();
//系统输出打印LN(imgY);
如果(imgX>=188&&imgX=(cImgX-10)&&imgX=320){
imgY=320;
}

如果你只想做一个简单的跳跃动作,那就太过分了

int vy = 0; //velocity of y
//.... heres your update code:
y += vy; //y is the yposition of your image or character
vy += GRAVITY; //GRAVITY is some arbitrary positive value
//...here's your onJump method:
vy = jumpSpeed; //jumpSpeed is some arbitrary negative value

你需要更具体一点。我们不想在你失去动力的情况下完成你的代码。