JavaFX - 在移动小距离时跟随鼠标断断续续的绘制形状

时间:2016-11-13 12:10:50

标签: java canvas javafx

我正在尝试使用GraphicsContext2D绘制一个三角形形状,按照鼠标移动,同时面向它。

当你移动超过10个像素的距离时,它的效果非常漂亮和漂亮。但是,当您移动小的精确距离并且没有正确地面对鼠标时,形状会断断续续。

游戏:

public class Game extends Application {

    final static private String GAME_NAME = "Trigon";
    final static private int WINDOW_WIDTH = 960;
    final static private int WINDOW_HEIGHT = 640;
    private PlayerShip ply;

    @Override
    public void start(Stage theStage) throws Exception {
        // Set title of window & make root, canvas, graphics context
        theStage.setTitle(GAME_NAME);
        Group root = new Group();
        Scene theScene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
        Canvas canvas = new Canvas(WINDOW_WIDTH, WINDOW_HEIGHT);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        theStage.setScene(theScene);
        root.getChildren().add(canvas);

        // Initialize game variables
        ply = new PlayerShip(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);

        theScene.setOnMouseMoved(
            new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent e) {
                    ply.setPos(e.getX(), e.getY());
                }
            }
        );

        new AnimationTimer() {
            @Override
            public void handle(long currentNanoTime) {
                gc.setFill(Color.WHITE);
                gc.fillRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
                ply.draw(gc);
            }
        }.start();

        theStage.show();
    }

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

}

PlayerShip:

public class PlayerShip {
    private double shipLength, shipWidth;
    private double posX, posY, rotAngle;

    public PlayerShip(double posX, double posY) {
        this(posX, posY);
    }

    public PlayerShip(double posX, double posY) {
        this.posX = posX;
        this.posY = posY;
        this.shipWidth = 30;
        this.shipLength = 30;
    }

    public void setPos(double posX, double posY) {
        double distX = posX - this.posX;
        double distY = posY - this.posY;
        rotAngle = Math.toDegrees(Math.atan2(distX, -distY));
        this.posX = posX;
        this.posY = posY;
    }

    public void draw(final GraphicsContext gc) {
        // Save
        gc.save();

        // Translate + rotate
        gc.translate(posX, posY);
        gc.rotate(rotAngle);

        // Draw ship
        gc.beginPath();
        gc.moveTo(0, -shipLength/2);
        gc.lineTo(shipWidth/2, shipLength/2);
        gc.lineTo(-shipWidth/2, shipLength/2);
        gc.lineTo(0, -shipLength/2);
        gc.stroke();
        gc.closePath();

        // Restore
        gc.restore();
    }
}

对于文本块或者我忘记重要内容感到抱歉。

1 个答案:

答案 0 :(得分:1)

当船的原点太靠近鼠标位置时会发生这种情况。鼠标位置的微小变化会导致角度发生较大变化,从而导致模板效应。

您可以通过不将船舶移动到鼠标位置,但将其移动到靠近鼠标的点来解决此问题:

public void setPos(double posX, double posY) {
    double distX = posX - this.posX;
    double distY = posY - this.posY;

    // movement distance
    double magnitude = Math.sqrt(distX * distX + distY * distY);

    if (magnitude > 5) {
        // only move, if the distance is greater than 5

        // factor to move to distance 5
        double factor = (magnitude - 5) / magnitude;

        this.posX += distX * factor;
        this.posY += distY * factor;
        rotAngle = Math.toDegrees(Math.atan2(distX, -distY));
    }
}