At the moment, these pick-ups are picked-up regardless of player state, if health is full, then the health pick-up is wasted.
There should be a game condition where if the player's health is full, the item is instead stored when picked up.
Summary
The Health pickup entity should be refactored to allow for storing items picked up by the player.
Will require some extra properties on the Player.js entity e.g. storedPickups = { health: <number> }...
Will require a new method in the Player.js entity:
Method to increment storedPickups.health when a health item is picked up.
Will need to rework the Health.js - pickup() method:
Check the player's health (will require access to the game or player object)
If the player's health is full, call the first method described above in the Player.js entity to store the item
Otherwise refill the player's health and then mark for deletion.
Will need to rework the createKeyboardMouseControls() method in Game.js to map the hotkey to the existing refillHealth() method in the Player.js entity to refill health when pressed.
Will need to rework the Player.js - refillHealth() method to know when it's being called via a hotkey so it can check for stored pickup items to use (it currently just refills using the value passed by the pickup).
The actual action/effect from pickup items happens within Game.js in the onUpdate() method (which is what triggers each entity's update() method every frame):
for (let i = 0; i < this.entities.length; i++) {
if (this.canUpdateEntity(this.entities[i])) {
this.entities[i].update(this);
}
if (this.entities[i].type === 'pickup') {
if (this.entities[i].markToDelete) { // this is set to true, therefore an item has been picked up
// If a health item has been picked up, call the player entity to refill health
if (this.entities[i].item === 'health') {
this.player.refillHealth(this.entities[i].value);
}
...
// Remove picked up entities from the canvas
this.entities.splice(i, 1);
}
}
...
So in sequence:
The Game.js manager calls onUpdate every frame.
onUpdate loops through the game entities (walls, player, enemies, pickup items)
Each updateable entity's update() method is called to update the entity's position, collision vectors, bounds etc.
In the case of pickup item entities, the Collision.js - entityToPlayer() method takes a 3rd parameter, this is a callback that is executed when the entities intersect. In other words, the pickup() callback is executed when the player reaches the item.
The pickup() method plays the audio FX snippet and then marks the entity for deletion.
Back in Game.js, the onUpdate() method, while looping through entities every frame, checks to see if the pickup item has been marked for deletion
In the case of health items, the Player.js - refillHealth() method is called, passing the value of the pickup item (25)
How it should work
The markToDelete functionality needs to remain, as it is responsible for deleting the entity and removng it from the canvas once it's picked up.
However, the logic to refill the player's health (this.player.refillHealth(this.entities[i].value);) should be removed from the Game.js - onUpdate() method and instead handled in the Health.js entity's pickup() method, something like:
pickup (game) {
const { player } = game;
// If the player's health is full, then store the pickup instead
if (player.health === 100) {
// you could store a copy of the entity
player.storePickupItem(this);
AudioFX.snippet({ name: 'pickup' });
} else {
// Otherwise refill the player's health now
player.refillHealth(this.value);
AudioFX.snippet({ name: 'inject' });
}
this.markToDelete = true;
}
This should be fairly straight-forward, because the pickup() method is executed as a callback passed from the same class' update() method, which already has access to the game object... Example:
update (game) {
Collision.entityToPlayer(this, game, () => { // we're already passing an anonymous function
this.pickup(game); // ...so simply pass the game here
});
}
At the moment, these pick-ups are picked-up regardless of player state, if health is full, then the health pick-up is wasted.
There should be a game condition where if the player's health is full, the item is instead stored when picked up.
Summary
The Health pickup entity should be refactored to allow for storing items picked up by the player.
Player.js
entity e.g.storedPickups = { health: <number> }
...Player.js
entity:storedPickups.health
when a health item is picked up.Health.js
-pickup()
method:game
orplayer
object)Player.js
entity to store the itemcreateKeyboardMouseControls()
method inGame.js
to map the hotkey to the existingrefillHealth()
method in thePlayer.js
entity to refill health when pressed.Player.js
-refillHealth()
method to know when it's being called via a hotkey so it can check for stored pickup items to use (it currently just refills using the value passed by the pickup).How it currently works
Here is the current
pickup()
method inHealth.js
:This is triggered by the entity's
update()
method (every entity has an update method which is called on every frame or "repaint"):The actual action/effect from pickup items happens within
Game.js
in theonUpdate()
method (which is what triggers each entity'supdate()
method every frame):So in sequence:
Game.js
manager callsonUpdate
every frame.onUpdate
loops through the game entities (walls, player, enemies, pickup items)update()
method is called to update the entity's position, collision vectors, bounds etc.Collision.js
-entityToPlayer()
method takes a 3rd parameter, this is a callback that is executed when the entities intersect. In other words, thepickup()
callback is executed when the player reaches the item.pickup()
method plays the audio FX snippet and then marks the entity for deletion.Game.js
, theonUpdate()
method, while looping through entities every frame, checks to see if the pickup item has been marked for deletionPlayer.js
-refillHealth()
method is called, passing the value of the pickup item (25)How it should work
The
markToDelete
functionality needs to remain, as it is responsible for deleting the entity and removng it from the canvas once it's picked up.However, the logic to refill the player's health (
this.player.refillHealth(this.entities[i].value);
) should be removed from theGame.js
-onUpdate()
method and instead handled in theHealth.js
entity'spickup()
method, something like:This should be fairly straight-forward, because the
pickup()
method is executed as a callback passed from the same class'update()
method, which already has access to thegame
object... Example: