Многопользовательский платформинг TCP и UDP с запахом Mango
Сегодняшний проект демонстрирует, как можно использовать преимущества новой поддержки сокетов TCP/UDP, появившейся в выпуске Windows Phone Mango. Вы полагаете, что брать существующие игры и встраивать поддержку многих пользователей может оказаться сложным делом, или что поддержка сокетов совсем не для вас, но это сообщение показывает, что это не так и не стоит бояться…
Одноранговые многопользовательские игры для Windows Phone, использующие сокеты в XNA
Одной из новых возможностей платформы разработки в Windows Phone Mango стали сокеты TCP и UDP. В этом сообщении я расскажу об их использовании для расширения существующих игр путем добавления множества одноранговых игроков через WiFi, используя UdpAnySourceMulticastClient. Телефоны с запущенной игрой в одной и той же WiFi-сети автоматически распознают друг друга и игроки появляются на экране.
Игра взята из другого примера, Windows Phone 7 Platformer Starter Kit из блога Дэвида Руссета.
Изменения заключаются в добавлении кода для запуска широковещательных сокетов UDP и в разрешении многих игроков.
Исходный код полного проекта прикреплен в zip-файле ниже.
PlatformerGame . cs: Этот файл содержит код игры и инициализацию сокетов, управление приемом и передачей.
UdpAnySourceMulticastChannel . cs: Этот файл содержит код широковещательных сокетов UDP для присоединения к группе, отсылки и приема данных.
OtherPlayer . cs: Это модификация файла Player.cs ддля подключения других игроков в игру.
...
Надеюсь, это поможет показать простой способ коммуникаций телефона с телефоном и продемонстрирует мощь сокетов. Удачной разработки!
Вот пара фрагментов кода для возбуждения аппетита:
public void Open()
{
if (!IsJoined)
{
this.Client.BeginJoinGroup(
result =>
{
try
{
this.Client.EndJoinGroup(result);
IsJoined = true;
this.OnAfterOpen();
this.Receive();
}
catch
{ }
}, null);
}
}
private void Receive()
{
if (IsJoined)
{
Array.Clear(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length);
this.Client.BeginReceiveFromGroup(this.ReceiveBuffer, 0,
this.ReceiveBuffer.Length,
result =>
{
if (!IsDisposed)
{
IPEndPoint source;
try
{
this.Client.EndReceiveFromGroup(result, out source);
this.OnReceive(source, this.ReceiveBuffer);
this.Receive();
}
catch
{
IsJoined = false;
this.Open();
}
}
}, null);
}
}
void Channel_PacketReceived(object sender, UdpPacketReceivedEventArgs e)
{
string data = e.Message;
Console.WriteLine(data);
string[] pos = data.Split(',');
//Discard packets that do not match
if (pos.Length != 5)
{
return;
}
try
{
if (pos[0] != identifier.ToString())
//if not originated from this phone
{
if (pos[1].Contains("ReachedExit"))
{
level.TimeRemaining = TimeSpan.Zero;
}
else
{
Vector2 position = new Vector2(float.Parse(pos[1]), float.Parse(pos[2]));
Vector2 velocity = new Vector2(float.Parse(pos[3]), float.Parse(pos[4]));
level.UpdateOtherPlayer(int.Parse(pos[0]), position, velocity);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Caught unexpected exception: " + ex.Message);
}
}
Добавление поддержки сокетов UDP/TCP в приложение или игру не должно быть трудным и ужасным, это просто, как отправить и получить...
Вот несколько ссылок, которые могут оказаться интересными:
- Соединяя управление состояниями игры и средства Platformer XNA
- Поднимая дух Mango-разработки с помощью двух обучающих ресурсов
- Скачать веб-установщик бета-версии инструментов разработки для Mango
- ISO-образ инструментов разработки для Mango
- Примеры кода для Windows Phone
- Новые API Silverlight для Windows Phone OS 7.1
- App Hub