BACKGROUND
I have the following:
class Fire extending Element,
class Wood extending Element,
class Tile which composites Element.
The Tile class represents a tile in a world/screen/canvas, and has some graphical and logical functionality in it. It composites an Element object, because every tile in the "world" is made out of some substance (=element).
I want to achieve the functionality of fire spreading - when a fire element "touches" a wood element, I want the wood element to become fire. Logically, this should be done within the fire element, but doing that, I'm unable to change the given Tile's element (e.g. from Wood to Fire).
The "world" is initialized as a grid of tiles that are composed of Wood elements, except for one tile that has a Fire element which is supposed to spread.
WHAT I'VE TRIED
I've tried Linking together elements, meaning each element has access to his four nearest neighbors. That way a fire can access a nearby piece of wood. This doesn't solve the problem of changing a Tile's element type when fire touches wood.
I've tried moving the entire functionality to the Tile class. Although it does solve the problem, I don't like it for two reasons:
Logically, I want the fire to act autonomously, meaning the fire is what spreads, and not the tile.
As a result, the Tile class has many methods that are only fire related (such as spread()), which requires me to check - "is this tile composed of a fire element?", which is bad practice.
CODE EXAMPLE
class Fire extends Element{
public void spread(){
// Move to all four neighbors and turn them into Fire elements
}
}
class Wood extends Element{
}
class Tile{
private Element _element;
}
IN DEPTH
The 'grid' of tiles consists of a 2-dimensional array of Tiles (logic part), and a JavaFx Pane consisting of all tiles (visual part).
A fire 'spreads' when it touches a neighbor tile and turns it from Wood to Fire. A fire ceases to spread when it consumed (=changed to fire) a given threshold of wood, e.g. after it consumed 30 pieces of wood. In a sense, the fire can keep track of the wood it consumed.
Thanks in advance!
My instant thought was there should a class to manage fire spreading. Let's say, there's a
Worldclass, the one that is aware of the grid of tiles and their nature.Firedoesn't know anything aboutWood, its location, its neighbours. The same goes forWood. They are independent objects that live their lives. TheWorldis up to decide where they reside and how they interact with each other.Let's imagine
Firereleases an event and tellsThe
Worldreceives the message, takes into account the fire's characteristics, and modify the grid accordingly.It would be interesting to have one instance of
Fireand keep track of all the elements it burned. I can see a modified version of the copy constructor.Though, you're free to figure out your own way how to record it.
With this, you would be able to restore cells (fully or partially) when the fire comes to end. You could also analyse how the fire was developing. I am not sure if this may come in handy, but it's fascinating to design.
I am thinking of alternatives... I still believe giving too much information (the whole map of tiles) to
Fireisn't a way to go and any interaction betweenWoodandFirecells should go through the manager class.Have a look at another scenario that suggests the
Worldprovides a partial view of itself as a list of contiguous to the fire elements.