[英]How can I get specific fields from an AnimationTimer object?
I've written a simple game using JavaFX for the GUI and AnimationTimer for the game itself, but I've found that any fields that update within the AnimationTimer object can't be found outside of the object.我已经编写了一个简单的游戏,使用 JavaFX 作为 GUI 和 AnimationTimer 作为游戏本身,但我发现在 AnimationTimer 对象内更新的任何字段都无法在对象之外找到。 I've managed to continuously record how long a game runs, and the score of that game, but can't find a way to get these values out of the AnimationTimer object so I can add them to my GUI.我已经设法连续记录游戏运行的时间以及该游戏的得分,但找不到从 AnimationTimer 对象中获取这些值的方法,以便我可以将它们添加到我的 GUI 中。
I've already tried java.lang.Reflect, but I can't seem to get it to work.我已经尝试过 java.lang.Reflect,但我似乎无法让它工作。
AnimationTimer animations = new AnimationTimer() //creates animations
{
@Override
public void handle(long now)
{
//update frames
if(jump == 0) //moves the player model to the starting position
{
playerY = 160;
}
else if(jump == 1) //moves the player model up (jumping)
{
playerY = 100;
}
if(shout == 1) //makes player immune while "shouting"
{
player.setFill(Color.GREEN);
}
if(shout == 0) //makes player not immune anymore
player.setFill(Color.BLUE);
if(obstacleX == PLAYER_X) //updates the score
{
points += 10;
score.setText("Score: " + String.valueOf(points));
}
if(player.getBoundsInParent().intersects(obstacle.getBoundsInParent())) //detects if the player model touches an obstacles
{
if(obstacle.getEndY() == 0)
{
if(player.getFill() == Color.BLUE)
player.setFill(Color.RED);
}
else if(obstacle.getEndY() == 130)
player.setFill(Color.RED);
}
if(obstacleX > 0) //moves the obstacles' reference point from the right to the left
obstacleX -= 5;
if(obstacleX == 0)
{
obstacleX = 400;
int[] array = new int[]{0, 0, 130};
Random randomNum = new Random();
int i = randomNum.nextInt(array.length);
random = array[i];
obstacle.setEndY(random);
}
//render frames
player.setCenterY(playerY);
obstacle.setStartX(obstacleX); //this and line 110 move the obstacle across the scene
obstacle.setEndX(obstacleX);
try{ //exception handler for outputs
if(player.getFill() == Color.GREEN)
{
digitalOutput6.setDutyCycle(1); //turns on green LED
digitalOutput0.setDutyCycle(0);
}
if(player.getFill() == Color.BLUE)
{
digitalOutput6.setDutyCycle(0); //turns off LEDs
digitalOutput0.setDutyCycle(0);
}
if(player.getFill() == Color.RED) //stops the animation when the player model reacts to touching an obstacle
{
endTime = System.currentTimeMillis() - startTime;
finalScore = score.getText();
this.stop(); //ends game
gameOver = 1;
digitalOutput0.setDutyCycle(1); //turns on red LED
digitalOutput6.setDutyCycle(0);
gameStage.setScene(gameEnd); //establishing scene
gameStage.setTitle("Game Over");
gameStage.show();
}
} //end of try block
catch(PhidgetException e)
{
System.out.println("Phidget Output Error");
}
} //end of animation handle itself
}; //end of animation method
I tried using我尝试使用
long finalTime = animations.getLong(endTime);
and和
String endScore = animations.getField(finalScore);
But no luck.但没有运气。 Any help appreciated.任何帮助表示赞赏。
AnimationTimer
itself doesn't expose any attributes, make a custom class which wraps an AnimationTimer
object in it, and save any attributes you want to access. AnimationTimer
本身不公开任何属性,创建一个包含AnimationTimer
对象的自定义类,并保存您想要访问的任何属性。
When you initialize the custom class, initialize the AnimationTimer
object and override the function (as what you've done), also updates whatever attributes you want to expose.当您初始化自定义类时,初始化AnimationTimer
对象并覆盖该函数(如您所做的那样),还会更新您想要公开的任何属性。
I am not familiar with javafx, there might be other better ways, this is the one quick solution I can think of.我对 javafx 不熟悉,可能还有其他更好的方法,这是我能想到的一种快速解决方案。
Did a quick search, these examples might be helpful:进行了快速搜索,这些示例可能会有所帮助:
https://netopyr.com/2012/06/14/using-the-javafx-animationtimer/ https://netopy.com/2012/06/14/using-the-javafx-animationtimer/
https://tbeernot.wordpress.com/2011/11/12/javafx-2-0-bubblemark/ https://tbeernot.wordpress.com/2011/11/12/javafx-2-0-bubblemark/
First of all do not use Reflections on Anonymous classes It will work but will cause a lot of ineffeciency and dirty code.首先不要在匿名类上使用反射它会工作,但会导致很多低效率和脏代码。 Second of all, you try to acces fields which are in the Methodscope of handle(long now) not in the Class scope.其次,您尝试访问句柄(现在很长时间)的方法范围内而不是类范围内的字段。
AnimationTimer t = new AnimationTimer() {
int fieldInt = 0; // would be accessible
@Override
public void handle(long now) {
//do something
}
};
AnimationTimer t = new AnimationTimer() {
@Override
public void handle(long now) {
int fieldInt = 0; // is not accessible as regular field
//do something
}
};
What you can do is the following:您可以执行以下操作:
Use a class that extends a Animationtimer使用扩展 Animationtimer 的类
public class Scheduler extends AnimationTimer{
private int gameEnd = 42;
private String someValue = "hello";
@Override
public void handle(long now) {
gameEnd += 1;
if(gameEnd >= 1000000) {
someValue ="Bye bye";
}
}
public String getSomeValue() {
return someValue;
}
here you can use:在这里你可以使用:
Scheduler s = new Scheduler();
s.start();
//whatever you want to do
System.out.Println(s.getSomeValue());
or when you want to use the Anonymous class approach, you should create a Property that is outside of AnimationTimer and use it.或者当您想使用匿名类方法时,您应该创建一个位于 AnimationTimer 之外的属性并使用它。 (Wich is a thing that I would prefer, because you can have a changeListener on the Property and recieve a callback when the value is changed) (这是我更喜欢的事情,因为您可以在属性上有一个 changeListener 并在值更改时接收回调)
public void whateverMethod() {
SimpleIntegerProperty gameEndProp = new SimpleIntegerProperty(42);
AnimationTimer t = new AnimationTimer() {
@Override
public void handle(long now) {
gameEndProp.set(gameEndProp.get()+1);
}
};
t.start();
//Do something
System.out.println(gameEndProp.get());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.