Battling Through to the Exit
Develop our game further to include challenges for the player.
We'll cover the following...
Our game needs a challenge, or it won’t be fun. A challenge will reduce the chances of the player winning and let them feel like they overcame something when they do win.
For our challenge, we’ll implement a room with an enemy. The hero and the enemy will fight, and the first one to reach zero hit points is defeated. We need to build a list of enemies, create functions to reduce and restore character hit points, build a battle module, and create a room that can trigger a battle. Once we have a room-trigger contract, we need to follow it strictly.
The first step will be to construct a list of enemies, creating the lib/dungeon_crawl/enemies.ex
file with the following code:
defmodule DungeonCrawl.Enemies doalias DungeonCrawl.Characterdef all, do: [%Character{name: "Ogre",description: "A large creature. Big muscles. Angry and hungry.",hit_points: 12,max_hit_points: 12,damage_range: 3..5,attack_description: "a hammer"},%Character{name: "Orc",description: "A green evil creature. Wears armor and an axe.",hit_points: 8,max_hit_points: 8,damage_range: 2..4,attack_description: "an axe"},%Character{name: "Goblin",description: "A small green creature. Wears dirty clothes and a dagger.",hit_points: 4,max_hit_points: 4,damage_range: 1..2,attack_description: "a dagger"},]end
We’ve used the same DungeonCrawl.Character
struct of the hero to create the enemies. It’s a list of suggested enemies. Feel free to create more or change the list. The next step is to create functions that permit the reduction or restoration of a character’s hit points and another function that displays the character’s current hit points. Let’s write these functions in the DungeonCrawl.Character
module:
defmodule DungeonCrawl.Character dodefstruct name: nil,description: nil,hit_points: 0,max_hit_points: 0,attack_description: nil,damage_range: nildefimpl String.Chars dodef to_string(character), do: character.nameend@type t :: %DungeonCrawl.Character{name: String.t,description: String.t,hit_points: non_neg_integer,max_hit_points: non_neg_integer,attack_description: String.t,damage_range: Range.t}def take_damage(character, damage) donew_hit_points = max(0, character.hit_points - damage)%{character | hit_points: new_hit_points}enddef heal(character, healing_value) donew_hit_points = min(character.hit_points + healing_value,character.max_hit_points)%{character | hit_points: new_hit_points}enddef current_stats(character),do: "Player Stats\nHP: #{character.hit_points}/#{character.max_hit_points}"end
The take_damage/2
function receives a character and the number of hit points ...