从 Java 的角度画线

Drawing Line From an Angle in Java

首先,我必须说这是一个repost。我之前的 post 被标记为重复,尽管我在编辑中非常清楚地说明了为什么这与另一个不同,但似乎没有人会访问它。这个问题仍然完全有效并且完全没有答案,所以请不要仅仅因为其他人也在用 Pacman 制作游戏而将其标记为重复。如果我纠正这个问题的方法是错误的,请原谅我并告诉我解决这个问题的正确方法,因为我对这个网站的功能仍然知之甚少。

我之前的post如下:

我正在制作一款以吃豆人为主题的乒乓球游戏。为了增加主题,我想在 Pacman 面对的角度画两条线,在球的两侧各画一条线。我将所有内容都放在一个 JPanel 中,因为我还没有达到使用组件的教育程度。我试图创建一个从我的 Pacman 获取参数的走廊对象,但我不知道如何进行触发。我的框架是 1000 x 1000,顶部 40 像素高的栏用于显示数据。 My Pacman 以度数提供信息,因此请在答案中说明这一点。谢谢,我会尽力回答任何问题。

更新:我已经完成了一些工作,并且我有一些代码可以分享这个主题。如下:

import java.awt.*;
public class Corridor
{
public Corridor()
{

}
public void drawLines(Graphics myBuffer, BallPacman pm)
{
double x1 = pm.getX();
double y1 = pm.getY() + 150;
double ix = pm.getdx();
double iy = pm.getdy();
double x2 = pm.getX();
double y2 = pm.getY() + 150;
    if (iy < 0) {
        while (x1 > 0 && y1 > 40) {
            x1 -= 0.1;
            y1 -= 0.1 * (iy / ix);
        }
        if (x1 <= 0)
        {
            y1 += (0 - x1) * (iy / ix);
            x1 = 0;
        }
        else {
            x1 += (40 - y1) * (iy / ix);
            y1 = 40;
        }
        while (x2 < 1000 && y2 < 1000) {
            x2 += 0.1;
            y2 += 0.1 * (iy / ix);
        }
        if (x2 >= 1000) {
            y2 -= (x1 - 1000) * (iy / ix);
            x2 = 1000;
        }
        else {
            x2 -= (1000 - y2) * (iy / ix);
            y2 = 1000;
        }
    }
    else {
        while (x1 > 0 && y1 > 40) {
            x1 -= 0.1;
            y1 -= 0.1 * -(iy / ix);
        }
        if (x1 <= 0)
        {
            y1 += (0 - x1) * -(iy / ix);
            x1 = 0;
        }
        else {
            x1 += (40 - y1) * -(iy / ix);
            y1 = 40;
        }
        while (x2 < 1000 && y2 < 1000) {
            x2 += 0.1;
            y2 += 0.1 * -(iy / ix);
        }
        if (x2 >= 1000) {
            y2 -= (x2 - 1000) * -(iy / ix);
            x2 = 1000;
        }
        else {
            x2 -= (y2 - 1000) * -(iy / ix);
            y2 = 1000;
        }
    }
    myBuffer.setColor (Color.BLUE);
    myBuffer.drawLine ((int)x1, (int)y1, (int)x2, (int)y2);
}
}

不幸的是,这会产生奇怪的结果,例如移动和垂直线。我意识到它只产生一行,但它是为了测试。 BallPacman 有一个移动方法,每次调用计时器时,它都会移动 dx 和 dy。 dx 和 dy 可正可负。

更新:我问了我的一个朋友,他说基本上,我想要的是有两条平行于 Ballpacman 所遵循的线的线。不幸的是,我不知道如何实现这个结果。

更新:我想 post 一些新的和额外的代码: 我用来获取角度的方法(输入dx和dy):

public double getFAngle (double x, double y)
{
    return Math.toDegrees(Math.atan2(x, y));
}

我试图用来获取线条的新策略(存在于 drawLines 方法中):

double angle = pm.getFAngle (pm.getdx(), pm.getdy());
int x1 = (int) (pm.getX() + 5000 * Math.cos (angle * Math.PI / 180));
int x2 = (int) (pm.getX() - 5000 * Math.cos (angle * Math.PI / 180));
int y1 = (int) (pm.getY() + 5000 * Math.sin (angle * Math.PI / 180));
int y2 = (int) (pm.getY() - 5000 * Math.sin (angle * Math.PI / 180));
myBuffer.setColor (Color.BLUE);
myBuffer.drawLine (x1, y1, x2, y2);`

这种方法是尝试制作一条直线穿过 Pacman 路径的直线。我的想法是,如果我能做到这一点,我就可以通过简单地分别增加和减少第 1 行和第 2 行的 y 点来实现墙壁。它在 90 的每个倍数(包括 0)中看起来都完美无缺。但是,它在所有其他角度上的工作方式非常奇怪。我可以为此提供的唯一具体信息是它在 45 度角处垂直。此外,线路在移动,这至少是不可取的。这段代码也破坏了我将端点直接放在墙上的愿望。请允许我详细说明我的计划的目标:

  1. 感知吃豆人的正确角度
  2. 画两条平行于吃豆人路径的线,这样吃豆人就不会 随时拦截他们。优选地,这些线路将具有 以下四行中至少有两行的端点:x = 0, x = 1000, y = 40, y = 1000
  3. 无论 Pacman 的 X 和 Y 方向如何,都绘制相同的线。换句话说,这些线不应因 Pacman 沿路径的任何进展变化而改变。
  4. 当吃豆人的角度发生变化时,线条也会发生变化以反映该变化。每次调用的计算是否 运行 都无关紧要,只要存在正确的结果,即具有正确角度的静态(非移动)线。

谢谢。

更新(重新post): 自上次更新以来,我最好的代码没有改变。然而,我对它为什么不起作用进行了一些思考,并提出了以下假设:它在 90 度倍数上的效果与在其他所有角度上的效果一样糟糕。然而,角度的性质使我看不到线在移动。因此,我必须猜测代码是有缺陷的,因为它无法忽略 Pacman 的移动。

更新: 为了响应我多次收到的图片请求,我从 VGR 优秀代码工作的少数几个角度之一得到了这个 rendering。 正如我所说,该代码适用于 90 度的倍数,例如上面的那个,但不能正确呈现所有其他角度。作为对 VGR 评论的回应,当 Pacman 的 x 和 y 发生变化时,它们永远不会移动(因为它们不必如此),但会响应 Pacman 改变角度而移动。将这些线想象成 Corridor 的墙,它总是移动到 Pacman 需要去的地方。当吃豆人走下走廊时,他们永远不会移动,但一旦他到达死胡同,走廊就会移动以适应他的新方向。我真诚地希望这会有所帮助。

你的想法是对的:

Shape originalClip = myBuffer.getClip();
myBuffer.clipRect(0, 40, 1000, 1000 - 40);

double x = pm.getX();
double y = pm.getY();
double angle = Math.atan2(pm.getdy(), pm.getdx());
double dx = PACMAN_RADIUS * Math.sin(angle);
double dy = PACMAN_RADIUS * Math.cos(angle);

double x1 = x - dx;
double x2 = x + dx;
double y1 = y - dy;
double y2 = y + dy;

myBuffer.setColor(Color.BLUE);

myBuffer.drawLine((int) (x1 - 5000 * dy),
                  (int) (y1 + 5000 * dx),
                  (int) (x1 + 5000 * dy),
                  (int) (y1 - 5000 * dx));

myBuffer.drawLine((int) (x2 - 5000 * dy),
                  (int) (y2 + 5000 * dx),
                  (int) (x2 + 5000 * dy),
                  (int) (y2 - 5000 * dx));

myBuffer.setClip(originalClip);

一些注意事项:

  • clipRect 用于确保线条不会在 y=40 以上绘制。
  • 转换为度数只是为了转换回弧度是没有意义的。
  • atan2 期望 dy 作为第一个参数,dx 作为第二个参数。