当前位置: 首页 > 知识库问答 >
问题:

JavaFX localToScene导致结果是原来的两倍-为什么?

史鹏云
2023-03-14

各位程序员大家好,

我目前正在为我的研究编写一个小型图形应用程序,该应用程序将在一个小型2D游戏中展示AI。我现在有点困了。我制作了一个类层次结构,在顶部有实体,基本上代表任何实体,如玩家、敌人和障碍物,它有一个节点属性,以图形方式表示实体。实体还具有两个受保护的SimpleIntegerProperty对象x和y,我将节点属性的布局属性绑定到它们,因此每当我更改x和y的值时,图形表示也会移动。

到目前为止,我可以很好地做任何不依赖实体-对象坐标的事情。碰撞工作等。然而,当我试图实现一个在玩家角色所在的位置(x和y属性的值)生成子弹(小圆圈对象)的系统时,有一个奇怪的偏移量是玩家到左上角(右下角)距离的两倍。我做了一点实验,发现当我通过localToScene方法检查坐标时,无论是使用两个属性的值还是直接使用Node的layoutX和layoutY方法,它会给我坐标TWICE AS BIG作为实际坐标。我的窗格是600x600像素大,当我把我的播放器(另一个扩展到实体的对象)放在300,300时,一切看起来都很好,但是localToScene方法显然告诉我它是那个的两倍,所以是600,600。当我和我的播放器一起去右下角并通过localToScene打印坐标时,它告诉我它在1200,1200。

public void addProjectile(Projectile p)
{
    Projectile p2 = new PlayerProjectile(100, 100, 0.5);
    projectiles.add(p2);
    System.out.println(p2.getSkin().localToScene(p2.getX(), p2.getY()));
    System.out.println(p2.getSkin().getLayoutX() + " " + p2.getSkin().getLayoutY());
    this.getChildren().add(p2.getSkin());
    System.out.println(p2.getSkin().getLayoutX() + " " + p2.getSkin().getLayoutY());

// p.setPosition(p.getSkin().localToScreen(p.getX(), p.getY()));

}

该方法在100100处创建射弹(layoutX和Y也确认了这一点)。然后,我将投射物p2添加到ArrayList(不重要)。第一次打印给我两个坐标,200和200。第二次打印给了我100和100。第三次打印也给了我10和100(加上这个,这是一个窗格,显然不会改变任何东西,也不是原因)。

有没有人知道为什么它会把一切都翻一番?这是所有相关的课程。

玩家项目类:

public class PlayerProjectile extends Projectile
{

public static final int FIRE_RATE = 5; // Higher is slower

public PlayerProjectile(int x, int y, double dir)
{

    super(x, y, dir);
    range = 150;
    speed = 4;
    damage = 20;

    nx = (int) (speed * Math.cos(angle));
    ny = (int) (speed * Math.sin(angle));

}

@Override
public void update()
{

    move();

}

@Override
protected void move()
{
    x.setValue(x.getValue() + nx);
    y.setValue(y.getValue() + ny);

    // if (distance() > range)
    // {
    // remove();
    // }
}
}

射弹等级:

public abstract class Projectile extends Entity
{
final protected int xOrigin, yOrigin;

protected double angle;

protected int nx, ny;

protected double distance;

protected double speed, range, damage;

public Projectile(int x, int y, double dir)
{
    super(x, y);
    skin = new Circle(x, y, 3);
    ((Circle) skin).setFill(new Color(0, 1, 0, 1));
    xOrigin = x;
    yOrigin = y;
    angle = dir;
    // this.getVisual().translateXProperty().bind(this.x);
    // this.getVisual().translateYProperty().bind(this.y);
    this.getSkin().layoutXProperty().bind(this.x);
    this.getSkin().layoutYProperty().bind(this.y);
    // this.getVisual().getChildren().add(skin);
}

protected void move()
{

}

public int getX()
{
    return x.getValue().intValue();
}

public int getY()
{
    return y.getValue().intValue();
}

public int getOriginX()
{
    return xOrigin;
}

public int getOriginY()
{
    return yOrigin;
}
}

实体类:

public class Entity
{
private boolean removed = false;

protected Level level;

protected Node skin;

// PROPERTIES FÜR X UND Y KOORDINATEN DES SKINS DES SPIELERS
protected SimpleIntegerProperty x, y;

// VISUELLE REPRÄSENTATION DER ENTITY
// protected Pane visual = new Pane();

public Entity()
{

}

public Entity(int x, int y)
{
    this.x = new SimpleIntegerProperty(x);
    this.y = new SimpleIntegerProperty(y);

}

public void update()
{

}

public void remove()
{
    // Remove from level
    removed = true;
}

public void setX(int x)
{
    this.x.setValue(x);
}

public void setY(int y)
{
    this.y.setValue(y);
}

public void setPosition(Point2D p)
{
    this.setX((int) p.getX());
    this.setY((int) p.getY());
}

public boolean isRemoved()
{
    return removed;
}

public void init(Level level)
{
    this.level = level;
}

// public Pane getVisual()
// {
// return visual;
// }

public Node getSkin()
{
    return skin;
}

}

共有1个答案

太叔岳
2023-03-14

localToScene从局部坐标转换为场景坐标。局部坐标相对于调用该方法的节点的原点。转换已包括此节点的<code>layoutX

Inverse(sceneToLocal) * P = Inverse(Inverse(nodeTransform)) * P
                          = Inverse(Inverse(Translation(P))) * P
                          = Translation(P) * P
                          = 2 * P

在局部坐标系中变换原点以获得实际位置:

p.setPosition(p.getSkin().localToScreen(0, 0));
 类似资料:
  • 为什么结果是: =NaN =无穷大 我知道或除法有一点不同。我对得到的NaN非常满意,因为当某物除以零时,结果并不是定义的。但是为什么他们定义大于零除以零的结果是不独立呢?这和他们用来执行浮点除法的方法有关系吗?

  • 考虑下面的代码。 我理解在这里工作的等号操作符,因为我们隐式地转换为对象,等号操作符正在检查两者的引用是否相等并返回false。 但我对第二个问题感到困惑,返回true看起来像是调用字符串类型提供的Equals override实现,如果它们相等,它会检查字符串的内容。 我的问题是,为什么它也不检查运算符的内容平等性,它们的实际类型是string而不是object。正当 而下面的代码为两者输出tu

  • 问题内容: 据我了解,python模块永远不会导入两次,即该模块中的代码仅在首次导入时才执行。随后的import语句只需将模块添加到导入范围即可。 我有一个名为“ TiledConvC3D.py”的模块,但似乎已多次导入。我使用pdb在该模块的代码顶部打印堆栈。 这是从第一次执行模块开始的堆栈跟踪的结尾: 它将继续执行多次。但是,第二次调用的完整堆栈跟踪不会显示对的任何调用,因此不应执行这些执行:

  • 本文向大家介绍资本结构的指导原则是什么?,包括了资本结构的指导原则是什么?的使用技巧和注意事项,需要的朋友参考一下 财务经理必须根据某些原则和可用资金来源来决定正确的资本组合,以实现最大的回报。资本结构的指导原则如下- 成本原则 风险原则 控制原理 弹性原则 时间原则 成本原则- 该原则的主要关注点是以最小的融资成本获得最大的每股收益。 利率和税率控制着融资成本。 债务资本更便宜。 风险原则 该原

  • minecraft 1.8.8的modcoderpack918中的有一个很大的问题。我的Java版本是1.8.0_271-B09。 我不知道我必须做什么。

  • 问题内容: 我在搜索我的网站上具有自动完成/提前输入功能。我看到他们有时是一个例外。我们正在使用代理服务器。 引起原因:java.net.ConnectException:连接被拒绝 这是我的编码方式 谁能告诉我为什么我只在某个时候得到这个例外?是否可能是由于从Android应用程序发出搜索请求而导致此异常,因为我们的网站不支持从android应用程序发出请求 问题答案: 当您尝试打开与IP地址/