The deer is inaccessible hidden behind all these shrubs. Heracles stays on the lookout, waiting for her to get out of there. For that, the animal would already have to be able to move!
The deer is going to be a monster with a somewhat particular behavior, in particular because it will be able to move, which is not the case for the other monsters.
SOLID Note: You could implement deer-specific behavior directly in
Monster
. However, our hero still has a lot of beasts to fight and therefore as many specificities, which would ultimately make theMonster
class very busy and certainly full of conditions specific to this or that subtype of monsters.
Another solution is not to touch
Monster
directly, and to create aHind
class, inheriting fromMonster
, which will contain the code specific to the hinds. For each new type of monster with its own specificity, you add a new class. And it is still possible to instantiate a "basic" monster if you wish. This is the "Open/Close Principle" of SOLID. The classes, once defined, should remain "closed" to any modification (which would not concern all the objects of this class). If you happen to encounter such a case, the class must however be open to an extension, you must be able to create a child class easily.
In your new Hind
class, add an image
property with the value hind.svg.
Remember to import your new class in the index.html (Pay attention to the order of imports)
In the index.js file, modify the instantiation of a Monster
by a Hind
.
-
Each time the hero has finished moving, the monsters with the ability to move will do so, using the
move()
method themselves, which already contains all the movement logic (directions, tile checking...). We must therefore modify ourmove()
methods so that it can react to different moveableFighters
. So add a secondfighter
parameter (TheFighter
moved) to the method and fix the code accordingly. -
The gameplay will be as follows: the hero moves then, if his move was successful, all the monsters that have the ability move in turn. To differentiate which
Fighters
can move, add amoveable
property to Fighters which isfalse
by default. Pass it totrue
inHero
andHind
class. -
Heroes and monsters will use the same
move()
method to manage their movement, in order to benefit from the checks specific to allmoveable
. To manage this, we use theglobalMove(direction, hero)
method, this one is already taken into account.
Hint: In the
globalMove(direction, hero)
method, our hero is already moving thanks tomove()
. Consider passing thehero
parameter to it to update your code with your previous developments
- Then still in
globalMove()
loop on monsters implementingmoveable
totrue
.
- Generate a direction by creating a new method in monsters
getDirection()
which will returnN/S/W/E
randomly. - Then move the monster in that direction by reusing the
move()
method. - To be able to move, we must modify our
CheckNoMonster()
method so as not to take it into account if the monster in the box is the one that is moving... Watch out for your brain
- You can restart the game, you should see the deer move after each move of Heracles.
If you want to test, you can also add a second Hind and a Monster, the hinds should move and not the monster because it does not implement
moveable
! Then go back to a single doe on the map.
Last point, our doe moves but is blocked behind the bushes. Let's change that. If Heracles doesn't know how to get through the thorny bushes in the forest, that's no problem for the deer. So we're going to make the Bush tile non-traversable, except for a doe!
-
To do this, create the
isCrossable()
method in Tile which returns the value ofcrossable
by default. It takes an instance ofMonster
as a parameter. InArena
, when you useisCrossable()
, pass in parameter what is trying to move on this tile. -
In
Bush
now, redefineisCrossable()
so that the function returns true if and only ifmoveable
is an instance ofHind
. Use thejs
instanceOf method for this. Otherwise, returns the value of thecrossable
property (which must be false). In other words, the tile is not traversable unless it's a deer trying! -
In Arena.js, fix the call to the
crossable
check by your newisCrossable(fighter)
method.
Perform several movements, you will see that the doe should end up crossing the bushes, it's the long-awaited moment, catch her!
We won't be looking to implement Heracles actually capturing the Doe as that would take quite a bit of extra effort, but as always, if you'd like to give it a try, don't hesitate!