Interface Trạng Thái
Mỗi lớp trạng thái cần implement interface State như GameConnectStart, GameConnectIng, GameConnectERROR,... Triển khai các phương thức của interface và lưu trữ từng trạng thái trong GameStateMachine để tiện quản lý.
public interface ITrangThai // Định nghĩa interface trạng thái
{
void KhoiTao(); // Phương thức khởi tạo
int LayIdTrangThaiHienTai(); // Trả về ID của trạng thái hiện tại
void SuKienVao(ITrangThai trangThai); // Sự kiện khi vào trạng thái
void SuKienRa(ITrangThai trangThai); // Sự kiện khi rời trạng thái
}
Interface Máy Trạng Thái
Địn nghĩa interface cho máy trạng thái với các phương thức cần thiết.
public interface IMayTrangThai<T> // Định nghĩa interface máy trạng thái
{
T LayTrangThaiHienTai(); // Trả về trạng thái hiện tại
T LayTrangThaiTruocDo(); // Trả về trạng thái trước đó
void DangKy(T t); // Đăng ký trạng thái
void XoaTrangThai(T t); // Xóa trạng thái
ChuyenTrangThai(T t); // Chuyển đổi trạng thái
}
Máy Trạng Thái Game
public class MayTrangThaiGame : IMayTrangThai<ITrangThai>
{
public ITrangThai TrangThaiHienTai = null; // Trạng thái hiện tại
public ITrangThai TrangThaiTruocDo = null; // Trạng thái trước đó
private Dictionary _danhSachTrangThai; // Lưu trữ các trạng thái
public MayTrangThaiGame()
{
_danhSachTrangThai = new Dictionary();
}
public ITrangThai LayTrangThaiHienTai()
{
return TrangThaiHienTai; // Trả về trạng thái hiện tại
}
public ITrangThai LayTrangThaiTruocDo()
{
return TrangThaiTruocDo; // Trả về trạng thái trước đó
}
public void DangKy(ITrangThai t)
{
if (_danhSachTrangThai.ContainsKey(t.LayIdTrangThaiHienTai())) // Kiểm tra trạng thái đã được đăng ký chưa
return;
_danhSachTrangThai.Add(t.LayIdTrangThaiHienTai(), t); // Thêm trạng thái vào danh sách
}
public void XoaTrangThai(ITrangThai t)
{
if (!_danhSachTrangThai.ContainsKey(t.LayIdTrangThaiHienTai())) // Kiểm tra trạng thái đã được đăng ký chưa
return;
_danhSachTrangThai.Remove(t.LayIdTrangThaiHienTai()); // Xóa trạng thái khỏi danh sách
}
public void ChuyenTrangThai(ITrangThai t)
{
if (!_danhSachTrangThai.ContainsKey(t.LayIdTrangThaiHienTai())) // Kiểm tra trạng thái đã được đăng ký chưa
return;
if (TrangThaiHienTai !=null) // Kiểm tra có phải lần đầu tiên chuyển trạng thái không
{
if (TrangThaiHienTai.LayIdTrangThaiHienTai() == t.LayIdTrangThaiHienTai()) // Kiểm tra trạng thái mới có giống trạng thái hiện tại không
return;
TrangThaiHienTai.SuKienRa(t); // Thực hiện sự kiện khi rời trạng thái hiện tại
TrangThaiTruocDo = TrangThaiHienTai; // Gán trạng thái hiện tại làm trạng thái trước đó
}
t.KhoiTao(); // Thực hiện khởi tạo trạng thái mới
TrangThaiHienTai = t; // Gán trạng thái mới là trạng thái hiện tại
TrangThaiHienTai.SuKienVao(t); // Thực hiện sự kiện khi vào trạng thái mới
}
public void ChuyenTrangThai(int id)
{
if (!_danhSachTrangThai.ContainsKey(id)) // Kiểm tra trạng thái đã được đăng ký chưa
return;
ITrangThai t = _danhSachTrangThai[id]; // Tìm trạng thái theo ID
if (TrangThaiHienTai != null)
{
if (TrangThaiHienTai.LayIdTrangThaiHienTai() == id)
return;
TrangThaiHienTai.SuKienRa(t);
TrangThaiTruocDo = TrangThaiHienTai;
}
t.KhoiTao(); // Thực hiện khởi tạo trạng thái mới
TrangThaiHienTai = t;
TrangThaiHienTai.SuKienVao(t);
}
}
Enum Trạng Thái Game
public enum TrangThaiGame
{
TRANG_THAI_KET_NOI,// Bắt đầu
TRANG_THAI_DANG_KET_NOI,
TRANG_THAI_KET_NOI_THAT_BAI,
TRANG_THAI_KET_THUC,
}
Trạng Thái Bắt Đầu Kết Nối
public class TrangThaiBatDauKetNoi : ITrangThai
{
public void SuKienVao(ITrangThai trangThai)
{
Console.WriteLine("Đã vào trạng thái Bắt đầu");
}
public int LayIdTrangThaiHienTai()
{
return (int)TrangThaiGame.TRANG_THAI_KET_NOI;
}
public void KhoiTao()
{
Console.WriteLine("Khởi tạo trạng thái Bắt đầu");
}
public void SuKienRa(ITrangThai trangThai)
{
Console.WriteLine("Thoát trạng thái Bắt đầu, chuyển sang trạng thái " + (TrangThaiGame)trangThai.LayIdTrangThaiHienTai());
}
}
Trạng Thái Đang Kết Nối
public class TrangThaiDangKetNoi : ITrangThai
{
public void SuKienVao(ITrangThai trangThai)
{
Console.WriteLine("Đã vào trạng thái Đang kết nối");
}
public int LayIdTrangThaiHienTai()
{
return (int)TrangThaiGame.TRANG_THAI_DANG_KET_NOI;
}
public void KhoiTao()
{
Console.WriteLine("Khởi tạo trạng thái Đang kết nối");
}
public void SuKienRa(ITrangThai trangThai)
{
Console.WriteLine("Thoát trạng thái Đang kết nối, chuyển sang trạng thái " + (TrangThaiGame)trangThai.LayIdTrangThaiHienTai());
}
}
Trạng Thái Kết Nối Thất Bại
public class TrangThaiKetNoiThatBai : ITrangThai
{
public void SuKienVao(ITrangThai trangThai)
{
Console.WriteLine("Đã vào trạng thái Kết nối thất bại, chuẩn bị chuyển sang trạng thái Kết thúc");
QuanLyDonThe.Instance.ChuyenTrangThai(TrangThaiGame.TRANG_THAI_KET_THUC); // Chuyển sang trạng thái kết thúc
}
public int LayIdTrangThaiHienTai()
{
return (int)TrangThaiGame.TRANG_THAI_KET_NOI_THAT_BAI;
}
public void KhoiTao()
{
Console.WriteLine("Khởi tạo trạng thái Kết nối thất bại, báo lỗi");
}
public void SuKienRa(ITrangThai trangThai)
{
Console.WriteLine("Thoát trạng thái Kết nối thất bại, chuyển sang trạng thái " + (TrangThaiGame)trangThai.LayIdTrangThaiHienTai());
}
}
Trạng Thái Kết Thúc
public class TrangThaiKetThuc : ITrangThai
{
public void SuKienVao(ITrangThai trangThai)
{
Console.WriteLine("Đã vào trạng thái Kết thúc");
}
public int LayIdTrangThaiHienTai()
{
return (int)TrangThaiGame.TRANG_THAI_KET_THUC;
}
public void KhoiTao()
{
Console.WriteLine("Khởi tạo trạng thái Kết thúc");
}
public void SuKienRa(ITrangThai trangThai)
{
Console.WriteLine("Thoát trạng thái Kết thúc, chuyển sang trạng thái " + (TrangThaiGame)trangThai.LayIdTrangThaiHienTai() + "/n");
}
}
Tạo Đối Tượng Đơn L Để Quản Lý Máy Trạng Thái
(Có thể triển khai theo nhiều cách khác nhau, tùy theo nhu cầu dự án)
QuanLyDonThe (Đơn Thể)
public class QuanLyDonThe
{
static QuanLyDonThe _instance;
private MayTrangThaiGame _mayTrangThaiGame = new MayTrangThaiGame(); // Máy trạng thái
// Bốn trạng thái
private TrangThaiBatDauKetNoi _trangThaiBatDau = new TrangThaiBatDauKetNoi();
private TrangThaiDangKetNoi _trangThaiDangKetNoi = new TrangThaiDangKetNoi();
private TrangThaiKetNoiThatBai _trangThaiThatBai = new TrangThaiKetNoiThatBai();
private TrangThaiKetThuc _trangThaiKetThuc = new TrangThaiKetThuc();
// Đơn thể
public static QuanLyDonThe Instance
{
get
{
if (_instance == null)
{
_instance = new QuanLyDonThe();
}
return _instance;
}
}
/// <summary>
/// Đăng ký trạng thái
/// </summary>
public void KhoiTao()
{
_mayTrangThaiGame.DangKy(_trangThaiBatDau);
_mayTrangThaiGame.DangKy(_trangThaiDangKetNoi);
_mayTrangThaiGame.DangKy(_trangThaiThatBai);
_mayTrangThaiGame.DangKy(_trangThaiKetThuc);
}
/// <summary>
/// Chuyển đổi trạng thái
/// </summary>
/// <param name="state"> Loại trạng thái </param>
public void ChuyenTrangThai(TrangThaiGame state)
{
_mayTrangThaiGame.ChuyenTrangThai((int)state);
}
}
Chạy Trong Chương Trình Chính
static void Main(string[] args)
{
QuanLyDonThe.Instance.KhoiTao(); // Đăng ký trạng thái
QuanLyDonThe.Instance.ChuyenTrangThai(0);
QuanLyDonThe.Instance.ChuyenTrangThai((TrangThaiGame)1);
QuanLyDonThe.Instance.ChuyenTrangThai((TrangThaiGame)2);
Console.ReadKey();
}