Programlama

Flash ile Realtime Birşeyler

11.01.2008

Sabah sabah Krokiller kardeşimin açtığı muhabbet üzerine yazıyorum bu yazıyı. Flash'da realtime multiplayer oyun nasıl yapılır? Evet bir çoğunuz bu sorunun cevabını merak ediyorsunuz! O zaman bu yazı tam size göre gençler taaam size göree. 

Şimdi efendim Flash'da sayfa yapanlarınız vardır elbet lakin hep dusunmussunuzdur "ulen bu sayfalar zıplıyor oynuyor ama bir dinamizm olsun bir coşku patlaması olsun ne bileyim". İşte bu hayallerin sonu ya bakırköy'e gider ya da "ulaaaan realtime oyun yapacam!" şeklinde bir düşünceye dönüşür. Flash'da kayda değer çok az uç konu varıdr. Bunlardan biri 3D olabilir (Flash'da Director gibi hazır bi 3D destegi olmadığını belirteyim) ve biri de mutlaka socket programlamadır. Bu işin en zor yanı, yalnızca flash içerisinden halledilememesidir. Ya kendiniz bir server yazmak zorundasınızdır veya hazır server'lardan birinin kurallarına uymak zorundasınızdır. Aslında Macromedia Firması bu işler için Macromedia Flash Communication Server programını çıkarmıştır ve gayt güzel çalışmaktadır ama ben her zaman kendi işimi kendim halletmek isterim :) - Tabii chat falan sorun değil ama video konferans gibi coşkulu işlerde kendi server'ını yazmak çüğünüzü kendi k.çınıza sokmak kadar zordur :) 

Şimdi size basit olarak bir C# yani dotnet Server ve buna bağlanan Client mantığını yazacağım. Öncelikle

Server'dan başlayalım :

Aşağıda açıklamaları ile beraber C# kodlarını okuyabilenzi

// Bunlar socket programming için çağırılıan gerekli sınıflar

using System;
using System.IO;
using System.Net.Sockets;
using System.Net;

// simpleServer diye bir isimuzayında saklanıyor

namespace simpleServer
{
 class Class1
 {

  // 2 oyunculu bir sistemin 1. ve 2. oyuncularının konumlarının başlangıç noktaları
  static int p1_x = 30;
  static int p1_y = 30;
  static int p2_x = 50;
  static int p2_y = 50;
 

konumarın listesini veren fonkiyon
  static string listeVer()
  {
   return p1_x.ToString() + ":" + p1_y.ToString() + ":" + p2_x.ToString() + ":" + p2_y.ToString();
  }

  [STAThread]
  static void Main(string[] args)
  {

   // Local ip adresi belirtiliyor ve TcpListener adındaki dinleyici 2800 numaralı portu dinlemeye alıyor.
   IPAddress ipAd = IPAddress.Parse("127.0.0.1");

   TcpListener TcpDinleyicisi = new TcpListener(ipAd,2800);
   TcpDinleyicisi.Start();

   // Sunucu ile ilgili Console'a bilgi gonderiliyor

   Console.WriteLine("Sunucu baslatildi...");

  // İlgili Port'dan gelen çağrı alındığı zaman ne yapılacağı

  Socket IstemciSoketi = TcpDinleyicisi.AcceptSocket();

   if (!IstemciSoketi.Connected)
   {
    Console.WriteLine("Sunucu baslatilamiyor...") ;
   }
   else
   {  
    // Mesaj sonlandirici (Flash icin Gerekli)
    char EOF = (char) 0x00;

    while(true)
    {    

     İlgili port'dan gelen giden veriyi kontrol etmek içinbi NetworkStream, StreamWriter ve StreamReader nesneleri yaratılıyor
     NetworkStream AgAkimi = new NetworkStream(IstemciSoketi);     
     StreamWriter AkimYazici = new StreamWriter(AgAkimi);
     StreamReader AkimOkuyucu = new StreamReader(AgAkimi);

     try
     {

      // Gelen bilgi işleniyor
      string IstemciString = AkimOkuyucu.ReadLine();     

      String[] plBilgi = IstemciString.Split(':');     
     
      if (plBilgi[0].Trim().Equals("1"))
      {
       p1_x = int.Parse(plBilgi[1]);
       p1_y = int.Parse(plBilgi[2]);
      }
      else
      {
       p2_x = int.Parse(plBilgi[1]);
       p2_y = int.Parse(plBilgi[2]);
      }

      String message = listeVer();
      Console.WriteLine(listeVer());
     

      // oyuncuların konumları WriteLine metodu ile client'a gönderiliyor
      AkimYazici.WriteLine(listeVer() + EOF);
      AkimYazici.Flush() ;
     }
        
     catch
     {

      // Konsola bilgi gönderiliyor
      Console.WriteLine("Sunucu kapatiliyor...");
      return ;
     }
    }
   }

   // Bitti ulan

   IstemciSoketi.Close();
   Console.WriteLine("Sunucu Kapatiliyor..."); 
  }
 }
}

işte gençler basit bir server bu şekilde kodlanabilir.Tabii bu server tek bir portdan bilgi alıp veriyor. Aslında bilginin bir portdan alınıp client'in boş olan diğer portlardan birine yönlendirilmesi lazım. Bir portdan aynı anda yalnızca bir client bağlı kalabilir (kalıcı bir bağlantıdan söz ediyoruz) Sağolsun Poison kardeşim bu konuda beni aydınlattı Öpüyorum yanaklarından :)

Neyse bir de flash kodunu yazalım da tam olsun :

Bunda açıklama falan yok uğraşın anasını satayım. Bir tek htırlatma ekranda mov1_mc, mov2_mc isimli iki tane movieclip olması br de log tutmak için log_txt isminde bir dynamictext olması lazım. Aşağıdaki kodları ilk frame'e yazdıktan sonra eğerki yukarıdaki server'ı yapmış ve çalıştırmışsanız flash da çalışacaktır. Ama yapamamışsanız e ben ne diyim size bilmiyorum ki?

var xs_xmlsocket = new XMLSocket();
var data_xml = new XML();

// Baglaninca yapilacak islemler
xs_xmlsocket.onConnect = function(success) {
 if (success) {
  log_txt.text = "Bağlantı Başarılı!";
 } else {
  log_txt.text = "Bağlantı Başarısız!";
 }
}

// Data alininca yapilacak islemler
xs_xmlsocket.onData = function(msg)
{
 log_txt.text = msg;
 var plYer = msg.split(":");
 mov1_mc._x = parseInt(plYer[0]);
 mov1_mc._y = parseInt(plYer[1]);
 mov2_mc._x = parseInt(plYer[2]);
 mov2_mc._y = parseInt(plYer[3]);
}

// Bagklanti kapandigi zamanki islemler
xs_xmlsocket.onClose = function(doc) {
 log_txt.text += "Server Bağlantısı Kesildi";
}

// Mesaj Gonderme Fonksiyonu
function sendMsg(a)
{
 xs_xmlsocket.send(a + "\n");
}

// Baglan
if (_root.plNumber == 1)
{
 xs_xmlsocket.connect("localhost", 2800)
} else {
 xs_xmlsocket.connect("localhost", 2900)
}


// ****************************************************************
// Hareket Kontrolü
mov1_mc._x = _root.pl_1.x;
mov1_mc._y = _root.pl_1.y;
mov2_mc._x = _root.pl_2.x;
mov2_mc._y = _root.pl_2.y;

_root.onEnterFrame = function () {
 if(Key.isDown(Key.DOWN))
 {
  eval("_root.pl_"+_root.plNumber).y += 1;
 }
 if(Key.isDown(Key.UP))
 {
  eval("_root.pl_"+_root.plNumber).y -= 1;
 }
 if(Key.isDown(Key.LEFT))
 {
  eval("_root.pl_"+_root.plNumber).x -= 1;
 }
 if(Key.isDown(Key.RIGHT))
 {
  eval("_root.pl_"+_root.plNumber).x += 1;
 }
 
 message = _root.plNumber + ":" + eval("_root.pl_"+_root.plNumber).x + ":" + eval("_root.pl_"+_root.plNumber).y; 
 sendMsg(message); 
}

stop();

Bunları da Oku, Sorucam

Yorum Yok

Yorum Yaz