You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中复刻Game Maker Studio的point_angle函数及应用

Let's tackle this two-part problem step by step—first replicating GameMaker's point_angle function in Java, then integrating it with your movement logic.

1. Replicating GameMaker's point_angle in Java

GameMaker's point_angle(x1, y1, x2, y2) returns a clockwise angle (in degrees) from the point (x1,y1) to (x2,y2), with 0° pointing right, 90° pointing down, 180° left, and 270° up. Java's Math.atan2 uses a standard mathematical coordinate system (y-axis up, counterclockwise angles), so we need to adjust for the differences.

Here's a Java method that matches GameMaker's behavior exactly:

public static double pointAngle(double x1, double y1, double x2, double y2) {
    // Calculate the distance between points
    double deltaX = x2 - x1;
    double deltaY = y2 - y1;
    
    // Calculate counterclockwise angle in standard coordinates (y-up)
    // We invert deltaY to account for GameMaker's y-down system
    double mathAngleDegrees = Math.toDegrees(Math.atan2(-deltaY, deltaX));
    
    // Convert to GameMaker's clockwise 0-360° range
    double gameMakerAngle = (360 - mathAngleDegrees) % 360;
    
    // Ensure non-negative result (mod can return negative values for negative inputs)
    if (gameMakerAngle < 0) {
        gameMakerAngle += 360;
    }
    
    return gameMakerAngle;
}

How it works:

  • We first calculate the horizontal (deltaX) and vertical (deltaY) differences between the two points.
  • Math.atan2(-deltaY, deltaX) adjusts for GameMaker's downward-pointing y-axis, giving us a counterclockwise angle in radians.
  • Convert radians to degrees, then flip the angle to get a clockwise value, and wrap it to the 0-360° range.
2. Integrating the Angle with Your Movement Class

Your existing tick() method handles position updates using velX and velY—we just need to convert a target angle into these velocity components. First, let's clean up and expand your class for better functionality (using double for velocities makes movement smoother than int):

public class GameObject {
    public double x;
    public double y;
    public double velX = 0.0;
    public double velY = 0.0;
    
    public void tick() {
        x += velX;
        y += velY;
    }
    
    // Reuse the pointAngle method we created earlier
    public static double pointAngle(double x1, double y1, double x2, double y2) {
        double deltaX = x2 - x1;
        double deltaY = y2 - y1;
        
        double mathAngleDegrees = Math.toDegrees(Math.atan2(-deltaY, deltaX));
        double gameMakerAngle = (360 - mathAngleDegrees) % 360;
        
        if (gameMakerAngle < 0) {
            gameMakerAngle += 360;
        }
        
        return gameMakerAngle;
    }
    
    // Set velocity to move towards a target point at a given speed
    public void setVelocityTowards(double targetX, double targetY, double speed) {
        double angle = pointAngle(x, y, targetX, targetY);
        setVelocityAtAngle(angle, speed);
    }
    
    // Set velocity to move at a specific GameMaker-style angle
    public void setVelocityAtAngle(double angle, double speed) {
        // Convert angle from degrees to radians for trigonometric functions
        double radians = Math.toRadians(angle);
        
        // Calculate velocity components using cosine (x-axis) and sine (y-axis)
        velX = speed * Math.cos(radians);
        velY = speed * Math.sin(radians);
    }
}

Usage Example:

public class GameLoopExample {
    public static void main(String[] args) {
        GameObject player = new GameObject();
        player.x = 100.0;
        player.y = 100.0;
        
        // Make the player move towards (300, 200) at a speed of 5 units per tick
        player.setVelocityTowards(300.0, 200.0, 5.0);
        
        // Simulate 10 ticks of the game loop
        for (int i = 0; i < 10; i++) {
            player.tick();
            System.out.printf("Player Position: (%.1f, %.1f)%n", player.x, player.y);
        }
    }
}

Key Notes:

  • Using double for velX, velY, x, and y avoids the choppy movement that comes with integer-based positioning/velocity.
  • setVelocityTowards calculates the angle to your target point automatically, while setVelocityAtAngle lets you specify a fixed direction (like 90° for straight down).
  • The tick() method stays simple—it just applies the velocity to the position each frame, which fits perfectly into a standard game loop.

内容的提问来源于stack exchange,提问作者404 Name Not Found

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:48:52