How to code Collision Detection in C# Console App Games
While learning Object Oriented Programming, I tried to create a text based RPG with C#. My toughest challenge at that moment is how to make my character knows that he had just touched a wall, or an enemy, therefore he cannot continue in that direction. The result is quite satisfying when I finally created a solution for this challenge.
In this entry, I am going explain how I created a Collision Detection algorithm for my own game.
The video above showed a brief gameplay where the main character (red) encountered and fight a demon (cyan) in a dungeon. The main character is controlled by the player via keyboard input, and the demon is controlled by a A.I with a primitive path finding algorithm.
The main character and the enemy are subclasses which derived from a superclass. Their visual form is stored in their own array like this.
player.PhysicalForm = new string[]
{
@" Θ ",
@"┌─┼─┐",
@" ┌┴┐ ",
@" │ │ ",
};
enemy.PhysicalForm = new string[]
{
@")/ ",
@"Y\_/",
@" /~\",
};
The map visual elements are also stored inside an array within its own class.
map = new string[]
{
@"███████████████████████████████████████████████████████████████████████████████████████████████████████████████████",
@"██ ██ ██ ",
@"██ ██ ██ ",
@"██ ██ ",
@"██ ██ ",
@"██ ██ ",
@"██ ██ ",
@"██ ████████ ████████",
@"██ ████████████████████████████████ ██",
@"██ ████████████████████████████████ ██",
@"██ ███ ████████ ╔═════════════╗ ██",
@"██ ███ ████████ ║ ║ ██",
@"██ ███ ████████ ║ ██",
@"██ ███ ████████ ████████ ║ ██",
@"██ ███ ████████ ║ ██",
@"██ ███ ████████ ║ ██",
@"██ ███ ████████ ║ ██",
@"██ ███ ████████ ║ ║ ██",
@"██ ███ ████████ ╚═════════════╝ ██",
@"███████████████████████████████████████████████████████████████████████████████████████████████████████████████████"
};
Solution concept
This is my idea:
With every move, each character will perform a position check (of X and Y coordinates) between its position and every obstacle element position of the map.
Collision happens when there are any duplicating coordinates. The algorithm will immediately send a signal to any colliding object to act appropriately.
Since the gameplay characters are not displayed as a single char on the screen, the coordinate check should perform on multiple chars simultaneously.
Additionally, each gameplay character has a different shape, so the coordinate check should be done on the character’s borders only.
Solution code
A custom method is created, it needs some passed-in data to perform the collision check.
observingObject needs to be the map class.
observer could be the main character or the enemy class.
The visual data was stored in an array data type but they are different in length and character count. So, to be flexible in storing every character coordinates, it’s best to use List<T>. 2 lists to store map X and Y, 1 list to store the map content.
private void CollisionCheckInsideBounds(CharacterObject observingObject, CharacterObject observer)
{
//Coordinates list
List allX = new List();
List allY = new List();
//Content list
List charMapList = new List();
int xB = observingObject.X;
int yB = observingObject.Y;
}
The next step is separating the map array into single characters and adding them to the constructed lists.
//------------- Break down observing object coordinates
for (int i = 0; i < observingObject.Width * observingObject.Height; i++)
{
allX.Add(xB); xB++;
allY.Add(yB);
if (xB > observingObject.X + observingObject.Width - 1)
{
xB = observingObject.X;
yB++;
}
}
//------------- Break down observing object array content into characters and put them into a list
for (int i = 0; i < observingObject.PhysicalForm.Length; i++)
{
foreach (char c in observingObject.PhysicalForm[i])
}
Well, all the data is here, lets compare.
Character and Enemy class has a method to obtain their own boundaries (step 4 in solution concept).
So,the general mechanics is when Character/Enemy detected any of its boundary elements entered an area that shared the same coordinates with the map that is not known as ‘ ‘ ( an empty space) or (char)32 in ASCII codes. A collision has happened.
for (int i = 0; i < allY.Count; i++)
{
if (observer.BoundaryTopX.Contains(allX[i]) && observer.BoundaryTopY.Contains(allY[i]) && charMapList[i] != " ")
{
observer.BlockedVertically = BlockedDirection.Up;
}
}
for (int i = 0; i < allY.Count; i++)
{
if (observer.BoundaryBotX.Contains(allX[i]) && observer.BoundaryBotY.Contains(allY[i]) && charMapList[i] != " ")
{
observer.BlockedVertically = BlockedDirection.Down;
}
}
for (int i = 0; i < allX.Count; i++)
{
if (observer.BoundaryLeftX.Contains(allX[i]) && observer.BoundaryLeftY.Contains(allY[i]) && charMapList[i] != " ")
{
observer.BlockedHorizontally = BlockedDirection.Left;
}
}
for (int i = 0; i < allX.Count; i++)
{
if (observer.BoundaryRightX.Contains(allX[i]) && observer.BoundaryRightY.Contains(allY[i]) && charMapList[i] != " ")
{
observer.BlockedHorizontally = BlockedDirection.Right;
}
}
At this point, your Character/Enemy should know if it collided with map obstacle or not. What to do next is up to you to decide. I hope this simple code could help with your project. You could view the whole solution here
Thank you for reading and you’re welcome to discuss further in the comment section.