Məsləhətlər

C Dərsliklərində 2D Oyun Proqramlaşdırması: İlan

C Dərsliklərində 2D Oyun Proqramlaşdırması: İlan

Bu dərsliyin məqsədi nümunələr vasitəsilə 2D oyun proqramlaşdırma və C dilini öyrətməkdir. Müəllif 1980-ci illərin ortalarında oyunları proqramlaşdırmaq üçün istifadə edirdi və 90-cı illərdə bir il ərzində MicroProse-də bir oyun dizayneri idi. Bunun çox hissəsi bugünkü böyük 3D oyunlarının proqramlaşdırılması ilə əlaqəli olmasa da, kiçik təsadüfi oyunlar üçün faydalı bir giriş kimi xidmət edəcəkdir.

İlan tətbiq etmək

Bir obyektin 2D sahəsi üzərində hərəkət etdiyi ilan kimi oyunlar, oyun obyektlərini ya 2D şəbəkə şəklində və ya obyektlərin tək ölçülü bir sıra şəklində təmsil edə bilər. "Obyekt" burada obyekt yönümlü proqramlaşdırmada istifadə olunduğu kimi deyil, hər hansı bir oyun obyekti mənasını verir.

Oyun nəzarətləri

Açarlar W = yuxarı, A = sola, S = aşağı, D = sağa hərəkət edir. Oyundan çıxmaq üçün Esc düyməsini basın, fırlanma sürətini dəyişmək üçün f (bu sürətli ola bilər ekrana sinxronizasiya olunmur), debug məlumatını dəyişdirmək üçün nişanı və pa. Durdurulduqda başlıq dəyişir və ilan yanıb-sönür,

İlanda əsas oyun obyektləri var

  • İlan
  • Tələlər və meyvələr

Gameplay üçün, bir sıra ints hər oyun obyektini (və ya ilan hissəsini) tutacaqdır. Bu obyektləri ekran tamponuna göstərərkən də kömək edə bilər. Oyun üçün qrafikanı aşağıdakı kimi tərtib etdim:

  • Üfüqi ilan gövdəsi - 0
  • Şaquli ilan bədəni - 1
  • 4 x 90 dərəcə döngələrdə baş 2-5
  • 4 x 90 dərəcə döngələrdə 6-9
  • İstiqamətləri dəyişdirmək üçün əyrilər. 10-13
  • Alma - 14
  • Çiyələk - 15
  • Banan - 16
  • Tələ - 17
  • Snake.gif faylı görüntüsünə baxın

Beləliklə, bu dəyərləri blockWIDTH * HEIGHT olaraq təyin olunan bir grid tipində istifadə etmək mənasızdır. Şəbəkədə cəmi 256 yer olduğundan, onu bir ölçülü serialda saxlamaq üçün seçdim. 16 x16 griddəki hər bir koordinat 0-255-lik bir tamdır. Şəbəkəni daha böyük edə biləcəyiniz üçün ints istifadə etdik. Hər şey # WIDTH və HEIGHT ikisi ilə 16 # müəyyən edilir. İlan qrafikası 48 x 48 piksel (GRWIDTH və GRHEIGHT #defines) olduğu üçün pəncərə əvvəlcədən 17 x GRWIDTH və 17 x GRHEIGHT olaraq təyin olunmuşdur. .

Bu oyun sürətində bir fayda var, çünki iki indeksdən istifadə həmişə birindən daha yavaş olur, ancaq ilanın Y koordinatlarından şaquli hərəkət etmək üçün 1 əlavə etmək və ya çıxartmaq əvəzinə WIDTH çıxartmaq deməkdir. Sağa keçmək üçün 1 əlavə edin. Gizli olsa da, x və y koordinatlarını tərtib zamanı çevirən makro l (x, y) təyin etdik.

Makro nədir?

#define l (X, Y) (Y * WIDTH) + X

Birinci sıra indeks 0-15, 2-ci 16-31 və s. İlan birinci sütunda olarsa və sola hərəkət edirsə, divara vurulan çek, sola keçməzdən əvvəl% WIDTH == 0 koordinatının olub-olmadığını yoxlamalıdır. sağ divar koordinatı% WIDTH == WIDTH-1. % C modulu operatordur (saat arifmetikası kimi) və bölündükdən sonra qalan hissəni qaytarır. 31 div 16 15-dən bir qalıq buraxır.

İlanı idarə etmək

Oyunda istifadə olunan üç blok (int massiv) var.

  • ilan, üzük tamponu
  • forma - Snake qrafik indekslərini tutur
  • dir - baş və quyruğu da daxil olmaqla ilanın hər seqmentinin istiqamətini tutur.

Oyun başlanğıcında ilan başı və quyruğu ilə iki seqmentdir. Hər ikisi 4 istiqamətdə işarə edə bilər. Şimal üçün baş 3, quyruq 7, şərq başı üçün 4, quyruq 8, cənub başı üçün 5 və quyruq 9, qərb üçün baş 6, quyruq 10dur İlan iki seqment uzun olduğu halda baş və quyruq həmişə 180 dərəcə bir-birindədir, lakin ilan böyüdükdən sonra 90 və ya 270 dərəcə ola bilər.

Oyun şimala 120-ci yerdə şimala baxan və quyruğu təxminən 136-da cənuba baxan ilə başlayır. Təxminən 1600 bayt saxlama dəyəri az olanda, yuxarıda göstərilən ilan halqası tamponunda ilan yerlərini tutaraq oyunda nəzərə çarpan bir sürət əldə edə bilərik.

Bir üzük Bufer nədir?

Bir ring tamponu sabit bir ölçüdə olan bir növbənin saxlanması üçün istifadə olunan bir yaddaş blokudur və bütün məlumatları tutmaq üçün kifayət qədər böyük olmalıdır. Bu vəziyyətdə, yalnız ilan üçün. Məlumatlar növbənin ön hissəsinə basdırılır və arxadan götürülür. Əgər növbənin ön hissəsi blokun ucuna dəyirsə, o zaman ətrafa sarılır. Blok kifayət qədər böyük olduqda, növbənin önü heç vaxt arxa ilə tutula bilməz.

İlanın hər yeri (yəni tək int koordinat) quyruqdan başınadək (yəni arxaya) ring tamponunda saxlanılır. Bu, sürət fayda verir, çünki ilanın nə qədər vaxtı olursa olsun, yalnız baş, quyruq və başdan sonrakı ilk seqment (əgər varsa) hərəkət edərkən dəyişdirilməlidir.

Arxada saxlamaq da faydalıdır, çünki ilan yediyi zaman ilan sonrakı yerə köçəndə böyüyəcəkdir. Bu halqa tamponunda başın bir yerini dəyişdirmək və köhnə baş yerini bir seqment halına gətirməklə edilir. İlan başdan, 0-n seqmentdən), sonra isə quyruqdan ibarətdir.

İlan yemək yeyərkən, yem yemi dəyişkənliyi 1-ə qoyulur və DoSnakeMove () funksiyasında yoxlanılır

İlanı hərəkət etdirmək

Üzük tamponundakı baş və quyruq yerlərini qeyd etmək üçün iki indeks dəyişəndən istifadə edirik, headindex və tailindex. Bunlar 1 (headindex) və 0-da başlayır. Beləliklə, ring tamponundakı 1 yer ilanın (0-255) yerini lövhədə saxlayır. Yer 0 quyruq yerini tutur. İlan bir yerə irəlilədikdə, həm quyruq ucu, həm də baş ucu bir-bir artırılaraq 256-a çatdıqda 0-a bükülür. İndi baş olan yer quyruğun olduğu yerdədir.

Deyilən 200 seqmentdə dolanan və qıvrılan çox uzun bir ilanla belə. yalnız headindex, başın yanında və segmentindex hər hərəkət edərkən dəyişir.

Qeyd edək ki, SDL-in necə işlədiyinə görə, hər çərçivəni bütün ilanı çəkməliyik. Hər element çərçivə tamponuna çəkilir və sonra göründüyü üçün sürüşür. Bunun bir üstünlüyü var, baxmayaraq ki, ilanı hamar bir şəkildə deyil, bir neçə piksel sürətlə hərəkət etdirə bilərik.