Question

This question is a continuation of a question originally posted here.

I'm trying my hand at creating a Snake clone with JavaFX. One of the requirements for the game is to have a sort of powerup food, which increases the velocity of the snake.

For my game loop, I'm using a Timeline with a single KeyFrame, which acts as the game tick. Every game object is rendered onto a Canvas.

To increase the velocity of the game, I currently stop the timeline and recreate its keyframe with a shorter duration.

The problem, however, is that the instance methods to do so are in class Game, but the caller is an instance of State, which Game has instantiated.

Is there a way to avoid a cyclic dependency here, but also keep it elegant? I'm open to redesigning the architecture.

Was it helpful?

Solution

This is a situation where I like to use callbacks. In a nutshell, you pass the function(s) the child object needs to call on the parent object as parameters to the child object e.g. in the constructor of the child. This allows you to avoid coupling the child object's class definition to the parent object's class definition. I'm not sure what language features you have in JavaFX but if you can't use function references, you can define a callback interface. The interface is also useful when you have multiple functions you want the child object to call.

Another completely opposite direction is to create the child object's class as an inner class of the parent. In pure Java, this gives you an implicit reference to the parent object's class in the child object's class. If your child class is implicitly coupled to the parent, this might be the easiest way to go. You can achieve the same thing by passing the parent to the child in the constructor. In general, I haven't found this to be a problematic approach. It only really creates issues if you what to decouple the parent object and child object. In that case, I would stick with the callbacks.

OTHER TIPS

The problem, however, is that the instance methods to do so are in class Game, but the caller is an instance of State, which Game has instantiated

So like

class Game{

  State state = new State();

  void changeVelocity(int someVelocity){  ... }

}

class State{

  //...
  //want to change game speed
  gameThatOwnsThisState.changeVelocity();

}

You use of parent and child here are inaccurate; Game is not the parent, State is not the child. They have a "Game has-a State" relationship, but if they were parent and child in the inherited sense (what OO people think of whenm they see parent/child) then they would have a "State is-a Game" relationship

In short, I think the answer to you question is "no", or "it depends what you mean by 'elegant non cyclic', but probably no".

Simplistically the Game can pass itself to the State when it creates it, and the state then has access to the Game instance on which to invoke the method - i think you'd class this as a cyclic reference/dependency.

You could have some eventing mechanism where State will announce a "WantToChangeSpeed" event that Game will listen to, but that seems similarly circularly dependent because all you've done really is pass a delegate method of Game to State for it to call when it wants to change speed. Or perhaps this satisfies you because it isn't a direct dependency; any method/delegate passed will suffice and State could exist independently of Game

Perhaps if Game is regularly inspecting the state it can read a property of the State and decide to change speed and thus remains "outside looking in" and State is relatively ignorant of everything - it just mutates every tick, however long a tick takes

Licensed under: CC-BY-SA with attribution
scroll top