Bu yazida
anlatacagim oyun, bazilarinin DXBall, bazilarinin
Alleyway… diye bildigi bir çok ismi olan bir oyun.
Oyunun tüm dosyalari
burada verilmeyecktir ancak .NET ile yeni bir proje açilip .cs dosyalari
kopyalanirsa, oyun çalisacaktir. Ayrica oyunda kullanilan top,blok sekilleri
için gerekli olan resimleri de istediginiz gibi seçebilirsiniz. Top resminin
dosya adi tp.bmp, bloklarin dosya adi brick.bmp, alttaki cubuk resminin dosya
adi ise blk.bmp olmak zorundadir.dir. Oyunu normal haliyle çalistirmak
istiyorsaniz download edebilirsiniz. (Bilgisayarda .NET ve Framework 1.1 kurulu
olmak zorunda! )
Programi
derleyip çalistirdiginizda oyunun ekran görüntüsünün asagidaki gibi oldugunu
göreceksiniz.
Oyunun kaynak kodunu indirmek için tiklayin.
Önemli:
Siniflarin neler oldugunu uzun uzun paragraflar
halinde anlatmaktansa kodun yaninda komut satirlariyla
anlatilacaktir.
Simdi
adim adim oyunu açiklayalim;
- Ilk olarak Top.cs
dosyamiz var. top sinifimizda, en önemli metot olan move metodunda topun
koordinatlarina bakilir ve koordinatlara göre ne tarafa hareket ettirilecegi
belirlenir.
Top.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
public
class Top
{
public
Point pos; //topun koordinatlarini tutmaya yarayacak.
private
Bitmap tp=null; //topun resmi için gerekli.
public
int Xhareket=4; //topun xde hareket hizini burada belirleyecegiz.
public
int Yhareket=4; //topun yde hareket hizini burada belirleyecegiz.
public
Top(int x,int y)
{
pos.X =
x; //ana formdan gelen topun nerede baslatilacagi
bilgisi
pos.Y =
y; // burada x ve y koordinatlari olarak girilir.
if
(tp==null) //eger resim yüklenmediyse yükleme islemi yapilacak.
{
tp
= new Bitmap("tp.bmp");
}
}
public
Rectangle GetFrame()
{
Rectangle
myRect = new Rectangle(pos.X, pos.Y, tp.Width, tp.Height);
return
myRect; //top nesnemizin konumunu dikdörtgen olarak belirlememize yarar.
} //
bu sayede top ile bloklarin çarpisip çarpismadigini
daha kolay
//anlayacagiz.
public
void Draw(Graphics g)
{
g.DrawImage
(tp,pos.X,pos.Y,tp.Width ,tp.Height ); //top nesnesi ekrana
//çizdirilir.
X,y koordinatlarindan sonra ebatlari parametre olarak
girilir.
}
public
void Remove(Top t)
{
Yhareket=-Yhareket;
pos.X +=
Xhareket;
pos.Y +=
Yhareket;
}
public
void Move(int hak,Grup grp,Top t,Rectangle r, Rectangle rblok)
{
//topun
pencere icinde duvarlara ve cubuga carptikça simetrik olarak
sekmesini
//burada
saglayacagiz.
if(t.GetFrame().IntersectsWith(rblok))
//eger top bloka çarptiysa,
{
Yhareket=-Yhareket;
// topun y yönünü ters cevir
}
// böylelikle sekmeyi sagla.
//top
ekrandaysa,
if(pos.X
> 539 || pos.X < 0)
{
//topun
x hareketini ters cevir
Xhareket
= -Xhareket;
}
//
top yukari carparsa
if(pos.Y
< 0)
{
//y
hareketini degistir
Yhareket
= -Yhareket;
}//
yanarsa,
else
if(pos.Y > 500)
{
//top
durur
Xhareket
= 0;
Yhareket
= 0;
//hakki
1 azalt
hak -=
1;
}
//
top koordinatlarini degistir
pos.X +=
Xhareket;
pos.Y +=
Yhareket;
}
}
}
- Blok.cs sinifi ise alt
taraftaki yönlendirecegimiz cubuktur.
Blok.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
public
class Blok
{
public
Point pos; //x ve y koordinatlarini belirlemek için kullanilacak.
static
Bitmap Cubuk = null; //Çubuk resmi için kullanilacak.
int inc =
6; //çubugun sürükleme hizini belirleyecek
int
LastposX = 0; //su anda son pozisyon olmadigindan ikisi
de sifirlanir.
int
LastposY = 0;
public
Blok(int x, int y)
{
pos.X =
x; //x konumu verilir.
pos.Y =
y; /y konumu verilir.
if
(Cubuk == null) //çubuk ekranda yoksa,
{
Cubuk =
new Bitmap("blk.bmp"); //çubuk ekrana çizdirilir.
}
}
public
Rectangle GetFrame()
{
Rectangle
myRect = new Rectangle(pos.X, pos.Y, Cubuk.Width, Cubuk.Height); //top sinifindaki
islevi görür.
return
myRect;
}
public
void Draw(Graphics g)
{
Rectangle
destR = new Rectangle(pos.X, pos.Y, Cubuk.Width, Cubuk.Height); //çubuk
hareketlerinde kullanilacak.
Rectangle
srcR = new Rectangle(0,0, Cubuk.Width, Cubuk.Height);
g.DrawImage(Cubuk,
destR, srcR, GraphicsUnit.Pixel);
LastposX
= pos.X;
LastposY
= pos.Y;
}
public
void MoveLeft(Rectangle r)
{
if
(pos.X <= 0) //eger pencerenin en solundaysa hareket etmeyecek,
degilse sola dogru hareketine devam edecektir.
return;
pos.X -=
inc;
}
public
void MoveRight(Rectangle r)
{ //eger
pencerenin en sagindaysa hareket etmeyecek, degilse saga
dogru hareketine devam edecektir.
if
(pos.X >= r.Width - Cubuk.Width)
return;
pos.X +=
inc;
}
}
}
- Brick.cs sinifi ise
patlatilacak bloklari temsil eder. Burada sadece basit özellikleri tutlur.
Bloklari kontrol eden Grup sinifinda tüm bloklari ayni anda kontrol
edildigini göreceksiniz. Grup sinifinda tüm bloklari tutan bir matris
bulunmaktadir.
Brick.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
public
class Brick
{
public
int yukseklik,genislik,basx,basy; //bloklarin özellikleri burada tutulur.
public
bool vuruldu=false; //top tarafindan vurulup vurulmadigi
buradan anlasilacaktir.
public
Brick(int yuk,int gen,int startx,int starty)
{
this.yukseklik=yuk;
this.genislik=gen;
this.basx=startx;
this.basy=starty;
this.vuruldu=false;
//yeni yaratildigi için vurulmadi oalarak isaretlenir.
}
}
}
- Grup.cs sinifinda ise
blok kontrolü yapilir.
Grup.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
public
class Grup
{
Bitmap
br=null;
public
Brick[,] yapi; //brick sinifinda nesneleri tutan matrisimiz
burada yaratiliyor.
int
sut=5; //bloklarin sütun ve satir sayilari bu kisimda
girilir.
int
sat=8;
public
Grup()
{
reset();
//vurulmus duurmda olan bloklar varsa bunlari da vurulmadi
olarak isaretleyen ve ilk haline döndüren metod çagrilir.
}
public
void Draw(Graphics g)
{
for
(int i=0;i
{
// bu iç içe for döngüleri bölümünde
bloklar tek tek dolasilarak
for
(int j=0;j
{
// vurulmayanlar ise ayni sekilde ekrana çizdirilir.
if
(yapi[i,j].vuruldu==false)
{
Brick
temp= (Brick) yapi[i,j];
g.DrawImage(br,temp.basx,temp.basy,br.Width,br.Height);
}
}
}
}
public
void reset(){ //tüm bloklar tekrar olusturulur.
yapi =
new Brick[sat,sut];
if
(br==null)
{
br
= new Bitmap("Brick.bmp");
}
for
(int i=0;i
{
for
(int j=0;j
{
yapi[i,j]=new
Brick(br.Height,br.Width,(i) * 65 +20, (j * 35) + 50);
yapi[i,j].vuruldu=false;
}
}
}
}
}
- Form1.cs,oyunun ana
formudur yani ekranimizdir. Bu formda esas önemli olan yerler
açiklanacaktir.
Form1.cs:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.InteropServices;
namespace alleyway
{
public
class Form1 : System.Windows.Forms.Form
{
public
int Hak=3; //kaç hakkimiz oldugunu belirleriz.
int
puan=0; //puan baslangiçta sifirdir.
private
bool flag = true;
private
Blok blok = new Blok(275, 490); //alttaki çubugun yeri belirlenir.
private
Top top = new Top(250, 300); // topun konumu belirlenir.
private
Grup grup=new Grup();
private
System.Windows.Forms.Timer timer1;
private
System.ComponentModel.IContainer components;
public
Form1()
{
InitializeComponent();
timer1.Start();
//top hareketleri ve ekran degisimleri bu timer sayesinde belirlenir.
Her 50 salisede ekran tekrar
//çizdirilir.
SetStyle(ControlStyles.UserPaint,
true);
SetStyle(ControlStyles.AllPaintingInWmPaint,
true);
SetStyle(ControlStyles.DoubleBuffer,
true);
}
protected
override void Dispose( bool disposing ) //bu kodlari .net kendisi yaratir.
{
if(
disposing )
{
if
(components != null)
{
components.Dispose();
}
}
base.Dispose(
disposing );
}
#region
Windows Form Designer generated code
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.components
= new System.ComponentModel.Container();
this.timer1
= new System.Windows.Forms.Timer(this.components);
//
timer1 öezlliklerini burada tanimlariz.
this.timer1.Enabled
= true;
this.timer1.Interval
= 50;
this.timer1.Tick
+= new System.EventHandler(this.timer1_Tick);
//
Form1 için yapilan degisiklier buradadir.
this.AutoScaleBaseSize
= new System.Drawing.Size(6, 16);
this.ClientSize
= new System.Drawing.Size(550, 500);
this.Font
= new System.Drawing.Font("Comic Sans MS", 8.25F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.KeyPreview
= true;
this.Location
= new System.Drawing.Point(150, 200);
this.MaximizeBox
= false;
this.Name
= "Form1";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text
= "PatLat";
this.KeyDown
+= new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
this.Load
+= new System.EventHandler(this.Form1_Load);
this.Paint
+= new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
}
#endregion
[STAThread]
static
void Main()
{
Application.Run(new
Form1());
}
private
void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics
g = e.Graphics;
g.FillRectangle(Brushes.Black,
0, 0, this.ClientRectangle.Width, ClientRectangle.Height);
blok.Draw(g);
//oyunumuzdaki tüm nesneler ekrana çizdirilir.
top.Draw
(g);
grup.Draw(g);
}
private
void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{ //bu
kisimda tusa basilinca çubugun hareket ettirilmesi
gerçeklestirilmistir. Case yapisi içinde sag saol
hareketleri
//yapilir.
string
result = e.KeyData.ToString();
Invalidate(blok.GetFrame());
switch
(result)
{
case
"Left": //sol tusuna basildiysa sola git
blok.MoveLeft(ClientRectangle);
Invalidate(blok.GetFrame());
//tekrar blogu çizdir.
break;
case
"Right": //sag tusuna basildiysa saga git
blok.MoveRight(ClientRectangle);
Invalidate(blok.GetFrame());//tekrar
blogu çizdir.
break;
default:
break;
}
}
private
void timer1_Tick(object sender, System.EventArgs e)
{ //timer
in her tikinde top ve bloklar kesisti mi? kontrolü yapilir
ve kesisme varsa o blok vuruldugu için ekrandan silinir.
flag=true;
for
(int i=0;i<8;i++)
{
for
(int j=0;j<5 ;j++)
{
Rectangle
r_brick = new Rectangle(grup.yapi[i,j].basx,grup.yapi[i,j].basy,grup.yapi[i,j].genislik,grup.yapi[i,j].yukseklik);
if(top.GetFrame().IntersectsWith(r_brick))
{
if
(grup.yapi[i,j].vuruldu==false)
{
grup.yapi[i,j].vuruldu=true;
top.Remove(top); //ekrandan
topun silinmesi.
puan=puan+10;
//blok vuruldu, puani arttir.
flag=false;//yanmadigimizi
belirtmek için flag false yapilir
}
}
}
}
if
(flag) //flag true ise yandi demektir.
{
top.Move
(Hak,this.grup,this.top,ClientRectangle, blok.GetFrame ());
if
(top.pos.Y>500)
{
timer1.Stop();
//hareketi durdur.
Hak--;
//hakki 1 azalt
if
(Hak==0) //eger hak sifir ise,
{
Form3
form3=new Form3(puan); //oyun bitti ekranini göster.
form3.ShowDialog(this);
if
(form3.DialogResult==DialogResult.OK) // O ekranda tekrar oynaya basilirsa,
{
Hak=3;
//hakki 3e çikar,
puan=0;
//puani sifirla ve tekrar baslat.
top.pos.X=265;
top.pos.Y=300;
blok.pos.X=275;
blok.pos.Y=490;
grup.reset();
top.Xhareket=-top.Xhareket;
Invalidate();
timer1.Start();
}
}
else
//hak sifir olmadiysa,
{
Form2
form2=new Form2(Hak); //kaç hakki oldugunu, puanini
göster,oyuna devam et
form2.ShowDialog(this);
top.pos.X=250;
top.pos.Y=250;
blok.pos.X=275;
blok.pos.Y=490;
top.Xhareket=-top.Xhareket;
Invalidate();
timer1.Start();
}
}
}
flag=true;
Invalidate();
}
}
}
- Simdi kodunu göreceginiz
iki form ise oyun bitince ve yaninca gösterilen formlar oldugundan
açiklanacak bir bölüm içermemektedirler.
- Oyun Bitince gösterilen
form:
Form3.cs:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace
alleyway
{
///
///
Summary description for Form3.
///
public
class Form3 : System.Windows.Forms.Form
{
int
ppuan;
private
System.Windows.Forms.Label label1;
private
System.Windows.Forms.Label label2;
private
System.Windows.Forms.Button button2;
private
System.Windows.Forms.Label label3;
private
System.Windows.Forms.Button OK;
///
///
Required designer variable.
///
private
System.ComponentModel.Container components = null;
public
Form3(int puan)
{
//
//
Required for Windows Form Designer support
//
ppuan=puan;
InitializeComponent();
//
//
TODO: Add any constructor code after InitializeComponent call
//
}
///
///
Clean up any resources being used.
///
protected
override void Dispose( bool disposing )
{
if(
disposing )
{
if(components
!= null)
{
components.Dispose();
}
}
base.Dispose(
disposing );
}
#region
Windows Form Designer generated code
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.label1
= new System.Windows.Forms.Label();
this.label2
= new System.Windows.Forms.Label();
this.OK =
new System.Windows.Forms.Button();
this.button2
= new System.Windows.Forms.Button();
this.label3
= new System.Windows.Forms.Label();
this.SuspendLayout();
//
//
label1
//
this.label1.Font
= new System.Drawing.Font("Bookman Old Style", 15.75F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label1.Location
= new System.Drawing.Point(48, 8);
this.label1.Name
= "label1";
this.label1.Size
= new System.Drawing.Size(144, 32);
this.label1.TabIndex
= 0;
this.label1.Text
= "Oyun Bitti!..";
//
//
label2
//
this.label2.Font
= new System.Drawing.Font("Bookman Old Style", 15.75F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location
= new System.Drawing.Point(8, 48);
this.label2.Name
= "label2";
this.label2.Size
= new System.Drawing.Size(112, 24);
this.label2.TabIndex
= 1;
this.label2.Text
= "Puaniniz:";
//
//
OK
//
this.OK.DialogResult =
System.Windows.Forms.DialogResult.OK;
this.OK.Location
= new System.Drawing.Point(24, 88);
this.OK.Name
= "OK";
this.OK.TabIndex
= 2;
this.OK.Text
= "Baslat";
this.OK.Click
+= new System.EventHandler(this.button1_Click);
//
//
button2
//
this.button2.Location
= new System.Drawing.Point(136, 88);
this.button2.Name
= "button2";
this.button2.TabIndex
= 3;
this.button2.Text
= "Yeter";
this.button2.Click
+= new System.EventHandler(this.button2_Click);
//
//
label3
//
this.label3.Font
= new System.Drawing.Font("Bookman Old Style", 15.75F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label3.Location
= new System.Drawing.Point(120, 48);
this.label3.Name
= "label3";
this.label3.Size
= new System.Drawing.Size(56, 24);
this.label3.TabIndex
= 4;
this.label3.Click
+= new System.EventHandler(this.label3_Click);
//
//
Form3
//
this.AutoScaleBaseSize
= new System.Drawing.Size(5, 13);
this.BackColor
= System.Drawing.Color.SkyBlue;
this.ClientSize
= new System.Drawing.Size(234, 122);
this.ControlBox
= false;
this.Controls.Add(this.label3);
this.Controls.Add(this.button2);
this.Controls.Add(this.OK);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox
= false;
this.MinimizeBox
= false;
this.Name
= "Form3";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Load
+= new System.EventHandler(this.Form3_Load);
this.ResumeLayout(false);
}
#endregion
private
void Form3_Load(object sender, System.EventArgs e)
{
this.label3.Text
= ppuan.ToString();
}
private
void button2_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
}
}
Form2.cs:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace
alleyway
{
///
///
Summary description for Form2.
///
public
class Form2 : System.Windows.Forms.Form
{
int
hhak;
private
System.Windows.Forms.Label label2;
private
System.Windows.Forms.Button button1;
private
System.Windows.Forms.Label label1;
///
///
Required designer variable.
///
private
System.ComponentModel.Container components = null;
public
Form2(int hak)
{
//
//
Required for Windows Form Designer support
//
hhak=hak;
InitializeComponent();
//
//
TODO: Add any constructor code after InitializeComponent call
//
}
///
///
Clean up any resources being used.
///
protected
override void Dispose( bool disposing )
{
if(
disposing )
{
if(components
!= null)
{
components.Dispose();
}
}
base.Dispose(
disposing );
}
#region
Windows Form Designer generated code
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.label2
= new System.Windows.Forms.Label();
this.button1
= new System.Windows.Forms.Button();
this.label1
= new System.Windows.Forms.Label();
this.SuspendLayout();
//
//
label2
//
this.label2.Font
= new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location
= new System.Drawing.Point(176, 32);
this.label2.Name
= "label2";
this.label2.Size
= new System.Drawing.Size(40, 40);
this.label2.TabIndex
= 5;
//
//
button1
//
this.button1.Font
= new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.button1.Location
= new System.Drawing.Point(232, 16);
this.button1.Name
= "button1";
this.button1.Size
= new System.Drawing.Size(88, 40);
this.button1.TabIndex
= 4;
this.button1.Text
= "Devam";
this.button1.Click
+= new System.EventHandler(this.button1_Click);
//
//
label1
//
this.label1.Font
= new System.Drawing.Font("Comic Sans MS", 16F, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label1.Location
= new System.Drawing.Point(24, 0);
this.label1.Name
= "label1";
this.label1.Size
= new System.Drawing.Size(136, 80);
this.label1.TabIndex
= 3;
this.label1.Text
= "Yandiniz!.. Kalan Hak =";
//
//
Form2
//
this.AutoScaleBaseSize
= new System.Drawing.Size(5, 13);
this.BackColor
= System.Drawing.Color.SkyBlue;
this.ClientSize
= new System.Drawing.Size(330, 79);
this.ControlBox
= false;
this.Controls.Add(this.label2);
this.Controls.Add(this.button1);
this.Controls.Add(this.label1);
this.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox
= false;
this.MinimizeBox
= false;
this.Name
= "Form2";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Load
+= new System.EventHandler(this.Form2_Load);
this.ResumeLayout(false);
}
#endregion
private
void Form2_Load(object sender, System.EventArgs e)
{
label2.Text=hhak.ToString();}
private
void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
}
}
Oyunun kaynak kodunu indirmek için
tiklayin.
Makale:
C# ve GDI+ Kullanılarak Yapılan DXBALL Oyunu C#, Visual C# ve .NET Tanıl Ergin
|