Implementing map in RPG game C# with Example



Implementing map in RPG game C# with Example

Flyweight is one of structural design patterns. It is used to decrease the amount of used memory by sharing as 
much data as possible with similiar objects. This document will teach you how to use Flyweight DP properly. 
Let me explain the idea of it to you on a simple example. Imagine you're working on a RPG game and you need to 
load huge file that contains some characters. For example: 
# is grass. You can walk on it. 
$ is starting point 
@ is rock. You can't walk on it. 
% is treasure chest 
Sample of a map: 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
@############@@@@@######@#$@@@ 
@#############@@@######@###@@@ 
@#######%######@###########@@@ 
@############################@ 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
Since those objects have similiar characteristic, you don't need to create separate object for each map field. I will 
show you how to use flyweight. 
Let's define an interface which our fields will implement: 
public interface IField 
{ 
string Name { get; } 
char Mark { get; } 
bool CanWalk { get; } 
FieldType Type { get; } 
} 
Now we can create classes that represent our fields. We also have to identify them somehow (I used an 
enumeration): 
public enum FieldType 
{ 
GRASS, 
ROCK, 
START, 
CHEST 
} 
public class Grass : IField 
{ 
public string Name { get { return "Grass"; } } 
public char Mark { get { return '#'; } } 
 

public bool CanWalk { get { return true; } } 
public FieldType Type { get { return FieldType.GRASS; } } 
} 
public class StartingPoint : IField 
{ 
public string Name { get { return "Starting Point"; } } 
public char Mark { get { return '$'; } } 
public bool CanWalk { get { return true; } } 
public FieldType Type { get { return FieldType.START; } } 
} 
public class Rock : IField 
{ 
public string Name { get { return "Rock"; } } 
public char Mark { get { return '@'; } } 
public bool CanWalk { get { return false; } } 
public FieldType Type { get { return FieldType.ROCK; } } 
} 
public class TreasureChest : IField 
{ 
public string Name { get { return "Treasure Chest"; } } 
public char Mark { get { return '%'; } } 
public bool CanWalk { get { return true; } } // you can approach it 
public FieldType Type { get { return FieldType.CHEST; } } 
} 
Like I said, we don't need to create separate instance for each field. We have to create a repository of fields. The 
essence of Flyweight DP is that we dynamically create an object only if we need it and it doesn't exist yet in our 
repo, or return it if it already exists. Let's write simple class that will handle this for us: 
public class FieldRepository 
{ 
private List lstFields = new List(); 
private IField AddField(FieldType type) 
{ 
IField f; 
switch(type) 
{ 
case FieldType.GRASS: f = new Grass(); break; 
case FieldType.ROCK: f = new Rock(); break; 
case FieldType.START: f = new StartingPoint(); break; 
case FieldType.CHEST: 
default: f = new TreasureChest(); break; 
} 
lstFields.Add(f); //add it to repository 
Console.WriteLine("Created new instance of {0}", f.Name); 
return f; 
} 
public IField GetField(FieldType type) 
{ 
IField f = lstFields.Find(x => x.Type == type); 
if (f != null) return f; 
else return AddField(type); 
} 
} 
Great! Now we can test our code: 
public class Program 
{ 
 

public static void Main(string[] args) 
{ 
FieldRepository f = new FieldRepository(); 
IField grass = f.GetField(FieldType.GRASS); 
grass = f.GetField(FieldType.ROCK); 
grass = f.GetField(FieldType.GRASS); 
} 
} 
The result in the console should be: 
Created a new instance of Grass 
Created a new instance of Rock 
But why grass appears only one time if we wanted to get it twice? That's because first time we call GetField grass 
instance does not exist in our repository, so it's created, but next time we need grass it already exist, so we only 
return it. 
 

System.Management.Automation 

0 Comment's

Comment Form

Submit Comment