Tutorial Game Mario dengan Basic Processing


Hi sobat.. kali ini ane akan posting melanjutkan tutorial membuat game mario dimana part 1 dan 3 bisa dilihat di sini PART 1 PART 3

latar belakang ...

Mari tambahkan latar belakang berikut:
Menambahkan latar belakang berarti memperlakukannya seperti sprite khusus, dan menambahkan ini ke daftar sprite latar yang tidak bergerak:
class MarioLayer extends LevelLayer {
MarioLayer(Level owner) {
    super(owner);
    setBackgroundColor(color(0, 100, 190));
    Sprite background_picture = new Sprite("graphics/backgrounds/sky.gif");
    TilingSprite background = new TilingSprite(background_picture,0,0,width,height);
    addBackgroundSprite(background);
    addBoundary(new Boundary(0,height-48,width,height-48));
    showBoundaries = true;
    Mario mario = new Mario(width/4, height/2);
    addPlayer(mario);
  }
}
Baris yang penting adalah baris addBackgroundSprite(...) . Ini mengatakan "Tambahkan sesuatu, yang ada di dalam (dan), ke daftar sprite latar belakang." dengan kata "statis" yang berarti "hal-hal yang tidak berubah". Dalam hal ini kami menambahkan apa yang dikenal sebagai "Tiling Sprite" - gambar yang diulang untuk mengisi area tertentu di layar. Karena kami ingin latar belakang untuk mengisi seluruh level, kami menggunakan gambar garis langit Mario yang khas, dan membuatnya berulang dengan sendirinya mulai dari (0,0), yang merupakan sudut kiri atas dari level, semua jalan ke (lebar, tinggi), yang merupakan sudut kanan bawah dari level.
Kami dapat mempertahankannya, tetapi karena kami memperbarui latar belakangnya, mari pastikan bahwa Mario tidak kehabisan level: 
class MarioLayer extends LevelLayer {
  MarioLayer(Level owner) {
    addBoundary(new Boundary(0,height-48,width,height-48));
    addBoundary(new Boundary(-1,0, -1,height));
    addBoundary(new Boundary(width+1,height, width+1,0));
    showBoundaries = true;
    [...]
  }
}

Kedua batas tambahan ini * hanya * di luar level di kiri dan kanan, seperti yang kami lakukan di tutorial sebelumnya untuk menjaga "Thingy" kami di dalam layar. Kecuali kali ini, Thingy kami adalah Mario!

Dan karena kita bisa, mari kita membuat satu perubahan lagi: latar belakang itu bagus, tetapi akan lebih baik lagi jika kita benar-benar bisa melihatnya mengulanginya, dengan membuat tingkat lebih lebar dari satu layar. Jadi ... ayo lakukan itu! 
void initialize() {
  frameRate(30);
  addScreen("level", new MarioLevel(2*width, height));  
}

class MarioLevel extends Level {
  MarioLevel(float levelWidth, float levelHeight) {
    super(levelWidth, levelHeight);
    addLevelLayer("layer", new MarioLayer(this));
    setViewBox(0,0,screenWidth,screenHeight);
  }
}
Dua hal yang perlu diperhatikan adalah bahwa dalam metode initialize kami, kami sekarang membuat MarioLevel yang dua kali lebih lebar dari layar. Untuk memastikan bahwa perpustakaan game tidak bingung, kami kemudian juga mengatakan bahwa viewbox untuk game ini dimulai pada (0,0), yang merupakan kiri atas layar, dan hanya lebar screenWidth , dan screenHeight tinggi, jadi ukurannya persis sama dengan "jendela" permainan kami. Jika kita membiarkannya seperti ini, kita akan melihat Mario berlari ke kanan dan kemudian menghilang, tetapi viewbox adalah spesial: ia bisa mengikuti pemain di sekitarnya. Jadi kami membuat satu perubahan terakhir:
class MarioLayer extends LevelLayer {
  Mario mario;
  MarioLayer(Level owner) {
    mario = new Mario(width/4, height/2);
    addPlayer(mario);
  }
  void draw() {
    super.draw();
    viewbox.track(parent, mario);
  }
}
Kami telah melakukan dua hal di sini. Pertama, kami telah membuat layer level selalu "tahu" apa yang mengacu pada kata mario . Sekarang, jika kita merujuk ke mario di salah satu metode lapisan tingkat, ia akan tahu apa yang harus digunakan. Itu penting, karena viewbox perlu tahu siapa yang harus mengikuti ketika level layer sedang digambar. Itu hal kedua yang kami ubah. Biasanya lapisan tingkat memiliki metode premade yang disebut "gambar" yang semacam "mewarisi" dari perpustakaan permainan. Tapi, itu hanya menarik lapisan level, itu tidak melakukan hal lain. Jika kita ingin membuat viewbox mengikuti Mario, kita perlu mengatur instruksi yang mengatakan "lakukan apa yang biasanya kamu lakukan, tetapi JUGA mengikuti mario!". Jadi itulah yang kami lakukan: super.draw() adalah baris yang mengatakan "lakukan apa yang biasanya Anda lakukan", yaitu memanggil metode "imbang" yang telah diketahui oleh level layer, karena ini adalah bagian dari kelas supernya (ingat super kelas dari tutorial sebelumnya?). Kemudian instruksi berikutnya adalah ke viewbox: viewbox.track(parent, mario) memberitahu viewbox untuk mengikuti mario sekitar, menggunakan properti visual dari level dimana level layer berada, yang level yang diletakan memanggil parent . Setiap kali lapisan level perlu menunjuk ke level kepemilikannya, kita dapat menggunakan kata parent dan perpustakaan permainan akan tahu apa yang harus dilakukan. Apalagi sekarang, itu sangat berguna.
Baik! Cukup! Kami menambahkan latar belakang. Kami menambahkan dinding ke kiri dan kanan. Kami membuat tingkat lebih besar dari layar. Kami (semoga!) Membuat layar "mengikuti" Mario ... apa yang terlihat sudah! ??!
Nah, itulah yang saya sebut keren! Kita bisa berlari dan latar belakang akan bergulir, sampai kita mencapai ujung dari level dan kita hanya berjalan ke dinding samping.
Jadi ... bagaimana kalau kita membuatnya lebih keren?

Game ini membutuhkan ground dan semacamnya!

Kami sudah menundanya cukup lama: membiarkan Mario berjalan di atas garis tipis, tetapi semuanya akan terlihat jauh lebih baik jika kami membuatnya berjalan di tanah yang sebenarnya. Atau setidaknya, jika kita membuatnya TERLIHAT seolah-olah dia. Mari kita mulai menciptakan dasar, ya?
Ground sebenarnya cukup mirip dengan menambahkan latar belakang. Karena satu-satunya hal yang menentukan apakah Mario "pada sesuatu" atau bukan adalah batas-batas yang (biasanya) tidak terlihat (yang bisa kita lihat sekarang karena kita curang dan kita menggambarnya, meskipun biasanya Anda tidak melakukannya), kita sebenarnya dapat meninggalkan batas di mana itu, dan mengatur beberapa latar belakang yang membuatnya terlihat seperti ada tanah di bawah garis batas.
Untuk membuat tanah, kita akan menggunakan beberapa gambar. Dua, sebenarnya. Satu terlihat seperti tanah bagian atas, dengan rumput, dan satu yang mengisi di wilayah di bawahnya:
Caranya adalah dengan meletakkan sebaris tanah bagian atas, dan kemudian isi sisanya dengan filler. Kami sebenarnya sudah melihat bagaimana kami seharusnya melakukan ini: kami menggunakan TilingSprite. Pertama, mari kita definisikan metode untuk "meletakkan" tanah:
class MarioLayer extends LevelLayer {
  void addGround(float x1, float y1, float x2, float y2) {
    Sprite grassy = new Sprite("graphics/backgrounds/ground-top.gif");
    TilingSprite groundline = new TilingSprite(grassy, x1,y1,x2,y1+16);
    addBackgroundSprite(groundline);
    Sprite filler = new Sprite("graphics/backgrounds/ground-filler.gif");
    TilingSprite groundfiller = new TilingSprite(filler, x1,y1+16,x2,y2);
    addBackgroundSprite(groundfiller);
    addBoundary(new Boundary(x1,y1,x2,y1));
  }  
} 
Metode ini mengharapkan empat nilai saat kami menggunakannya: dua yang pertama adalah koordinat x / y kiri atas untuk tanah yang akan kami tempatkan, dan dua terakhir adalah koordinat x / y kanan bawah, jadi kami seharusnya menggambar tanah di persegi panjang antara dua koordinat tersebut. Baris paling atas harus berupa tanah berumput, jadi kami menggunakan gambar berumput, dan membuat TilingSprite yang berjalan dari (x1, y1), yang merupakan sudut kiri atas kami, ke (x2, y1 + 16).
Apa arti nilai-nilai itu? Nah, x2 adalah koordinat horizontal untuk tepi paling kanan dari persegi panjang yang ingin kita isi. Jadi itu cukup mudah. "y1 + 16" berarti "nilai koordinat teratas, plus 16 piksel". Kami menambahkan 16 piksel karena kami tahu gambar untuk rumput adalah 16 piksel tinggi. Jadi kami ingin menggambar deretan rumput yang dimulai pada (0,0) dan tepat 16 piksel tinggi, dan lebar lebarnya normal.
Setelah itu, kita isi sisanya dengan gambar pengisi. Ini tidak dimulai pada (
x1, y1), tetapi pada (x1, y1 + 16), karena kita perlu memulai pada posisi horizontal yang sama, tetapi 16 piksel lebih rendah (atau kita akan menggambar pengisi di atas rumput !). Dan kemudian harus cukup lebar untuk mencapai x2, secara horizontal, dan cukup tinggi untuk mencapai y2, secara vertikal.
Akhirnya, karena tanah berfungsi sebagai sesuatu yang dapat dilakukan Mario, kami menambahkan batas yang membentang di atas rumput, sehingga Mario memiliki sesuatu untuk berdiri. Dan dengan itu, kami menambahkan beberapa tanah ke lapisan tingkat kami:
class MarioLayer extends LevelLayer {
 MarioLayer(Level owner) {
   addGround(-32,height-48, width+32,height);
  }
}
Sekarang kita akan memiliki tanah berjalan di layar, dari 32 piksel "di luar" layar di sebelah kiri, hingga 32 piksel "di luar" layar di sebelah kanan, mengisi area dengan ketinggian "tinggi layar, minus 48 piksel" ke "ketinggian layar". Seperti apa bentuknya? Nah, ini:
Apa bedanya beberapa hal yang bisa dibuat oleh tanah!
Ada hal lain yang bisa kita lakukan yang juga membuat perbedaan yang rapi, dan itu menambahkan lapisan kedua latar belakang yang terlihat lebih jauh, sehingga ketika kita berjalan, ia bergerak lebih lambat daripada latar belakang normal.

Parallax, atau "jarak pura-pura"

Kita dapat menambahkan "paralaks", atau konsep jarak berpura-pura dengan mengelabui mata agar percaya bahwa ada jarak dengan membuat hal-hal yang seharusnya terlihat "dekat" bergerak cepat dan hal-hal yang seharusnya "jauh" memindahkan slolwy, dengan menambahkan lapisan baru ke tingkat kita . Kita akan membuatnya terlihat seperti kita memiliki lebih banyak latar di kejauhan, jadi kita akan menambahkan layer baru di belakang lapisan utama yang memiliki Mario di atasnya. Sebenarnya, kode untuk itu tidak terlalu panjang, dapatkah Anda tahu apa yang dilakukannya?
 class MarioLevel extends Level {
  MarioLevel(float levelWidth, float levelHeight) {
    addLevelLayer("background", new BackgroundLayer(this));
    addLevelLayer("layer", new MarioLayer(this));
  }
}

class BackgroundLayer extends LevelLayer {
  BackgroundLayer(Level owner) {
    super(owner, owner.width, owner.height, 0, 0, 0.75, 0.75);
    setBackgroundColor(color(0, 100, 190));
    addBackgroundSprite(new TilingSprite(new Sprite("graphics/backgrounds/sky_2.gif"),0,0,width,height));
  }
}
class MarioLayer extends LevelLayer {
  Mario mario;
  MarioLayer(Level owner) {
    super(owner);
    // we no longer have a background color in the main level layer now
    addBackgroundSprite(new TilingSprite(new Sprite("graphics/backgrounds/sky.gif"),0,0,width,height));
  }
}

Bagian yang penting adalah kelas BackgroundLayer baru, yang melakukan sesuatu yang istimewa. Tidak seperti lapisan normal, seperti MarioLayer , BackgroundLayer memiliki panggilan yang lebih rumit untuk memberi tahu kelas supernya apa yang ada: ia memberinya tujuh nilai, bukan satu! Nilai pertama sama dengan layer normal: Level yang harus dimasukkan lapisan ini. Sejauh ini bagus. Kemudian, ia memberitahukan apa itu lebar dan tinggi badan itu. Ini penting, karena itu diperlukan untuk melakukan sesuatu yang cerdas dengan empat nilai berikut: dua yang pertama adalah nilai "bergeser", yang mari kita katakan dengan seberapa banyak lapisan ini bergeser ke kiri atau kanan, serta naik atau turun. Kami tidak menginginkan itu sekarang, jadi kami menjaga keduanya nol. Kemudian, dua nilai setelah itu memberi tahu layer dengan seberapa banyak diskalakan. Ini sangat penting! Agar terlihat seperti lapisan ini lebih jauh, kami ingin itu bergerak lebih lambat dari lapisan tingkat utama dengan Mario di dalamnya. Karena kami tidak dapat memberi tahu lapisan seberapa cepat mereka harus bergerak, kami malah mengatakan kepada mereka bahwa mereka lebih besar atau lebih kecil dari tingkat utama. Ini membuat permainan perpustakaan labu atau meregangkan tingkat, sehingga awal dan akhir cocok - jika kita menambahkan lapisan yang lebih besar dari lapisan utama, itu akan terjepit, dan itu akan terlihat seperti itu bergulir lebih cepat daripada lapisan utama. Dan tentu saja sebaliknya; jika kita menambahkan lapisan yang lebih kecil, itu akan peregangan, dan akan terlihat seperti itu bergulir lebih lambat. Jadi itulah yang kami lakukan, kami katakan bahwa layer latar belakang baru ini hanya 0,75 ukuran lapisan utama. Jadi seharusnya bergulir lebih lambat. Mari kita cari tahu: 

silakan, buat Mario berlari ke kanan. Perhatikan bagaimana latar belakang baru kami bergerak lebih lambat daripada yang sudah kami miliki sebelumnya? Apakah itu membuatnya terlihat seperti latar belakang baru ini lebih jauh? Keren, ya?
Sekarang kami memiliki awal yang bagus untuk permainan nyata: kami memiliki Mario, kami memiliki latar belakang yang keren, dan kami memiliki beberapa landasan untuk dijalankan. Saat mulai menambahkan sentuhan akhir, apa yang Anda katakan?

Mari tambahkan beberapa elemen platforming

Biasanya, "platformer" seperti game yang kami buat disebut, memiliki "platform" yang dapat Anda lewati, dan dari. Tentu saja, game kami tidak memiliki ini ... belum! Tapi kita bisa menambahkannya dengan mudah dengan menggunakan ide yang sama seperti sebelumnya: bagian dari platform yang dapat kita berdiri akan diwakili oleh batas, dan yang lainnya hanya akan menjadi gambar backgroud, tentu saja ditempatkan sehingga terlihat seperti ada platform. Kami akan menambahkan dua jenis: platform miring, dan platform lurus.
Untuk kemiringannya, kami akan menggunakan satu gambar, dan kodenya cukup sederhana:

class MarioLayer extends LevelLayer {
  MarioLayer(Level owner) {
   
    // add a few slanted hills
    addSlant(256, height-48);
    addSlant(1300, height-48);
    addSlant(1350, height-48);
  }
  
  void addSlant(float x, float y) {
    Sprite groundslant = new Sprite("graphics/backgrounds/ground-slant.gif");
    groundslant.align(LEFT, BOTTOM);
    groundslant.setPosition(x, y);
    addBackgroundSprite(groundslant);
    addBoundary(new Boundary(x, y + 48 - groundslant.height, x + 48, y - groundslant.height));
  }
}
Untuk platform horizontal kita akan memasukkan sedikit lebih banyak pekerjaan, menggunakan trik yang sama yang kita gunakan untuk tanah biasa: jika kita memperlakukannya sebagai enam gambar (tiga untuk tanah teratas, dan tiga untuk pengisi di bawahnya) kemudian kita dapat membuat platform berukuran apa saja dengan selalu menggambar sudut kiri dan kanan atas, dan sudut kiri dan kanan bawah, dan kemudian "mengisi ruang di antara mereka" dengan bit yang masuk di tengah:
class MarioLayer extends LevelLayer {
  MarioLayer(Level owner) {

    // add some ground platforms    
    addGroundPlatform(928, height-224, 96, 112);
    addGroundPlatform(920, height-176, 32, 64);
    addGroundPlatform(912, height-128, 128, 80);
    addGroundPlatform(976, height-96, 128, 48);
    addGroundPlatform(1442, height-128, 128, 80);
    addGroundPlatform(1442+64, height-96, 128, 48);  
  }

  void addGroundPlatform(float x, float y, float w, float h) {
    // create our top soil layer
    Sprite lc = new Sprite("graphics/backgrounds/"+tileset+"-corner-left.gif");
    lc.align(LEFT, TOP);
    lc.setPosition(x, y);
    Sprite tp = new Sprite("graphics/backgrounds/ground-top.gif");
    Sprite rc = new Sprite("graphics/backgrounds/ground-corner-right.gif");

    rc.align(LEFT, TOP);
    rc.setPosition(x+w-rc.width, y);

    TilingSprite toprow = new TilingSprite(tp, x+lc.width, y, x+(w-rc.width), y+tp.height);
    addBackgroundSprite(lc);
    addBackgroundSprite(toprow);
    addBackgroundSprite(rc);

    // sides/filler
    TilingSprite sideleft  = new TilingSprite(new Sprite("graphics/backgrounds/ground-side-left.gif"),


                                              x,            y+tp.height, x+lc.width,     y+h);

    TilingSprite filler    = new TilingSprite(new Sprite("graphics/backgrounds/ground-filler.gif"),


                                              x+lc.width,   y+tp.height, x+(w-rc.width), y+h);
    TilingSprite sideright = new TilingSprite(new Sprite("graphics/backgrounds/ground-side-right.gif"),


                                              x+w-rc.width, y+tp.height, x+w,            y+h);
    addBackgroundSprite(sideleft);
    addBackgroundSprite(filler);
    addBackgroundSprite(sideright);

    // boundary to walk on
    addBoundary(new Boundary(x, y, x+w, y));
  }
}
Anda mungkin bertanya-tanya apa itu lc.align(LEFT, TOP); tidak. Secara default, sprite ditempatkan dengan titik pusatnya di mana pun Anda memberi tahu mereka untuk ditempatkan. Jika kita memanggil setPosition(0,0) dan sprite adalah gambar 16 dengan 16 piksel, maka 8 piksel akan berada di sebelah kiri (0,0), 8 akan berada di sebelah kanan, 8 di atas, dan 8 di bawah. Kadang-kadang, itu tidak berguna sama sekali, dan Anda ingin mengubah itu sehingga jika Anda meletakkan gambar di (0,0), seluruh gambar ke kiri, kanan, atas atau bawah koordinat itu. Dalam kasus tersebut, kita dapat menggunakan align(...,...) untuk mengubah penempatan default. Dalam hal ini, kita ingin sisi kiri gambar, dan atas, untuk disejajarkan dengan koordinat yang kita berikan setPosition - setPosition , jadi kita katakan align(LEFT,TOP) (kita harus mengatakannya bagaimana melakukan horizontal align pertama, dan kemudian vertical meluruskan).
Jadi, tidak terlalu rumit kode, hanya "banyak" untuk membuat sesuatu yang benar-benar berguna terjadi: Setelah kita mendefinisikan fungsi addGroundPlatform kita dapat memanggilnya sebanyak yang kita suka
untuk menambahkan platform ke tingkat kita. Dalam kode di atas, kami menambahkan enam platform, dan kemudian sedikit di atas bahwa kami menambahkan tiga platform miring, jadi ... seperti apa tampilannya? 

Itu lebih seperti itu! Sekarang kami mulai membuat game nyata. Tentu saja, masih ada barang yang hilang. Kami ingin harta, dan musuh, dan cara untuk menang. Setidaknya. Jadi mari kita mulai menambahkan hal-hal itu di akan kita?

Untuk melihat full source code nya klink link berikut HERE

Comments

Post a Comment