【问题标题】:How to have an object access its invoking object's variables and modify them?如何让对象访问其调用对象的变量并修改它们?
【发布时间】:2016-05-10 14:51:53
【问题描述】:

假设我有一个 2d 侧视图类型的游戏。在这个游戏中,我有精灵和其他对象。当您单击空格键时,精灵会跳跃。跳跃和其他事情都受到重力的影响。我有一个Gravity 类,它需要它所影响的对象的 x 和 y 坐标的参数。当它从Sprite 类构造时,我会将精灵位置的 x 和 y 作为参数提供给它。然后,重力类进行必要的数学运算,现在有一个修改后的 x & y 坐标。如何将Sprite 类(即调用类)中的旧x & y 更新为Gravity 计算的新坐标对(需要修改Sprite 中变量的对象)?

额外信息: x & y 变量不能是静态的。目前这一切都在一个线程上(绘制的图形线程除外)。如果需要,我可以制作更多线程。我在重力类中有一个摆动定时器,它在创建对象时启动,用于计算坐标作为时间、速度、加速度等的影响。

重力等级代码:

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class Gravity implements ActionListener { 

    final double gravAccel = -32.174;
    double velocity; // in FPS
    double angle; // in degrees
    double x; // centralized location of object in feet
    double y; // centralized location in feet
    double time = 0;
    Timer timer;
    boolean fired = true;
    Point start;

    public Gravity(double x, double y, double velocity, double angle, Point start) {
        this.x = x;
        this.y = y;
        this.velocity = velocity;
        this.angle = angle;
        this.start = start;
        initTimer();
    }



    void initTimer() {
        timer = new Timer(10, this);
        timer.start();
    }   


    public void fire(double velocity, double angle) {
        //timer.start();
        x = (velocity * Math.cos(Math.toRadians(angle))) * time + start.getX();
        y = 0.5 * gravAccel * Math.pow(time, 2) + (velocity * Math.sin(Math.toRadians(angle))) * time + start.getY();
        System.out.println("Time:" + time + "          " + x + "," + y);

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        time = time + 0.01;
        if (fired == true) {
            fire(velocity, angle);
        }

    }
}

精灵:

public class Sprite {
    double x = 10; //how can I modify these from gravity
    double y = 10;
    Sprite() {
       new Gravity(x, y, 100, 45, new Point(0,0));
    }
}

【问题讨论】:

  • 你的精灵类调用它了吗?你不能只获取新重力的 x 和新重力的 y 并将精灵 x 和 y 位置设置为重力类吗?
  • @RileyCarney 你是指getter/setter吗?是的,我可以,但是计时器在重力类中,所以我必须在我的 Sprite 类中创建一个与重力计时器同步的新计时器,并在 Sprite 计时器的 actionPreformed() 方法中调用 get()为了更新 Sprite 的 x & y。这似乎不是很有效或干净。我真的不应该只需要一个 Timer 就可以让 Sprite 对象工作吗? (我可以将计时器移动到 Sprite 类,但是我必须将计时器添加到所有游戏对象中,在 Gravity 中内置一个计时器以使其适用于所有东西不是更容易吗?)
  • 你有一个主要的client 类或你的游戏运行的东西吗?你应该有一个类,在某种意义上,所有东西都“聚集在一起”,你的主游戏循环在哪里运行等等。
  • 我相信你应该把你的定时器线程放在那里,但是,我没有用 Java 做过太多的 Swing 编程,所以我不确定这是否是正确的做法。就个人而言,每当角色跳跃时,我都会运行计时器并对他应用物理,但如果他没有跳跃,则没有计时器运行,就像我阅读 Timer 的 javadoc 时一样,它说Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread.
  • 是的,你应该有一个游戏类作为控制器(看看 MVC),它有游戏计时器。

标签: java oop parameters constructor


【解决方案1】:

在 Gravity 中保留对 Sprite 的引用:

private Sprite;
public Gravity(double x, double y, double velocity, double angle, Point start, Sprite sprite) {
   this.sprite = sprite;
   ...
}

然后在创建时从 Sprite 传递它:

Sprite() {
   new Gravity(x, y, 100, 45, new Point(0,0), this);
}

【讨论】:

  • 聪明!正是我需要的。谢谢。
【解决方案2】:

您可以将xy 公开:

public double x = 10;
public double y = 10;

然后直接从精灵类中访问它们。

【讨论】:

  • 是的,我可以。但是,这仍然需要我在我的 Sprite 类中有某种计时器来从重力获取/设置 x 和 y,这样就达不到目的了。问题标题明确表示让对象修改其调用对象,而不是相反。
  • 不好的建议。这样做将使所有代码都有可能更改那些应该以非常受控的方式更改的值。无论如何,访问并不重要。为什么他们不能使用 getter 和 setter?
  • 然后将它们设为protected 并添加getter 和setter——这仍然是我的主要概念:让Gravity 类可以访问它们。
  • 看看 Ashwin Gupta 的回复 @Majora320,他想要一些不同的东西。
  • @RileyCarney 我正在回复 ChiefTwoPencils,我应该 \@提到他。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 2021-02-19
  • 2021-01-24
  • 1970-01-01
相关资源
最近更新 更多