java – 在玩家后面创建一条尾随血迹

我目前正在制作一个简单的自上而下的射击游戏.物体是一个在屏幕上滑动的球,我试图做出一种湿拖动的效果.

我正在使用Java Swing,并且只使用默认的Graphics2d lib.

这就是我所拥有的:

这是我的目标:

我需要知道如何制作一条能够在尾端改变alpha的曲线.我在线搜索但我只能找到非动态解决方案. (当玩家在屏幕上移动时,尾部需要更新.)

解决方法:

一个简单的解决方案可能是简单地将每个点添加到移动玩家之前的List of Points.

你只需要迭代这个列表,然后简单地使用Graphics#drawLine甚至GeneralPath之类的东西来渲染“拖动”行,例如……

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Drag {

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

    public Drag() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<Point> points;
        private Point pos;

        private int diametere = 10;

        public TestPane() {
            points = new ArrayList<>(25);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");

            ActionMap am = getActionMap();
            am.put("left", new MoveAction(-5, 0));
            am.put("right", new MoveAction(5, 0));
            am.put("up", new MoveAction(0, -5));
            am.put("down", new MoveAction(0, 5));

            pos = new Point(100 - (diametere / 2), 100 - (diametere / 2));
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (points.size() > 1) {
                g2d.setColor(Color.RED);
                GeneralPath path = new GeneralPath();
                boolean started = false;
                System.out.println("----");
                for (Point p : points) {
                    if (started) {
                        System.out.println(p);
                        path.lineTo(p.x, p.y);
                    } else {
                        path.moveTo(p.x, p.y);
                        started = true;
                    }
                }
                g2d.draw(path);
            }
            int radius = (int) (diametere / 2d);
            g2d.setColor(Color.GREEN);
            g2d.draw(new Ellipse2D.Double(pos.x - radius, pos.y - radius, diametere, diametere));
            g2d.dispose();
        }

        protected void moveBy(int xDelta, int yDelta) {

            if (pos.x + xDelta < 0) {

                xDelta = 0;
                pos.x = 0;

            } else if (pos.x + xDelta + diametere > getWidth()) {

                xDelta = 0;
                pos.x = getWidth() - diametere;

            }
            if (pos.y + yDelta < 0) {

                yDelta = 0;
                pos.y = 0;

            } else if (pos.y + yDelta + diametere > getHeight()) {

                yDelta = 0;
                pos.y = getWidth() - diametere;

            }

            points.add(new Point(pos));

            pos.x += xDelta;
            pos.y += yDelta;

            repaint();

        }

        public class MoveAction extends AbstractAction {

            private int xDelta;
            private int yDelta;

            public MoveAction(int xDelta, int yDelta) {
                this.xDelta = xDelta;
                this.yDelta = yDelta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                moveBy(xDelta, yDelta);
            }

        }
    }

}
上一篇:OSX上的JavaFX screencapture无头异常


下一篇:java – 获取类之外的JPanel的宽度和高度