如何实现物理引擎跳入游戏

时间:2015-06-07 15:14:29

标签: 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.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();
            }
        });
    }
}

1 个答案:

答案 0 :(得分:0)

如果你只是想实现一个简单的跳跃运动,这将是一个过度杀伤。

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