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

时间:2015-01-23 13:56:42

标签: java

我正在为我的游戏创建一个Player类,我需要一些方法来跟踪控件,但我想从播放器的hitbox / rendering类中单独跟踪键盘。我设置代码来存储某些键的值( W A S D 和< kbd>▲,)在变量中,在我的主类中。我想以某种方式指向构造函数中的变量,并以某种方式跟踪它们。

解决问题的一种方法是将变量w替换为player2.up,依此类推,因此我的键盘跟踪方法可以直接编辑Player个对象,但这不是&#39}。这样灵活。我也可以将调用对象传递给构造函数,但这更不灵活。我现在必须在播放器类中跟踪键盘,但以某种方式引用变量真的很酷。

我必须同时传递KeyListener界面提供的常量,但这里是代码:

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);
    }

}

1 个答案:

答案 0 :(得分:1)

正如JB Nizet所提到的,如果没有至少一个有效的代码示例,很难提供帮助。但这是我对此的抨击。听起来您可能想要考虑实现观察者模式。 Java提供了界面Observer和类Observable来执行此操作,但您不必使用它们。

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

Observer JavaDoc, Observable JavaDoc

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

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()分别处理添加(注册),删除(取消注册)和通知任何观察者的更改。

现在,让我们看看一个与我们的observable一起使用的简单MyObserverObject

public class MyObserverObject {     private String 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的{​​{1}}方法。在此示例中,我编写了一个方法来验证Collection registeredObservers是否已更改,如果MyObservableObject返回true,则hasChanged()实例将调用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);
}
}

我不知道我是否可以解释这个例子,而不是解释自己:)。

我不确定是否需要现场直播,但我希望它有所帮助。我确实从这个解释中留下了一些东西,但这基本上就是观察者的工作方式。通过这种方式,一个班级可以非常灵活的方式观察另一个班级的价值观。