You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/tr/6-space-game/3-moving-elements-around/README.md

37 KiB

Uzay Oyunu Yapımı Bölüm 3: Hareket Ekleme

journey
    title Your Game Animation Journey
    section Movement Basics
      Understand motion principles: 3: Student
      Learn coordinate updates: 4: Student
      Implement basic movement: 4: Student
    section Player Controls
      Handle keyboard events: 4: Student
      Prevent default behaviors: 5: Student
      Create responsive controls: 5: Student
    section Game Systems
      Build game loop: 5: Student
      Manage object lifecycle: 5: Student
      Implement pub/sub pattern: 5: Student

Favori oyunlarınızı düşünün onları etkileyici kılan şey sadece güzel grafikler değil, her şeyin hareket etmesi ve eylemlerinize tepki vermesidir. Şu anda uzay oyununuz güzel bir tablo gibi, ancak ona hayat verecek hareketi eklemek üzereyiz.

NASA mühendisleri Apollo görevleri için rehberlik bilgisayarını programladıklarında benzer bir zorlukla karşılaştılar: Bir uzay aracını pilotun girdilerine nasıl tepki verecek şekilde programlarsınız ve aynı zamanda otomatik olarak rota düzeltmelerini nasıl sağlarsınız? Bugün öğreneceğimiz prensipler, oyuncu kontrollü hareketi otomatik sistem davranışlarıyla yönetme konusunda aynı kavramları yansıtıyor.

Bu derste, uzay gemilerinin ekran boyunca kaymasını, oyuncu komutlarına tepki vermesini ve pürüzsüz hareket desenleri oluşturmayı öğreneceksiniz. Her şeyi doğal bir şekilde birbirine bağlanan yönetilebilir kavramlara ayıracağız.

Sonunda, oyuncular kahraman gemilerini ekranın etrafında uçururken düşman gemileri yukarıda devriye gezecek. Daha da önemlisi, oyun hareket sistemlerini çalıştıran temel prensipleri anlayacaksınız.

mindmap
  root((Game Animation))
    Movement Types
      Player Controlled
      Automatic Motion
      Physics Based
      Scripted Paths
    Event Handling
      Keyboard Input
      Mouse Events
      Touch Controls
      Default Prevention
    Game Loop
      Update Logic
      Render Frame
      Clear Canvas
      Frame Rate Control
    Object Management
      Position Updates
      Collision Detection
      Lifecycle Management
      State Tracking
    Communication
      Pub/Sub Pattern
      Event Emitters
      Message Passing
      Loose Coupling

Ders Öncesi Test

Ders öncesi test

Oyun Hareketini Anlamak

Oyunlar, nesneler hareket etmeye başladığında canlanır ve bu genelde iki şekilde olur:

  • Oyuncu kontrollü hareket: Bir tuşa bastığınızda veya farenizi tıkladığınızda bir şey hareket eder. Bu, sizinle oyun dünyanız arasındaki doğrudan bağlantıdır.
  • Otomatik hareket: Oyun kendi kendine bir şeyleri hareket ettirmeye karar verdiğinde örneğin, düşman gemilerinin ekran boyunca devriye gezmesi gibi, siz bir şey yapmasanız bile.

Bilgisayar ekranında nesneleri hareket ettirmek düşündüğünüzden daha basittir. Matematik dersinden hatırladığınız x ve y koordinatlarını hatırlıyor musunuz? İşte tam olarak bununla çalışıyoruz. Galileo, 1610 yılında Jüpiter'in uydularını izlerken aslında aynı şeyi yapıyordu hareket desenlerini anlamak için zaman içinde konumları çiziyordu.

Ekranda bir şeyleri hareket ettirmek, bir flipbook animasyonu oluşturmak gibidir şu üç basit adımı takip etmeniz gerekir:

flowchart LR
    A["Frame N"] --> B["Update Positions"]
    B --> C["Clear Canvas"]
    C --> D["Draw Objects"]
    D --> E["Frame N+1"]
    E --> F{Continue?}
    F -->|Yes| B
    F -->|No| G["Game Over"]
    
    subgraph "Animation Cycle"
        H["1. Calculate new positions"]
        I["2. Erase previous frame"]
        J["3. Render new frame"]
    end
    
    style B fill:#e1f5fe
    style C fill:#ffebee
    style D fill:#e8f5e8
  1. Konumu güncelle Nesnenizin nerede olması gerektiğini değiştirin (belki 5 piksel sağa hareket ettirin)
  2. Eski kareyi sil Ekranı temizleyin, böylece her yerde hayalet izler görmezsiniz
  3. Yeni kareyi çizin Nesnenizi yeni yerine yerleştirin

Bunu yeterince hızlı yaparsanız, işte! Oyunculara doğal gelen pürüzsüz bir hareket elde ettiniz.

Kodda nasıl görünebileceğine bir örnek:

// Set the hero's location
hero.x += 5;
// Clear the rectangle that hosts the hero
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw the game background and hero
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);

Bu kodun yaptığı şey:

  • Kahramanın x-koordinatını 5 piksel güncelleyerek yatay olarak hareket ettirir
  • Önceki kareyi kaldırmak için tüm tuvali temizler
  • Tuvali siyah bir arka plan rengiyle doldurur
  • Kahraman resmini yeni konumunda yeniden çizer

Kahramanınızı saniyede birçok karede yeniden çizmenin performans maliyetlerini artırabileceği bir neden düşünebilir misiniz? Bu desene alternatifler hakkında okuyun.

Klavye olaylarını işleme

Burada oyuncu girdisini oyun eylemine bağlayacağız. Birisi lazer ateşlemek için boşluk tuşuna bastığında veya bir asteroitten kaçmak için ok tuşuna dokunduğunda, oyununuz bu girdiyi algılamalı ve buna tepki vermelidir.

Klavye olayları pencere seviyesinde gerçekleşir, yani tüm tarayıcı pencereniz bu tuş vuruşlarını dinler. Öte yandan fare tıklamaları belirli öğelere bağlanabilir (örneğin bir düğmeye tıklamak gibi). Uzay oyunumuz için klavye kontrollerine odaklanacağız çünkü bu, oyunculara klasik arcade hissi verir.

Bu, 1800'lerde telgraf operatörlerinin mors kodu girdisini anlamlı mesajlara çevirmesi gerektiği zamana benziyor biz de benzer bir şey yapıyoruz, tuş vuruşlarını oyun komutlarına çeviriyoruz.

Bir olayı işlemek için pencerenin addEventListener() metodunu kullanmanız ve ona iki giriş parametresi sağlamanız gerekir. İlk parametre olayın adıdır, örneğin keyup. İkinci parametre ise olay gerçekleştiğinde çağrılması gereken fonksiyondur.

İşte bir örnek:

window.addEventListener('keyup', (evt) => {
  // evt.key = string representation of the key
  if (evt.key === 'ArrowUp') {
    // do something
  }
});

Burada olanlarııklamak:

  • Tüm pencere üzerinde klavye olaylarını dinler
  • Hangi tuşun basıldığını içeren olay nesnesini yakalar
  • Basılan tuşun belirli bir tuşla eşleşip eşleşmediğini kontrol eder (bu durumda yukarı ok tuşu)
  • Koşul sağlandığında kodu çalıştırır

Tuş olayları için hangi tuşun basıldığını görmek için olay üzerinde kullanabileceğiniz iki özellik vardır:

  • key - basılan tuşun string temsili, örneğin 'ArrowUp'
  • keyCode - bu bir sayı temsili, örneğin 37, ArrowLeft ile eşleşir

Tuş olayı manipülasyonu oyun geliştirme dışında da faydalıdır. Bu tekniğin başka hangi kullanımlarını düşünebilirsiniz?

sequenceDiagram
    participant User
    participant Browser
    participant EventSystem
    participant GameLogic
    participant Hero
    
    User->>Browser: Presses ArrowUp key
    Browser->>EventSystem: keydown event
    EventSystem->>EventSystem: preventDefault()
    EventSystem->>GameLogic: emit('KEY_EVENT_UP')
    GameLogic->>Hero: hero.y -= 5
    Hero->>Hero: Update position
    
    Note over Browser,GameLogic: Event flow prevents browser defaults
    Note over GameLogic,Hero: Pub/sub pattern enables clean communication

Özel tuşlar: dikkat!

Bazı tuşların yerleşik tarayıcı davranışları vardır ve bunlar oyununuzu etkileyebilir. Ok tuşları sayfayı kaydırır ve boşluk tuşu aşağıya atlar birisi uzay gemisini kullanmaya çalışırken istemediğiniz davranışlar.

Bu varsayılan davranışları önleyebilir ve girdiyi oyununuzun işlemesine izin verebilirsiniz. Bu, erken dönem bilgisayar programcılarının özel davranışlar oluşturmak için sistem kesintilerini geçersiz kılmak zorunda olduğu zamana benzer biz bunu tarayıcı seviyesinde yapıyoruz. İşte nasıl:

const onKeyDown = function (e) {
  console.log(e.keyCode);
  switch (e.keyCode) {
    case 37:
    case 39:
    case 38:
    case 40: // Arrow keys
    case 32:
      e.preventDefault();
      break; // Space
    default:
      break; // do not block other keys
  }
};

window.addEventListener('keydown', onKeyDown);

Bu önleme kodunu anlamak:

  • İstenmeyen tarayıcı davranışlarına neden olabilecek belirli tuş kodlarını kontrol eder
  • Ok tuşları ve boşluk tuşu için varsayılan tarayıcı eylemini engeller
  • Diğer tuşların normal şekilde çalışmasına izin verir
  • Tarayıcının yerleşik davranışını durdurmak için e.preventDefault() kullanır

🔄 Pedagojik Kontrol

Olay İşleme Anlayışı: Otomatik harekete geçmeden önce şunları yapabildiğinizden emin olun:

  • keydown ve keyup olayları arasındaki farkııklayın
  • Varsayılan tarayıcı davranışlarını neden engellediğimizi anlayın
  • Olay dinleyicilerinin kullanıcı girdisini oyun mantığına nasıl bağladığınııklayın
  • Hangi tuşların oyun kontrollerine müdahale edebileceğini belirleyin

Hızlı Kendini Test Et: Ok tuşları için varsayılan davranışı engellemeseydiniz ne olurdu? Cevap: Tarayıcı sayfayı kaydırır, oyun hareketine müdahale eder

Olay Sistemi Mimarisi: Şimdi şunları anlıyorsunuz:

  • Pencere seviyesinde dinleme: Olayları tarayıcı seviyesinde yakalama
  • Olay nesnesi özellikleri: key stringleri ve keyCode numaraları
  • Varsayılan önleme: İstenmeyen tarayıcı davranışlarını durdurma
  • Koşullu mantık: Belirli tuş kombinasyonlarına tepki verme

Oyun kaynaklı hareket

Şimdi oyuncu girdisi olmadan hareket eden nesnelerden bahsedelim. Ekranda dolaşan düşman gemilerini, düz çizgilerde uçan mermileri veya arka planda sürüklenen bulutları düşünün. Bu otonom hareket, kimse kontrolleri dokunmasa bile oyun dünyanızı canlı hissettirir.

JavaScript'in yerleşik zamanlayıcılarını kullanarak konumları düzenli aralıklarla güncelleriz. Bu konsept, sarkaçlı saatlerin nasıl çalıştığına benzer düzenli bir mekanizma, tutarlı ve zamanlanmış eylemleri tetikler. İşte ne kadar basit olabileceği:

const id = setInterval(() => {
  // Move the enemy on the y axis
  enemy.y += 10;
}, 100);

Bu hareket kodunun yaptığı şey:

  • Her 100 milisaniyede bir çalışan bir zamanlayıcı oluşturur
  • Her seferinde düşmanın y-koordinatını 10 piksel günceller
  • Daha sonra durdurabilmek için interval kimliğini saklar
  • Düşmanı ekranda otomatik olarak aşağıya doğru hareket ettirir

Oyun döngüsü

İşte her şeyi bir araya getiren konsept oyun döngüsü. Oyununuz bir film olsaydı, oyun döngüsü film projektörü olurdu, kare kare göstererek her şeyin pürüzsüz bir şekilde hareket etmesini sağlar.

Her oyunun sahne arkasında çalışan bir döngüsü vardır. Bu, tüm oyun nesnelerini güncelleyen, ekranı yeniden çizen ve bu süreci sürekli olarak tekrarlayan bir fonksiyondur. Bu, kahramanınızı, tüm düşmanları, uçan lazerleri tüm oyun durumunu takip eder.

Bu konsept, Walt Disney gibi erken dönem film animatörlerinin hareket illüzyonu yaratmak için karakterleri kare kare yeniden çizmek zorunda olduğu zamana benziyor. Biz aynı şeyi yapıyoruz, sadece kalem yerine kod kullanıyoruz.

Bir oyun döngüsünün genelde kodda nasıl görünebileceğine bir örnek:

flowchart TD
    A["Start Game Loop"] --> B["Clear Canvas"]
    B --> C["Fill Background"]
    C --> D["Update Game Objects"]
    D --> E["Draw Hero"]
    E --> F["Draw Enemies"]
    F --> G["Draw UI Elements"]
    G --> H["Wait for Next Frame"]
    H --> I{Game Running?}
    I -->|Yes| B
    I -->|No| J["End Game"]
    
    subgraph "Frame Rate Control"
        K["60 FPS = 16.67ms"]
        L["30 FPS = 33.33ms"]
        M["10 FPS = 100ms"]
    end
    
    style B fill:#ffebee
    style D fill:#e1f5fe
    style E fill:#e8f5e8
    style F fill:#e8f5e8
const gameLoopId = setInterval(() => {
  function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    drawHero();
    drawEnemies();
    drawStaticObjects();
  }
  gameLoop();
}, 200);

Oyun döngüsü yapısını anlamak:

  • Önceki kareyi kaldırmak için tüm tuvali temizler
  • Arka planı düz bir renkle doldurur
  • Tüm oyun nesnelerini mevcut konumlarında çizer
  • Pürüzsüz animasyon oluşturmak için bu süreci her 200 milisaniyede bir tekrarlar
  • Kare hızını kontrol ederek interval zamanlamasını yönetir

Uzay Oyununa Devam Etmek

Şimdi, daha önce oluşturduğunuz statik sahneye hareket ekleyeceğiz. Onu bir ekran görüntüsünden interaktif bir deneyime dönüştüreceğiz. Her parçanın bir sonrakini doğal bir şekilde oluşturmasını sağlamak için adım adım ilerleyeceğiz.

Önceki derste kaldığınız kodu alın (veya yeni bir başlangıç yapmanız gerekiyorsa Bölüm II- başlangıç klasöründeki kodla başlayın).

Bugün oluşturacağımız şey:

  • Kahraman kontrolleri: Ok tuşları uzay geminizi ekranın etrafında yönlendirecek
  • Düşman hareketi: O uzaylı gemileri ilerlemeye başlayacak

Haydi bu özellikleri uygulamaya başlayalım.

Önerilen adımlar

your-work alt klasöründe sizin için oluşturulmuş dosyaları bulun. Şunları içermelidir:

-| assets
  -| enemyShip.png
  -| player.png
-| index.html
-| app.js
-| package.json

Projenize your-work klasöründe şu komutu yazarak başlayın:

cd your-work
npm start

Bu komutun yaptığı şey:

  • Proje dizinine geçer
  • Adres http://localhost:5000 üzerinde bir HTTP Sunucusu başlatır
  • Oyun dosyalarınızı tarayıcıda test etmeniz için sunmaya başlar

Yukarıdaki işlem adres http://localhost:5000 üzerinde bir HTTP Sunucusu başlatacaktır. Bir tarayıcıın ve o adresi girin, şu anda kahramanı ve tüm düşmanları görüntülemelidir; henüz hiçbir şey hareket etmiyor!

Kod ekleme

  1. Kahraman, düşman ve oyun nesnesi için özel nesneler ekleyin, bunlar x ve y özelliklerine sahip olmalıdır. (Kalıtım veya kompozisyon bölümünü hatırlayın).

    İPUCU oyun nesnesi, x ve y özelliklerine sahip olan ve kendisini bir tuvale çizebilme yeteneğine sahip olan nesne olmalıdır.

    İpucu: Aşağıda belirtilen yapıcı ile yeni bir GameObject sınıfı ekleyerek başlayın ve ardından tuvale çizin:

    class GameObject {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.dead = false;
        this.type = "";
        this.width = 0;
        this.height = 0;
        this.img = undefined;
      }
    
      draw(ctx) {
        ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
      }
    }
    

    Bu temel sınıfı anlamak:

    • Tüm oyun nesnelerinin paylaştığı ortak özellikleri tanımlar (konum, boyut, resim)
    • Nesnenin kaldırılıp kaldırılmadığını takip etmek için bir dead bayrağı içerir
    • Tuvalde nesneyi çizen bir draw() metodu sağlar
    • Alt sınıfların geçersiz kılabileceği tüm özellikler için varsayılan değerler ayarlar
    classDiagram
        class GameObject {
            +x: number
            +y: number
            +dead: boolean
            +type: string
            +width: number
            +height: number
            +img: Image
            +draw(ctx)
        }
    
        class Hero {
            +speed: number
            +type: "Hero"
            +width: 98
            +height: 75
        }
    
        class Enemy {
            +type: "Enemy"
            +width: 98
            +height: 50
            +setInterval()
        }
    
        GameObject <|-- Hero
        GameObject <|-- Enemy
    
        class EventEmitter {
            +listeners: object
            +on(message, listener)
            +emit(message, payload)
        }
    

    Şimdi bu GameObject sınıfını genişleterek Hero ve Enemy oluşturun:

    class Hero extends GameObject {
      constructor(x, y) {
        super(x, y);
        this.width = 98;
        this.height = 75;
        this.type = "Hero";
        this.speed = 5;
      }
    }
    
    class Enemy extends GameObject {
      constructor(x, y) {
        super(x, y);
        this.width = 98;
        this.height = 50;
        this.type = "Enemy";
        const id = setInterval(() => {
          if (this.y < canvas.height - this.height) {
            this.y += 5;
          } else {
            console.log('Stopped at', this.y);
            clearInterval(id);
          }
        }, 300);
      }
    }
    

    Bu sınıflardaki anahtar kavramlar:

    • extends anahtar kelimesini kullanarak GameObject'ten miras alır
    • super(x, y) ile üst yapıcıyı çağırır
    • Her nesne türü için belirli boyutlar ve özellikler ayarlar
    • setInterval() kullanarak düşmanlar için otomatik hareket uygular
  2. Tuş olay işleyicileri ekleyin ve kahramanı yukarı/aşağı, sola/sağa hareket ettirmek için tuş navigasyonunu yönetin.

    UNUTMAYIN bu bir Kartezyen sistemdir, sol üst köşe 0,0'dır. Ayrıca varsayılan davranışı durdurmak için kod eklemeyi unutmayın.

    İpucu: onKeyDown fonksiyonunuzu oluşturun ve pencereye bağlayın:

    const onKeyDown = function (e) {
      console.log(e.keyCode);
      // Add the code from the lesson above to stop default behavior
      switch (e.keyCode) {
        case 37:
        case 39:
        case 38:
        case 40: // Arrow keys
        case 32:
          e.preventDefault();
          break; // Space
        default:
          break; // do not block other keys
      }
    };
    
    window.addEventListener("keydown", onKeyDown);
    

    Bu olay işleyicinin yaptığı şey:

    • Tüm pencere üzerinde tuş aşağı olaylarını dinler
    • Hangi tuşların basıldığını görmek için tuş kodunu kaydeder
    • Ok tuşları ve boşluk tuşu için varsayılan tarayıcı davranışını engeller
    • Diğer tuşların normal şekilde çalışmasına izin verir

    Bu noktada tarayıcı konsolunuzu kontrol edin ve basılan tuşların kaydedildiğini izleyin.

  3. Uygula Pub sub pattern, bu kodunuzu temiz tutmanıza yardımcı olur ve geri kalan bölümleri takip etmenizi sağlar.

    Yayın-Abone olma deseni, olay algılamayı olay işleme sürecinden ayırarak kodunuzu düzenli tutmaya yardımcı olur. Bu, kodunuzu daha modüler ve bakımını kolay hale getirir.

    Bu son kısmı yapmak için şunları yapabilirsiniz:

    1. Pencereye bir olay dinleyici ekleyin:

      window.addEventListener("keyup", (evt) => {
        if (evt.key === "ArrowUp") {
          eventEmitter.emit(Messages.KEY_EVENT_UP);
        } else if (evt.key === "ArrowDown") {
          eventEmitter.emit(Messages.KEY_EVENT_DOWN);
        } else if (evt.key === "ArrowLeft") {
          eventEmitter.emit(Messages.KEY_EVENT_LEFT);
        } else if (evt.key === "ArrowRight") {
          eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
        }
      });
      

    Bu olay sistemi ne yapar:

    • Klavye girdisini algılar ve bunu özel oyun olaylarına dönüştürür
    • Girdi algılamayı oyun mantığından ayırır
    • Kontrolleri daha sonra değiştirmeyi kolaylaştırır, oyun kodunu etkilemeden
    • Aynı girdiye birden fazla sistemin tepki vermesine izin verir
    flowchart TD
        A["Keyboard Input"] --> B["Window Event Listener"]
        B --> C["Event Emitter"]
        C --> D["KEY_EVENT_UP"]
        C --> E["KEY_EVENT_DOWN"]
        C --> F["KEY_EVENT_LEFT"]
        C --> G["KEY_EVENT_RIGHT"]
    
        D --> H["Hero Movement"]
        D --> I["Sound System"]
        D --> J["Visual Effects"]
    
        E --> H
        F --> H
        G --> H
    
        style A fill:#e1f5fe
        style C fill:#e8f5e8
        style H fill:#fff3e0
    
    1. Bir EventEmitter sınıfı oluşturun ve mesajları yayınlayıp abone olun:

      class EventEmitter {
        constructor() {
          this.listeners = {};
        }
      
        on(message, listener) {
          if (!this.listeners[message]) {
            this.listeners[message] = [];
          }
          this.listeners[message].push(listener);
        }
      
      
    2. Sabitler ekleyin ve EventEmitter'ı ayarlayın:

      const Messages = {
        KEY_EVENT_UP: "KEY_EVENT_UP",
        KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
        KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
        KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
      };
      
      let heroImg, 
          enemyImg, 
          laserImg,
          canvas, ctx, 
          gameObjects = [], 
          hero, 
          eventEmitter = new EventEmitter();
      

    Kurulumu anlamak:

    • Yazım hatalarını önlemek ve yeniden düzenlemeyi kolaylaştırmak için mesaj sabitlerini tanımlar
    • Resimler, tuval bağlamı ve oyun durumu için değişkenler tanımlar
    • Yayın-abone sistemi için global bir olay yayıcı oluşturur
    • Bir dizi başlatır ve tüm oyun nesnelerini tutar
    1. Oyunu Başlat

      function initGame() {
        gameObjects = [];
        createEnemies();
        createHero();
      
        eventEmitter.on(Messages.KEY_EVENT_UP, () => {
          hero.y -= 5;
        });
      
        eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
          hero.y += 5;
        });
      
        eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
          hero.x -= 5;
        });
      
      
  4. Oyun döngüsünü ayarla

    window.onload fonksiyonunu yeniden düzenleyerek oyunu başlatın ve iyi bir aralıkta bir oyun döngüsü kurun. Ayrıca bir lazer ışını ekleyeceksiniz:

    window.onload = async () => {
      canvas = document.getElementById("canvas");
      ctx = canvas.getContext("2d");
      heroImg = await loadTexture("assets/player.png");
      enemyImg = await loadTexture("assets/enemyShip.png");
      laserImg = await loadTexture("assets/laserRed.png");
    
      initGame();
      const gameLoopId = setInterval(() => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        drawGameObjects(ctx);
      }, 100);
    };
    

    Oyun kurulumunu anlama:

    • Sayfanın tamamen yüklenmesini bekler
    • Canvas öğesini ve 2D çizim bağlamını alır
    • Tüm resim varlıklarını await kullanarak eşzamanlı olarak yükler
    • Oyun döngüsünü 100ms aralıklarla (10 FPS) başlatır
    • Ekranı temizler ve her karede yeniden çizer
  5. Kod ekle ve düşmanları belirli bir aralıkta hareket ettir

    createEnemies() fonksiyonunu yeniden düzenleyerek düşmanları oluşturun ve yeni gameObjects sınıfına ekleyin:

    function createEnemies() {
      const MONSTER_TOTAL = 5;
      const MONSTER_WIDTH = MONSTER_TOTAL * 98;
      const START_X = (canvas.width - MONSTER_WIDTH) / 2;
      const STOP_X = START_X + MONSTER_WIDTH;
    
      for (let x = START_X; x < STOP_X; x += 98) {
        for (let y = 0; y < 50 * 5; y += 50) {
          const enemy = new Enemy(x, y);
          enemy.img = enemyImg;
          gameObjects.push(enemy);
        }
      }
    }
    

    Düşman oluşturma işlemi:

    • Düşmanları ekranın ortasına yerleştirmek için pozisyonları hesaplar
    • İç içe döngülerle bir düşman ızgarası oluşturur
    • Her düşman nesnesine düşman resmini atar
    • Her düşmanı global oyun nesneleri dizisine ekler

    ve benzer bir işlem için bir createHero() fonksiyonu ekleyin.

    function createHero() {
      hero = new Hero(
        canvas.width / 2 - 45,
        canvas.height - canvas.height / 4
      );
      hero.img = heroImg;
      gameObjects.push(hero);
    }
    

    Kahraman oluşturma işlemi:

    • Kahramanı ekranın alt ortasına yerleştirir
    • Kahraman nesnesine kahraman resmini atar
    • Kahramanı çizim için oyun nesneleri dizisine ekler

    ve son olarak, çizimi başlatmak için bir drawGameObjects() fonksiyonu ekleyin:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    Çizim fonksiyonunu anlama:

    • Dizideki tüm oyun nesnelerini iterasyonla dolaşır
    • Her nesne üzerinde draw() metodunu çağırır
    • Canvas bağlamını nesnelerin kendilerini çizebilmesi için iletir

    🔄 Eğitimsel Kontrol Noktası

    Tam Oyun Sistemi Anlayışı: Tüm mimariyi kavradığınızı doğrulayın:

    • Hero ve Enemy'nin ortak GameObject özelliklerini paylaşmasını sağlayan miras nasıl çalışıyor?
    • Pub/sub deseni kodunuzu neden daha sürdürülebilir hale getiriyor?
    • Oyun döngüsü, akıcı animasyon oluşturmakta nasıl bir rol oynuyor?
    • Olay dinleyicileri kullanıcı girdisini oyun nesnesi davranışına nasıl bağlar?

    Sistem Entegrasyonu: Oyununuz artık şunları gösteriyor:

    • Nesneye Yönelik Tasarım: Temel sınıflar ve özel miras
    • Olay Tabanlı Mimari: Gevşek bağlılık için pub/sub deseni
    • Animasyon Çerçevesi: Tutarlı kare güncellemeleriyle oyun döngüsü
    • Girdi İşleme: Varsayılan önleme ile klavye olayları
    • Varlık Yönetimi: Resim yükleme ve sprite çizimi

    Profesyonel Desenler: Şunları uyguladınız:

    • Sorumlulukların Ayrılması: Girdi, mantık ve çizim ayrı tutuldu
    • Polimorfizm: Tüm oyun nesneleri ortak bir çizim arayüzünü paylaşıyor
    • Mesajlaşma: Bileşenler arasında temiz iletişim
    • Kaynak Yönetimi: Verimli sprite ve animasyon işleme

    Düşmanlarınız kahraman uzay geminize doğru ilerlemeye başlamalı! } }

    
    and add a `createHero()` function to do a similar process for the hero.
    
    ```javascript
    function createHero() {
      hero = new Hero(
        canvas.width / 2 - 45,
        canvas.height - canvas.height / 4
      );
      hero.img = heroImg;
      gameObjects.push(hero);
    }
    

    ve son olarak, çizimi başlatmak için bir drawGameObjects() fonksiyonu ekleyin:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    Düşmanlarınız kahraman uzay geminize doğru ilerlemeye başlamalı!


GitHub Copilot Agent Challenge 🚀

İşte oyununuzun cilasını artıracak bir meydan okuma: sınırlar ve akıcı kontroller eklemek. Şu anda kahramanınız ekranın dışına uçabiliyor ve hareket biraz kesik kesik hissedebilir.

Göreviniz: Uzay geminizi daha gerçekçi hissettirmek için ekran sınırlarını ve akıcı hareketi uygulayın. Oyuncular bir ok tuşuna bastığında, gemi kesikli adımlar yerine sürekli olarak kaymalı. Geminin ekran sınırlarına ulaştığında görsel bir geri bildirim eklemeyi düşünün oyun alanının kenarını göstermek için hafif bir efekt olabilir.

agent mode hakkında daha fazla bilgi edinin.

🚀 Meydan Okuma

Projeler büyüdükçe kod organizasyonu giderek daha önemli hale gelir. Fonksiyonlar, değişkenler ve sınıfların hepsinin bir arada karıştığını fark etmiş olabilirsiniz. Bu, Apollo görev kodunu organize eden mühendislerin birden fazla ekibin aynı anda çalışabileceği açık ve sürdürülebilir sistemler oluşturması gerektiği durumu hatırlatıyor.

Göreviniz: Bir yazılım mimarı gibi düşünün. Kodunuzu nasıl organize ederdiniz ki altı ay sonra siz (veya bir ekip arkadaşınız) ne olduğunu anlayabilsin? Şimdilik her şey tek bir dosyada kalsa bile, daha iyi bir organizasyon oluşturabilirsiniz:

  • İlgili fonksiyonları gruplandırmak ve net yorum başlıkları eklemek
  • Sorumlulukları ayırmak - oyun mantığını çizimden ayrı tutmak
  • Tutarlı adlandırma kuralları kullanmak
  • Modüller veya ad alanları oluşturmak ve oyununuzun farklı yönlerini organize etmek
  • Dokümantasyon eklemek ve her ana bölümün amacınııklamak

Düşünme soruları:

  • Kodunuzun hangi bölümleri geri döndüğünüzde anlaması en zor olanlar?
  • Kodunuzu başkalarının katkıda bulunmasını kolaylaştıracak şekilde nasıl organize edebilirsiniz?
  • Güçlendirmeler veya farklı düşman türleri gibi yeni özellikler eklemek isteseydiniz ne olurdu?

Ders Sonrası Quiz

Ders sonrası quiz

Gözden Geçirme ve Kendi Kendine Çalışma

Her şeyi sıfırdan inşa ediyoruz, bu öğrenmek için harika, ama işte küçük bir sır JavaScript'te harika oyun çerçeveleri var ve bunlar sizin için birçok ağır işi halledebilir. Kapsadığımız temellerde kendinizi rahat hissettiğinizde, mevcut olanları keşfetmeye değer.

Çerçeveleri, her aracı el yapımı yapmak yerine iyi donanımlı bir alet çantası olarak düşünün. Kod organizasyonu ile ilgili konuştuğumuz birçok sorunu çözebilirler ve haftalarca sürecek özellikler sunabilirler.

Keşfetmeye değer şeyler:

  • Oyun motorlarının kodu nasıl organize ettiği kullandıkları akıllı desenlere hayran kalacaksınız
  • Canvas oyunlarının sorunsuz çalışmasını sağlamak için performans ipuçları
  • Kodunuzu daha temiz ve sürdürülebilir hale getirebilecek modern JavaScript özellikleri
  • Oyun nesnelerini ve ilişkilerini yönetmek için farklı yaklaşımlar

🎯 Oyun Animasyonu Ustalık Zaman Çizelgeniz

timeline
    title Game Animation & Interaction Learning Progression
    
    section Movement Fundamentals (20 minutes)
        Animation Principles: Frame-based animation
                            : Position updates
                            : Coordinate systems
                            : Smooth movement
        
    section Event Systems (25 minutes)
        User Input: Keyboard event handling
                  : Default behavior prevention
                  : Event object properties
                  : Window-level listening
        
    section Game Architecture (30 minutes)
        Object Design: Inheritance patterns
                     : Base class creation
                     : Specialized behaviors
                     : Polymorphic interfaces
        
    section Communication Patterns (35 minutes)
        Pub/Sub Implementation: Event emitters
                              : Message constants
                              : Loose coupling
                              : System integration
        
    section Game Loop Mastery (40 minutes)
        Real-time Systems: Frame rate control
                         : Update/render cycle
                         : State management
                         : Performance optimization
        
    section Advanced Techniques (45 minutes)
        Professional Features: Collision detection
                             : Physics simulation
                             : State machines
                             : Component systems
        
    section Game Engine Concepts (1 week)
        Framework Understanding: Entity-component systems
                               : Scene graphs
                               : Asset pipelines
                               : Performance profiling
        
    section Production Skills (1 month)
        Professional Development: Code organization
                                : Team collaboration
                                : Testing strategies
                                : Deployment optimization

🛠️ Oyun Geliştirme Araç Seti Özeti

Bu dersi tamamladıktan sonra artık şunları ustalıkla yapabiliyorsunuz:

  • Animasyon İlkeleri: Kare tabanlı hareket ve akıcı geçişler
  • Olay Tabanlı Programlama: Klavye girdi işleme ve doğru olay yönetimi
  • Nesneye Yönelik Tasarım: Miras hiyerarşileri ve polimorfik arayüzler
  • İletişim Desenleri: Sürdürülebilir kod için pub/sub mimarisi
  • Oyun Döngüsü Mimarisi: Gerçek zamanlı güncelleme ve çizim döngüleri
  • Girdi Sistemleri: Varsayılan davranış önleme ile kullanıcı kontrol eşlemesi
  • Varlık Yönetimi: Sprite yükleme ve verimli çizim teknikleri

Sonraki 5 Dakikada Yapabilecekleriniz

  • Tarayıcı konsolunu açın ve addEventListener('keydown', console.log) ile klavye olaylarını görün
  • Basit bir div öğesi oluşturun ve ok tuşlarıyla hareket ettirin
  • Sürekli hareket oluşturmak için setInterval ile deney yapın
  • event.preventDefault() ile varsayılan davranışı önlemeyi deneyin

🎯 Bu Saatte Başarabilecekleriniz

  • Ders sonrası quiz'i tamamlayın ve olay tabanlı programlamayı anlayın
  • Tam klavye kontrolleriyle hareket eden kahraman uzay gemisini oluşturun
  • Akıcı düşman hareket desenlerini uygulayın
  • Oyun nesnelerinin ekran dışına çıkmasını önlemek için sınırlar ekleyin
  • Oyun nesneleri arasında temel çarpışma algılama oluşturun

📅 Haftalık Animasyon Yolculuğunuz

  • Cilalı hareket ve etkileşimlerle tam uzay oyununu tamamlayın
  • Eğriler, hızlanma ve fizik gibi gelişmiş hareket desenleri ekleyin
  • Akıcı geçişler ve yumuşatma fonksiyonları uygulayın
  • Parçacık efektleri ve görsel geri bildirim sistemleri oluşturun
  • Oyun performansını optimize ederek akıcı 60fps oynanış sağlayın
  • Mobil dokunmatik kontroller ve duyarlı tasarım ekleyin

🌟 Aylık Etkileşimli Gelişim

  • Gelişmiş animasyon sistemleriyle karmaşık etkileşimli uygulamalar oluşturun
  • GSAP gibi animasyon kütüphanelerini öğrenin veya kendi animasyon motorunuzu oluşturun
  • ık kaynak oyun geliştirme ve animasyon projelerine katkıda bulunun
  • Grafik yoğun uygulamalar için performans optimizasyonunda ustalaşın
  • Oyun geliştirme ve animasyon hakkında eğitim içerikleri oluşturun
  • Gelişmiş etkileşimli programlama becerilerini sergileyen bir portföy oluşturun

Gerçek Dünya Uygulamaları: Oyun animasyon becerileriniz doğrudan şunlara uygulanabilir:

  • Etkileşimli Web Uygulamaları: Dinamik panolar ve gerçek zamanlı arayüzler
  • Veri Görselleştirme: Animasyonlu grafikler ve etkileşimli görseller
  • Eğitim Yazılımı: Etkileşimli simülasyonlar ve öğrenme araçları
  • Mobil Geliştirme: Dokunmatik tabanlı oyunlar ve hareket algılama
  • Masaüstü Uygulamaları: Akıcı animasyonlarla Electron uygulamaları
  • Web Animasyonları: CSS ve JavaScript animasyon kütüphaneleri

Kazanılan Profesyonel Beceriler: Artık şunları yapabilirsiniz:

  • Olay Tabanlı Sistemler tasarlayarak karmaşıklıkla ölçeklenebilir
  • Matematiksel İlkeler kullanarak akıcı animasyonlar uygulayın
  • Karmaşık Etkileşim Sistemlerini tarayıcı geliştirici araçlarıyla hata ayıklayın
  • Oyun Performansını farklı cihazlar ve tarayıcılar için optimize edin
  • Sürdürülebilir Kod Yapıları tasarlayarak kanıtlanmış desenler kullanın

Oyun Geliştirme Kavramlarında Ustalık:

  • Kare Hızı Yönetimi: FPS ve zamanlama kontrollerini anlama
  • Girdi İşleme: Platformlar arası klavye ve olay sistemleri
  • Nesne Yaşam Döngüsü: Oluşturma, güncelleme ve yok etme desenleri
  • Durum Senkronizasyonu: Oyun durumunu kareler arasında tutarlı tutma
  • Olay Mimarisi: Oyun sistemleri arasında ayrık iletişim

Bir Sonraki Seviye: Çarpışma algılama, puanlama sistemleri, ses efektleri eklemeye veya Phaser ya da Three.js gibi modern oyun çerçevelerini keşfetmeye hazırsınız!

🌟 Başarı Kilidi Açıldı: Profesyonel mimari desenlerle tam bir etkileşimli oyun sistemi oluşturdunuz!

Ödev

Kodunuzu yorumlayın


Feragatname:
Bu belge, AI çeviri hizmeti Co-op Translator kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çeviriler hata veya yanlışlıklar içerebilir. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan yanlış anlamalar veya yanlış yorumlamalardan sorumlu değiliz.