İş, güç, aile derken uzun zamandır günlüğe birşeyler eklemediğimin ve hatta eklediğim yazının devamını da getiremediğimin farkındayım. Bu konuda özürlerimi lütfen kabul edin Peki artık daha sık mı yazılar ekleyeceğim ? Elimden geleni yapacağıma inanabilirsiniz. Ama ne yazık ki bunun için bir söz veremiyorum. Şimdi gelelim esas konuya.
Bu yazıda bir süredir uğraştığım Zengl motorunda sprite ekleyerek eklediğimiz spritein klavye tuşlarıyla yönlendirilmesini işleyeceğiz. Zor bir iş mi ? Hayır. Ama önemli bir iş. Spritelar oyunun içindeki figürlerdir diyebiliriz. Bu kapsamda yukarıdan seyredilerek oynan bir uçak oyununda komuta ettiğiniz uçaktan tutun, savaştığınız uçaklar, size hediye gelen paketler, hatta düşmanı yok etmek için gönderdiğiniz mermiler bile sayılabilir. { Not: Bu yazıda uçağa mermide eklemeyi düşünüyordum ama karışıklık artmasın diye onu Zengl #2.5 yazısında anlatacağım. }
Şimdi bir düşünün haritanızda farklı zamanlarda oluşturulmuş yukarıdan aşağıya inen kimi ödül kimi size zarar vermek isteyen patlayıcı malzemeler ağır ağır aşağıya doğru geliyor. Bununla kalmazmış gibi düşman uçaklarıda size roketlerini göndermiş durumda ve siz hem bunlardan kaçıp, kaçarken olabildiğince karşı tarafa zarar verip toplayabildiğiniz kadarda ödül toplayama çalışıyorsunuz. Evet yukarıdan bakınca eğlenceli shoot em up tarzı oyun diyebilirsiniz ama programlama kısmına baktığınızda bütün bu objeleri hareketlerini, birbiriyle olan etkileşimlerini kontrol etmeli (yok olma, çarpışma ya da puan kazanma gibi ) ve yazdığınız yazılım oyun olduğu için işlemciyide düşünmeniz gerekmektedir.
İşte spritelar bu konuda inanılmaz derece yardımcıdırlar. Çünkü siz tür olarak bir sprite yaratırsınız diyelim ki düşman uçağı. Ve bu türün prosedürlerine ne işlem yapması gerektiğini örnek olarak nerden nereye, ne hızla uçması ve ne kadar atış yapması gerektiği gibi bilgileri program kodunda belirtirsiniz ve sengine2d_AddSprite dedikçe size bir öncekinden bağımsız ama aynı karakterde uçaklar üretir. Hepsinin yapması gerektiği iş aynıda olsa aynı işi farklı zamanlarda yaparlar ve sizin bunu takip etmeniz gerekmez. Kontrol rutinlerini, işlemleri her tür için bir kez yazarsınız ve istediğiniz kadar eklersiniz.
Aşağıdaki örnekte kullanıcının kullanmış olduğu uçak sadece bulunmakta yakın zamanda ekleyecek olduğum diğer yazıda ise bu uçak çizgiler halinde karşı tarafa kurşun atabilecek hale gelecek
https://rapidshare.com/files/1599033160/zengl2.rar
program init1;{$IFDEF WINDOWS} {$R *.res} {$ENDIF} {$DEFINE STATIC}uses {$IFNDEF STATIC} zglHeader {$ELSE} zgl_main, zgl_screen, zgl_window, zgl_timers, zgl_keyboard, zgl_render_2d, zgl_fx, zgl_textures, zgl_textures_png, zgl_textures_jpg, zgl_sprite_2d, zgl_sengine_2d, zgl_primitives_2d, zgl_font, zgl_text, zgl_math_2d, zgl_utils, zgl_camera_2d {$ENDIF} ;
var DirApp : String; DirHome : String; fnt : zglPFont; fullScreen : Boolean; dirRes : String {$IFNDEF DARWIN} = '../data/' {$ENDIF}; logo : zglPTexture; screen : zglPTexture; back : zglPTexture; bulut : zglPTexture; f14 : zglPTexture; time : Integer; camMain : zglTCamera2D; sengine2d : zglTSEngine2D;
procedure f14_init ( const Sprite : zglPSprite2D ); // Sprite'ın açılış procedürü begin
Sprite.X :=400; Sprite.Y :=500+camMain.Y +10;
end; procedure f14_Draw( const Sprite : zglPSprite2D ); // Ekrana çizim esnasında işletilen procedür begin
with Sprite^ do ssprite2d_Draw( f14,Sprite.X,camMain.Y +Sprite.Y, 78, 100,0 );
end;
procedure f14_proc( const Sprite : zglPSprite2D ); // Sprite'ın işlem procedürü var i :integer; left:Boolean; up:Boolean; right:Boolean; down:Boolean;
begin // açılış pozisyonları left :=false; up :=false; right :=false; down :=false;
// basılan tuşların algılanması ve uçağın çerçeveye hapis edilmesi if key_Down( K_RIGHT ) Then if Sprite.X < 720 then right:=true else right:=false; if key_Down( K_LEFT ) Then if Sprite.X > 20 then left:=true else left:=false ; if key_Down( K_UP ) Then if Sprite.y > 20 then up:=true else up:=false; if key_Down( K_DOWN ) Then if Sprite.y < 520 then down:=true else down:=false;
// basımı bitmiş tuşların algılanması if key_Up( K_RIGHT ) Then right:=false; if key_Up( K_LEFT ) Then left:=false; if key_Up( K_UP ) Then up:=false; if key_Up( K_DOWN ) Then down:=false;
// Sonuca göre Sprite'ın hareketi if right then Sprite.X := Sprite.X +2; if left then Sprite.X := Sprite.X -2; if up then Sprite.y := Sprite.y -2; if down then Sprite.y := Sprite.y +2;
//Programdan çıkış if key_Press( K_ESCAPE ) Then zgl_Exit();
key_ClearState();
end; procedure f14_free( const Sprite : zglPSprite2D ); begin
end;
procedure Init; begin camMain.Zoom.X := 1; camMain.Zoom.Y := 1; // Program açılırken ilk çalışan procedur. fnt := font_LoadFromFile( dirres + 'font.zfi' ); logo := tex_LoadFromFile( dirres + 'boreas.png', $FF000000, TEX_DEFAULT_2D ); screen := tex_LoadFromFile( dirres + 'screen.png', $FF000000, TEX_DEFAULT_2D ); back := tex_LoadFromFile( dirres + 'back.png', $FF000000, TEX_DEFAULT_2D ); bulut := tex_LoadFromFile( dirres + 'bulut.png', $FF000000, TEX_DEFAULT_2D ); f14 := tex_LoadFromFile( dirres + 'f14.png', $FF000000, TEX_DEFAULT_2D ); // Uçak resminin yüklenmesi sengine2d_Set( @sengine2d ); // Sprite motorunun set edilmesi sengine2d_AddSprite( f14,1, @f14_Init, @f14_Draw, @f14_Proc, @f14_Free ); // Sprite'ın eklenmesi
end;
procedure Draw; begin // Programın ana çizim procedürü
// Oyunun açılış ekranının ve diğer fonların ayarlandığı bölüm
batch2d_Begin(); cam2d_Set( @camMain ); if time <= 255 Then ssprite2d_Draw( logo, 0, 0, 800, 600, 0, time ) // Dahili zamanlayıcıyı kullanarak ekranda logo // açılış resmi gibi sunumlar yapabiliriz. else if (time < 510) Then begin ssprite2d_Draw( logo,0, 0, 800, 600, 0, 510 - time ); end;
if (time > 550) and (time <= 805) Then ssprite2d_Draw( screen, 0, 0, 800, 600, 0,time - 550 ) else if (time > 805) and (time<=1010) Then begin ssprite2d_Draw( screen,0, 0, 800, 600, 0, 1010 - time ); end; if time > 1020 then begin
ssprite2d_Draw( back,0, -1800, 800, 2400, 0,255 ); ssprite2d_Draw( bulut,0, -1800, 800, 2400, 0,100 );
sengine2d_Draw(); camMain.Y:=camMain.Y-0.02;
end; batch2d_End(); end;
procedure Update( dt : Double ); begin // Bu bölüm herhangi birşeyin yumuşak hareket etmesi için en iyi yöntemdir. Zamanlayıcılar FPS ile sınırlıdır.
end;
procedure Timer; begin INC(time,2); sengine2d_Proc(); // Zamanlayıcının işletildiği bölüm wnd_SetCaption( '01 - Initialization[ FPS: ' + u_IntToStr( zgl_Get( RENDER_FPS ) ) + ' ]' ); // Pencerenin başlığı if key_Down( K_ALT ) and key_Press( K_ENTER ) Then begin FullScreen := not FullScreen; scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FullScreen, FALSE ); end; // EN: If Escape was pressed - shutdown the application. if key_Press( K_ESCAPE ) Then zgl_Exit(); key_ClearState(); end;
procedure Quit; begin // Çıkarken işletilecek komutlar end;
Begin {$IFNDEF STATIC} {$IFDEF LINUX} zglLoad( libZenGL ); {$ENDIF} {$IFDEF WIN32} zglLoad( libZenGL ); {$ENDIF} {$IFDEF DARWIN} zglLoad( libZenGL ); {$ENDIF} {$ENDIF} // EN: For loading/creating your own options/profiles/etc. you can get path to user home // directory, or to executable file(not works for GNU/Linux). // Kullanıcıyla ilgili kayıtlar tutmak için faydası olabilir DirApp := utf8_Copy( PChar( zgl_Get( DIRECTORY_APPLICATION ) ) ); // Uygulamanın adresi DirHome := utf8_Copy( PChar( zgl_Get( DIRECTORY_HOME ) ) ); // Ev klasörü.
// EN: Create a timer with interval 1000ms. // Uygulamaya 1000ms interval tanımlı bir zamanlayıcı ekleniyor. timer_Add( @Timer, 16 );
// EN: Register the procedure, that will be executed after ZenGL initialization. // Yukarıda tanımlanan procedurlerin çalışması için (init,draw, timer .. ) register procedurü ile tanıtılması gerekir. // Initialization procedürünün tanıtılması zgl_Reg( SYS_LOAD, @Init ); // Render procedürünün tanıtılması zgl_Reg( SYS_DRAW, @Draw ); // Update procedürünün tanıtılması zgl_Reg( SYS_UPDATE, @Update ); // Çıkış procedürünün tanıtılması zgl_Reg( SYS_EXIT, @Quit ); // Açılacak pencerenin başlığı tanımlanıyor. wnd_SetCaption( '01 - Initialization' ); // Cursor gözükmesine izin veriliyor wnd_ShowCursor( FALSE );
// Ekranın boyutları tanımlanıyor scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE ); // ZenGL başlatılıyor. zgl_Init(); End.