我正在为我的游戏创建一个 Player
类,并且我需要某种方法来跟踪控件,但我想将键盘与玩家的 hitbox/渲染类分开跟踪。我设置了代码来将某些键的值(W、A、S、D 和 ▲、◄、▼、►)存储在我的主类中的变量中。我想以某种方式指向构造函数中的变量并以某种方式跟踪它们。
解决该问题的一种方法是将变量 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 的链接 Observer
和Observable
对象,供您学习,以防您想实现这些:
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/