During college, I was initially focusing on an emphasis on web-based game development alongside programming. For that purpose, I created several games in JavaScript.
With this small demo, I wanted to create a turn-based combat system where the player could enter combat with several differing groups of enemies. I call it Slime, named after a common enemy type in many fantasy-themed games. In the game, the player acts as a slime-monster and must fight several enemies in an arena.
It can be played in any modern PC browser here: https://pycee.github.io/Web_Slime/
The source code for this demo can be found on GitHub: https://github.com/PyCee/Web_Slime
This game was developed in JavaScript with a small amount of HTML/CSS. There are two main areas of user control: Exploration and Combat.
Exploration
Exploration is where the player controls the Slime character to move around a map. Movement works by modifying the controlled character’s velocity based on button press/release events.
One map is explained in the following section.
The above image shows several things.
- The Slime (green square) – The character that the player controls.
- The Gate (top-center of the screen) – An area that is impassable until the player gets the key.
- The Key – An item that unlocks the gate.
- The Walls (black surrounding area) – An impassable area that defines the bounds of this room.
A basic physics system is in place to detect and respond to collisions. Every object has a box-shaped collider. The walls are made up of multiple box-shaped colliders to surround the playable area. Maps are made up of collision boxes and events that are called when the Slime character enters an event box.
When the character collides with the key, it disappears and a key is added to the player’s inventory. The inventory is referenced when interacting with the gate.
An example of how this is done in code is shown below.
key_pickup_test = function() {
// returns true if the slime character is touching the key
// otherwise, returns false
return key.bounding_box.intersects(slime.bounding_box);
};
key_pickup_callback = function () {
// Alert the player, put key item in inventory, and make
// the key on the map disappear
Dialogue.set(["Picked up a key!"], 1.5);
Inventory.add_item(key_item);
key.hide();
};
// Make an event out of key_pickup_test and key_pickup_callback so
// if key_pickup_test returns true, call key_pickup_callback
key_pickup_event = new Event(key_pickup_test,
key_pickup_callback);
When the character collides with the gate, the inventory is checked to see if the character has picked up the key. If the character has the key, the gate disappears and the character can progress. Otherwise, the gate remains impassable.
Once the character passes the gate, the map changes.
Combat
In a battle, the player takes turns with a basic enemy AI to select actions and attempt to reduce the opponent’s health to zero.
The Slime character has two actions: “Tackle” and “Heal”. “Tackle” will remove health from an enemy. If there is more than one enemy, the game prompts the user to select an enemy. “Heal” will give health to an ally. If there are multiple allies, the user must select one.
Combat is made up of several states. The enumeration of these states is shown below.
var Combat_State = {
// If there are multiple allied characters,
// select an allied character to use an action
// Then go to Combat_State.Action_Select
Characer_Select: 0,
// Select which of the character's actions to use
// If there are multiple potential targets for that action,
// go to Combat_State.Target_Select
// Otherwise, go to Combat_State.Player_Action
Action_Select: 1,
// Select a target for the selected action
// Then go to Combat_State.Player_Action
Target_Select: 2,
// Play animation and complete the effects of that action
// If the enemies have no health, go to Combat_State.Win
// Otherwise, go to Combat_State.Enemy_Action
Player_Action: 3,
// Randomly select an enemy/action to use
// If the player has no health, go to Combat_State.Lose
// Otherwise, go to Combat_State.Characer_Select
Enemy_Action: 4,
// The enemies have lost all health
// Play a victory animation and leave combat
Win: 5,
// The allied characters have lost all health
// Display a message then refresh the page
Lose: 6
};
Once a combat has ended an event is sent to the originating map so the story may progress.