18 Aralık 2016 Pazar

2D Arkanoid Oyunu Yapımı




Gereksinimler

Bu oyun Unity 5.4.3f1 sürümü ve C# programlama dili kullanılarak yapılmıştır. İleri sürümlerde oyunu yapmak için kullanılabilir.



Proje Kurulum Ayarları

Unity Ekranını açıyoruz. "New project" butonuna tıklıyoruz.



Proje adını "arkanoid" yaptıktan sonra projeyi kaydetmek için istediğimiz bir klasörü seçiyoruz. Ardından oyununun boyutunu 2D olarak seçiyoruz.




Şimdi kamera ayarlarını yapmaya başlayabiliriz. İlk olarak Hiyerarşi bölümündeki Main Camera'yı seçiyoruz. Background rengini siyah yapıyoruz ve size ayarını aşağıda görüldü gibi 125 yapıyoruz.
Camera in Inspector
Not: "Size" kısmını  kameranın zoom ayarını yapmak için kullanırız. 

Arkaplan Deseni

Orjinal Arkanoid oyununda olduğu gibi arka planı mavi desenli yapıyoruz.
Arkanoid Hexagon Pattern
Not: Yukarıdaki resme sağ tıklayıp, Save As'e tıkladıktan sonra..., projenin Assets klasörünü seçiyoruz.Klasörün içine Sprites isimli yeni bir klasör ekledikten sonra resmi buraya kaydediyoruz.
Project kısmından hexagon_pattern dosyasına tıklıyoruz.
Hexagon Pattern selected
Ve Import Settings ayarlarını yapıyoruz.
Hexagon Pattern ImportSettings
Not: Bu kısım  Unity'e resmi yükleme ayarlarını gösteren kısımdır. 
Şimdi hexagon_pattern dosyasını Hiyerarşiye bölümüne sürüklüyoruz. Artık resmimiz oyunun bir parçası.
Drag Hexagon Pattern into Hierarchy

Sorting Layer Ayarı 

Oyunumuzda bazı karakterler üst katmanda bazıları altta olacaktır. Sorting Layer ayarını bunun için yaparız. 
 Resmin arkaplanda kalmasını, topun ve diğer bölümlerin onun üstünde kalmasını sağlamalıyız. 
Bunun için  Sorting Layer kullanacağız. hexagon pattern dosyasının Sorting Layer ayarını değiştireceğiz.
Hexagon SpriteRenderer with default sorting layer
Bunun için Sorting Layer listesini açtıktan sonra Background isimli yeni bir layer (katman) ekleyeceğiz.  
Background Sorting Layer
Şimdi hexagon_pattern dosyasını tekrar seçiyoruz ve Sorting Layer ayarını Background yapıyoruz.
Hexagon Pattern SpriteRenderer with Background Sorting Layer

Sınırların Eklenmesi

Sınırların Resim Dosyaları

Topun oyundan uçup çıkmaması için oyuna kenar çizgileri eklemeliyiz. Her bir sınır için bi resim dosyası kullanıyoruz.
Arkanoid Top Border
Arkanoid Left Border       Arkanoid Right Border
Not: Yukarıdaki üç resmide projenin Assets klasörü içindeki kendi açtığımız Sprites klasörüne ekleyiniz. 

Border(Sınır) Dosyalarının İçe Aktarma Ayarları

Önceden kullandığımız import etme ayarlarını kullanacağız:
Border ImportSettings
Şimdi Project kısmından bu dosyaları Hiyerarşi kısmına aktarabiliriz. Ve oyunun üç kenarına şekildeki gibi konumlandırırız.

Borders Positioned

Border(Sınır) Fizik Ayarları


Şu anda sınırlarımız sadece bir resimden ibaret. Onları fiziksel oyun parçaları yapmamız gerekiyor(Topun bloklara çarpması(collide) gibi ayarlar yapılmalı).Öncelikle hepsini Hierarchy kısmından seçiyoruz.
Borders in Hierarchy
Daha sonra, Inspector kısmından Add Component->Physics 2D->Box Collider 2D'ı seçiyoruz.
Borders with Collider
Artık sınırlar da oyundaki fiziksel dünyanın bir parçası. (BoxCollider2D ayarı sayesinde çarpılabilen objelere dönüştüler.)

Raket

Raket Resim Dosyası

Şimdi raket karakterimizi oluşturalım. Oyuncu raketi sağa sola hareket ettirebilmeli.
Öncelikle raket resim dosyasını indirip projenin Assets/Sprites dosyasına kaydediyoruz.
Arkanoid Racket

Raket Dosyasının Import Ayarlarının Yapılması


Import Settings bölümünden ayarları aşağıdaki gibi yapıyoruz.
Racket ImportSettings
Import ayarlarını yaptıktan sonra, raket dosyasını Project kısmından, Hierarchy kısmına sürüklüyoruz ve Raket karakterini  aşağıdaki resimdeki gibi ekranın altında ortalıyoruz.
Racket InGame

Raket Fizik Ayarları

Raketi resim dosyası olmaktan çıkarmak için fizik ayarlarını yapıyoruz.Bunun için Hierarchy kısmından raketi seçtikten sonra  Inspector kısmından Add Component->Physics 2D->Box Collider 2D ekliyoruz.
Racket Collider
Rakete  BoxCollider2D (başka cisimlerle çarpışma)ayarını ekledikten sonra bir de Rigidbody ayarı ekliyoruz.Rigidbody ayarı karakterimizin hareket edebilmesi , hız ağırlık gibi fiziksel ayarla sahip olması için kullanılır.

Rakete Rigidbody eklemek için Inspector kısmından Add Component->Physics 2D->Rigidbody'i seçeriz.Daha sonra Rigidbody ayarlarından,  Gravity ayarını 0 yaptık(Raketimizin aşağıya düşmemesi için) ve  Fixed Angle' seçili hale getirdik(Raket kendi etrafında dönmeye başlamaması için).
Racket Rigidbody

Raketin Hareket Etmesi

Oyuncu raketi yatay olarak hareket ettirebilmeli. Bu tarz bir özellik kod ekleyerek yapılabilir. Bunun için Inspector kısımıdan Add Component->New Script'i seçiyoruz ve ismini Racket olarak değiştirdikten sonra dilini C# yapıyoruz. 
Create Racket Script
Rakete Racket isimli yeni bir script eklemiş olduk.Bu scripti raketin hareket ayarlarını yazmak için kullanacağız.Daha sonra Project kısmında Assets dosyasının içinde oluşan Racket.cs dosyasının, Assets dosyasının içinde oluşturduğumuz yeni Scripts klasörünün içine klasör düzenini sağlamak için koyarız.
Racket Script in Project Area

Scripte çift tıklayarak, script dosyasını Unity'nin MonoDevelop editöründe açtık. Visual Studio, Unity Xamarin gibi editörleride kullanabiliriz.Bu ayarı Unity ekranında Edit/Preferences bölümünü açtıktan sonra içerdeki External Tools sekmesinden External Script Editor ayarını MonoDevelop olarak seçerek yapabiliriz.(MonoDevelop editörü Unity  kurulum paketi içinde gelmektedir.)
using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }
}
Hazır gelen Start() fonksiyonu oyunun başlangıç anında çağırılan bir fonksiyondur. Update() fonksiyonu ise 60 sn'de bir yeniden çağırılan bir fonksiyondur.
 FixedUpdate ise başka bir update fonksiyonudur. Update() fonksiyonu gibi ara ara çağırılan bir fonksiyondur ama çağrılacağı zamanı kısıtlayabildiğimizden dolayı kullanılması daha avantajlı bir fonksiyondur.
Start() ve Update() fonksiyonlarını kaldırdıktan sonra FixedUpdate() fonksiyonunu ekledik.
using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    void FixedUpdate () {
    
    }
}



Raketin hareket etmesi için Rigidbody içindeki velocity(yön verilmiş hız) değişkenini kullanırız.Bu değişken cismin hareket doğrultusuna göre +, - değer alabilir. Tipi Vector2'dir.
Vector2 Directions
Scriptimize speed(hızın sadece değerini tutar, yönünü tutmaz) değişkeni ekliyoruz.
using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {
    // Movement Speed
    public float speed = 150;
    
    void FixedUpdate () {
    
    }
}
Kullanıcı raketi sağa sola hareket ettirebilmelidir(yön tuşlarıyla veya A/D harf tuşlarıyla). Bunun için  Unity'nin GetAxisRaw fonksiyonu kullanırız(yatay hareket i sağlamakiçin). Bu fonksiyon sol için  -1, yönsüzlük için 0  ve sağ için 1 değerini döndürüyor.
void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");
}
Şimdi  velocity değişkeninin değerini hesaplayabiliriz(speed değişkeninin değerini hareket yönüyle çarparak).
void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");
    
    // Set Velocity (movement direction * speed)
    GetComponent<Rigidbody2D>().velocity = Vector2.right * h * speed;
}

Note: Hareketin yönünü hesaplamak için Vector2.right değerini h ile çarptık. h 'ın aldığı değerlere göre(-1, 0 ,1) hareketimiz sırasıyla sol, hareketsiz yada sağ değerlerini alacaktır. Bu hareket yönü değerini spped değişkeniyle çarparak velocity değişkeninin değerini bulduk.
Raketi hareket ettirmek için yapmamız gerekenler bu kadar. Game ekranını açıp, play'e basarak artık 
raketimizi sağa sola hareket ettirebildiğimizi görürüz.
Racket Movement

Top

Top Resim Dosyası

Topu oyuna eklemenin vakti geldi.Öncelikle aşağıdaki Ball.png adlı resim dosyasını Assets/Sprites klasörümüze kaydediyoruz.

Aşağıdaki Import Settings ekran ayarlarını yapıyoruz.
Ball ImportSettings
Ve Ball.png dosyasını Project bölümünden Hieararch bölümüne sürüklüyoruz.
Arkanoid Ball in Scene

Ball Collider Özelliğinin Eklenmesi (Çapışma Özelliği)

Top fiziksel dünyanın özelliklerini göstermeli.Bunun için , Hierarchy bölümünde Ball'a tıkladıktan sonra, Add Component->Physics 2D->Box Collider 2D diyerek bu özelliği ekliyoruz.
Ball Collider
Top sınır duvarlarına geldiğinde sekebilmeli. Bunun için  Ball Collider'a Physics 2D Material özelliği eklememiz gerekir. Physics 2D Material  Friction(sürtünme) and Bounciness(sekme,sıçrama) gibi özellikler içeriyor.
Project alanına sağ tıklıyoruz ve  Create->Physics2D Material dedikten sonra BallMaterial olarak ismlendiriyoruz:
Ball Material in Project Area
Daha sonra Inspector'dan aşağıdaki iki ayarı yapıyoruz.
Ball Material in Inspector
Şimdi yapmamız gereken, BallMaterial dosyasını Project Area bölümünden Ball's Collider içindeki  Material kutucuğuna sürüklemek.
Ball Collider with Physics Material
Artık topumuz duvarlardan geri sekebiliyor.

Topun Rigidbody Ayarı

Top artık fiziksel dünyanın bir parçası oldu., Ama oyunda hareket eden herşeyin bir Rigidbody'si olmalıdır. Topumuza  Inspector kısmından Add Component->Physics 2D->Rigidbody 2D'i seçerek ekliyoruz.
Rigidbody için aşağıdaki resimdeki ayarları yapıyoruz.
  • Topun kütlesi(Mass) raketten daha küçük olmalı, raketi aşağıya düşürmemeli.
  • Ağırlık(Gravity) kapatılmış olmalı.(yanındaki kutucuk seçilmemiş olmalı)

Ball Rigidbody

Şu anda play'e bassaydık top hareket etmezdi, çünkü velocity(yönlü hız) değişkeni yok. Bunun için Inspector kısmından Add Component->New Script'e tıklıyoruz ve C# dilini seçerek Ball isimli bir script oluşturuyoruz. Klasör düzeni içinde, Project kısmında oluşan yeni Ball.cs script dosyamızı, Assets/Scripts dosyamızın içine atıyoruz.
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }
}
Update() fonksiyonuna ihtiyacımız olmadığından siliyoruz.
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
}
Rigidbody'nin velocity özelliğini kullanarak, topun belli bir hızla yukarı gitmesini sağlıyoruz.
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;
    
    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }
}
Play tuşuna basarak, topun duvarlardan geri sektiğini görebiliriz.
Ball Bouncing off

Top ve Raketin Çarpışma Açısının Ayarı

Oyunun sonuna doğru yaklaştık. Şimdi to ve raketin çarpışma ayarını yapabiliriz.
unity-2d-pong-game-racket-bounce-angles
Ball scriptini açıyoruz. Unity'nin OnCollisionEnter2Dfonksiyonunu kullanacağız. Top herhangi bir cisimle çarpıştığı anda çağrılan özel bir fonksiyondur.
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;
    
    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }
    
    void OnCollisionEnter2D(Collision2D col) {
        // This function is called whenever the ball
        // collides with something
    }
}

Topun, rakete çarpma açısına göre velocity(yönlü hız) hesaplayan bir koda ihtiyacımız olacaktır.
1  -0.5  0  0.5   1  <- x value depending on where it was hit
===================  <- this is the racket

Bulmamız gereken şey tam olarak topun rakete hangi açıyla çarptığıdır. Bunun için topun x koordinatını
raketin enine bölüyoruz.Bunu yapan fonksiyonumuz aşağıdaki gibidir.
float hitFactor(Vector2 ballPos, Vector2 racketPos,
                float racketWidth) {
    // ascii art:
    //
    // 1  -0.5  0  0.5   1  <- x value
    // ===================  <- racket
    //
    return (ballPos.x - racketPos.x) / racketWidth;
}


 OnCollisionEnter2D fonksiyonumuzun son hali sağıdaki gibidir:
void OnCollisionEnter2D(Collision2D col) {
    // Hit the Racket?
    if (col.gameObject.name == "racket") {
        // Calculate hit Factor
        float x=hitFactor(transform.position,
                          col.transform.position,
                          col.collider.bounds.size.x);

        // Calculate direction, set length to 1
        Vector2 dir = new Vector2(x, 1).normalized;

        // Set Velocity with dir * speed
        GetComponent<Rigidbody2D>().velocity = dir * speed;
    }
}

Play tuşuna basarak, topumuzun rakete çarpma açısına göre hareket ettiğini görebiliriz.

Blokların Eklenmesi

Artık blokları eklemeye başlayabiliriz. 
Bloklar için aşağıdaki resim dosyalarını kullanacağız:
  •  Blue Block
  •  Green Block
  •  Pink Block
  •  Red Block
  •  Yellow Block
Not:Bu beş resmi indirerek Assets/Sprites klasörüne kaydettik.

Öncelikle kırmızı renkli blokla başladık.Project kısmından dosyayı seçtikten sonra Import Settings ayarlarını aşağıdaki gibi yaptık.
Block Import Settings
Bu ayardan sonra dosyayı Project Area bölümünden Hierarchy bölümüne sürükledik ve oyun ekranımıza aşağıdaki gibi yerleştirdik.

Block in Scene
Inspector bölümünden Add Component->Physics 2D->Box Collider 2D'ı seçerek bloğu oyununun fiziksel dünyasının bir parçası haline getirdik.

Block Collider
Topun bloğa dokunduğu anda bloğun parçalanmasını istiyoruz. Bu tarz bir özelliği eklemek için script yazmalıyız. Şimdi,  Inspector'dan Add Component->New Script'i seçerek  Block isimli  CSharp dili ayarlı bir script oluşturuyoruz. Project bölümünden oluşan yeni script dosyasını Assets/Scripts dosyasının içine sürüklüyoruz.
using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }
}


Start ve Update fonksiyonlarını onlara ihtiyacımız olmadığı için siliyoruz. OnCollisionEnter2D fonksiyonunu kullanıyoruz.
using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D collisionInfo) {
        // Destroy the whole Block
        Destroy(gameObject);
    }
}

Note: Destroy(this) sadece blok scriptini siler.Eper tüm bloğu silmek istersek Destroy(gameObject) fonksiyonunu kullanırız.
Kopyala yapıştır yaparak bloğumuzu çoğaltıyoruz ve yeni blokları aşağıdaki gibi yerleştiriyoruz.
Block duplicated
Bu işlemleri sarı,mavi,pembe ve yeşil bloklar içinde tekrarlıyoruz.
All Blocks
Not: Block scriptimizi de diğer bloklar için kullanıyoruz.
Ve oyunumuz hazır. Play butonuna tıklayarak oyunumuzu oynayabiliriz.
Unity 2D Arkanoid Game

4 yorum:

  1. Baya sağlam olmuş bence

    YanıtlaSil
  2. ya
    kb yeniyim de kamera ayarlarına giremiyorum size ı ayarlayamıyorum yardımcı olabilirmsizin

    YanıtlaSil
  3. tmm ya yaptım np ve çok teşşekkür ederim

    YanıtlaSil
  4. Bu yorum yazar tarafından silindi.

    YanıtlaSil