java - 如何跟踪另一个类的变量值

标签 java

我正在为我的游戏创建一个 Player 类,并且我需要某种方法来跟踪控件,但我想将键盘与玩家的 hitbox/渲染类分开跟踪。我设置了代码来将某些键的值(WASD)存储在我的主类中的变量中。我想以某种方式指向构造函数中的变量并以某种方式跟踪它们。

解决该问题的一种方法是将变量 w 替换为 player2.up 等,因此我的键盘跟踪方法直接编辑 Player 对象,但这不太灵活。我还可以将调用对象传递给构造函数,但这更加不灵活。我现在必须从玩家类中跟踪键盘,但以某种方式引用变量真的很酷。

我必须同时传递 KeyListener 接口(interface)提供的常量,但代码如下:

package learn_game_programming;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Player extends Rectangle {

    private static final long serialVersionUID = 6027220656827265195L;

    int upKey;
    int downKey;
    int leftKey;
    int rightKey;
    boolean up;
    boolean down;
    boolean left;
    boolean right;
    int ym;
    int xm;
    KeyboardTracker keyListener;
    Component caller;
    String name;

    public Player() {
        // TODO Auto-generated constructor stub
    }

    public Player(Rectangle r) {
        super(r);
        // TODO Auto-generated constructor stub
    }

    public Player(Point p) {
        super(p);
        // TODO Auto-generated constructor stub
    }

    public Player(Dimension d) {
        super(d);
        // TODO Auto-generated constructor stub
    }

    public Player(int width, int height) {
        super(width, height);
        // TODO Auto-generated constructor stub
    }

    public Player(Point p, Dimension d) {
        super(p, d);
        // TODO Auto-generated constructor stub
    }

    public Player(String name, int x, int y, int width, int height, int upKey, int downKey, int leftKey, int rightKey, Component caller) {
        super(x, y, width, height);
        this.upKey = upKey;
        this.downKey = downKey;
        this.leftKey = leftKey;
        this.rightKey = rightKey;
        this.keyListener = new KeyboardTracker();
        this.caller = caller;
        caller.addKeyListener(this.keyListener);
        this.name = name;
    }

    private class KeyboardTracker implements KeyListener{
        public void keyPressed(KeyEvent ke){
            int key = ke.getKeyCode();
            if(key == upKey){
                up = true;
            }
            if(key == downKey){
                down = true;
            }
            if(key == leftKey){
                left = true;
            }
            if(key == rightKey){
                right = true;
            }
        }

        public void keyReleased(KeyEvent ke){
            int key = ke.getKeyCode();
            if(key == upKey){
                up = false;
            }
            if(key == downKey){
                down = false;
            }
            if(key == leftKey){
                left = false;
            }
            if(key == rightKey){
                right = false;
            }
        }

        public void keyTyped(KeyEvent x){

        }

        @SuppressWarnings("unused")
        public void actionPerformed(ActionEvent x){

        }

    }

    public void tick(){
        if(up){
            ym = -4;
            xm = 0;
        }
        if(down){
            ym = 4;
            xm = 0;
        }
        if(left){
            xm = -4;
            ym = 0;
        }
        if(right){
            xm = 4;
            ym = 0;
        }

        x += xm;
        y += ym;

        //System.out.println(x + ", " + y);

        if(this.y <= 25) y = 25;
        if(this.y >= caller.getHeight() - 10) y = caller.getHeight() - height;
        if(this.x <= 0) x = 0;
        if(this.x >= caller.getWidth() - 10) x = caller.getWidth() - height;
    }

    public void render(Graphics g){
        g.drawString(name, (x + width / 2) - g.getFontMetrics().stringWidth(name) / 2, y);
        g.fillOval(x , y, width, height);
    }

}

最佳答案

正如 JB Nizet 提到的,如果没有至少一个有效的代码示例,就很难提供帮助。但这是我的破解方法。听起来您可能想考虑实现观察者模式。 Java提供了接口(interface)Observer和类(class)Observable这样做,但您不必使用它们。

以下是 Java 的 JavaDocs 的链接 ObserverObservable对象,供您学习,以防您想实现这些:

Observer Java文档, Observable Java文档

以及有关该主题的深入教程的链接:

Observer and Observable tutorial

这是一个非常简单的可观察类和观察者类的示例。有很多需要考虑的事情没有在这个例子中。这只是为了说明这个概念:

public class MyObservableObject {
    private Collection<MyObserverObject> registeredObservers;
    private String  previousValue;
    private String  observedValue;
    private boolean isChanged;

public D(String observedValue) {
    this.observedValue = observedValue;
    registeredObservers = new LinkedList<MyObserverObject>();
    isChanged = false;
}

public boolean hasChanged() { return isChanged; }

private void setChanged() {
    isChanged = previousValue != null &&
                !previousValue.equalsIgnoreCase(observedValue);
}

public void setObservedValue(String observedValue) {
    previousValue = this.observedValue;
    this.observedValue = observedValue;
    setChanged();
    notifyObservers();
}

public String toString() { return observedValue; }

public void addObserver(MyObserverObject observer) {
    registeredObservers.add(observer);
}

public void removeObserver(MyObserverObject observer) {
    registeredObservers.remove(observer);
}

public void notifyObservers() {
    for (MyObserverObject ob : registeredObservers) { ob.notify(this); }
}
}

这是一个相当简单的设置:

  • 我们要跟踪的值是 String observedValue
  • Collection<MyObserverObject> registeredObservers是相当不言自明的。它将包含我们的自定义可观察对象在 observedValue 时通知的所有观察者对象。通过调用 setObservedValue(String) 进行更改.
  • addObserver(MyObserverObject) , removeObserver(MyObserverObject) ,和notifyObservers()它们分别处理添加(注册)、删除(取消注册)以及通知任何观察者更改。

现在,让我们看一个简单的 MyObserverObject与我们的可观察到的一起工作:

公共(public)类MyObserverObject { 私有(private)字符串 valuedWatched;

public MyObserverObject() { valuedWatched = null; }

public void notify(MyObservableObject observed) {
    if (observed.hasChanged()) updateMyValueWith(observed);
}

private void updateMyValueWith(MyObservableObject observed) { valuedWatched = observed.toString(); }

public String toString() { return valuedWatched; }
}

这个例子非常简单。每当MyObservableObject的实例称之为 notifyObservers()方法,它将调用notify(MyObservableObject)所有方法MyObserverObject Collection registeredObservers 中包含的内容。在此示例中,我编写了一个方法来验证 MyObservableObject已经改变,如果 hasChanged()返回 true,MyObserverObject实例将调用updateMyValueWith(MyObservableObject)方法。

现在,它正在发挥作用:

public class App {
public static void main(String[] args) {
    MyObservableObject myOb = new MyObservableObject("Bob");
    MyObserver ob = new MyObserver();
    System.out.println(myOb + " " + ob); 
    myOb.addObserver(ob);
    d.setObservedValue("Dave");
    System.out.println(myOb + " " + ob);
}
}

输出:

Bob null
Dave Dave

我不知道我是否可以解释这个例子,而不是它本身:)。

我不确定是否有必要进行手动演练,但我希望它有所帮助。我确实在这个解释中遗漏了一些东西,但这本质上就是观察者的工作原理。通过这种方式,一个类可以以一种非常灵活的方式观察另一个类的值。

关于java - 如何跟踪另一个类的变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28111497/

相关文章:

java - 如何将数据库中选定的行放入 jTable 中?

java - SetCellValue 不适用于第一行 java

java - Spring自定义转换器中的@Autowired

java - Java中Double类型的总和

Opensolaris 2009.6 上的 javac 异常

java - 如何计算两个 gio 点(lat 和 lng)之间的距离?

java - 阻止 ArrayOutOfBoundsException 在 Java 中停止程序执行

java - 有没有什么好的网站教Java中数据报套接字的使用?

java - 设置水果点的贪吃蛇游戏

java - 在接口(interface)中嵌套类在哪里有用?