我正在为我的游戏创建一个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);
}
}
答案 0 :(得分:1)
正如JB Nizet所提到的,如果没有至少一个有效的代码示例,很难提供帮助。但这是我对此的抨击。听起来您可能想要考虑实现观察者模式。 Java提供了界面Observer
和类Observable
来执行此操作,但您不必使用它们。
以下是Java Observer
和Observable
对象的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);
}
}
我不知道我是否可以解释这个例子,而不是解释自己:)。
我不确定是否需要现场直播,但我希望它有所帮助。我确实从这个解释中留下了一些东西,但这基本上就是观察者的工作方式。通过这种方式,一个班级可以非常灵活的方式观察另一个班级的价值观。