java - 用Java从一个角度画线

标签 java swing awt

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

我以前的帖子如下:

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

更新:我已经完成了一些工作,并且我有一些关于此主题的代码可以共享。如下:

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有一个move方法,每次调用计时器时,该方法都会将其移动dx和dy。 dx和dy可以为正或负。

更新:我问了我的一个朋友,他说的是,基本上,我要使两条线与Ballpacman遵循的线平行。不幸的是,我不知道如何获得这个结果。

更新:我想发布一些新的附加代码:
我用来获取角度的方法(输入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度垂直。此外,生产线还在移动,这至少是不希望的。这段代码也损害了我将端点直接放在墙上的愿望。请允许我详细说明我的程序的目标:


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


谢谢。

更新(重新发布时):
自上次更新以来,我最好的代码没有改变。但是,我已经思考了为什么它不起作用,并产生了以下假设:它在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是第二个参数。

关于java - 用Java从一个角度画线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36208241/

相关文章:

java - 如何使用 Jsoup 只获取第一级节点

Java:如何在 GridLayout 中嵌套 JPanel?

javax 打印 vs java awt 打印 api

java - 如何有效地实现 java.awt.Composite?

java - 以 JFrame 形式创建对象

java - @BeforeSuite 不工作

java - 如何将 "Set functions"(例如removeAll和addAll)从Java转换为C++?可以使用删除或插入来完成吗?

java - GUI JTextArea & JScrollPane & 定位

java - 我可以向 JFrame 添加 CSS 文件吗?

java - 无法在使用 jdk1.7 或 1.8 的 IntelliJ IDEA 中使用或导入 javax.swing 和 java.awt