Tuesday, 26 October 2010

Kapal Luar Angkasa v0.2 (2)

Tulisan ini merupakan lanjutan dari:
Kapal Luar Angkasa v0.2 (1)

Gambar 1. Aku siap untuk berperang.

Animasi


Animasi dapat berupa pengambaran satu demi satu gambar yang berbeda sehingga membentuk sebuah gerakan, dapat juga berupa pergerakan posisi dari kiri ke kanan, atas ke bawah atau sebagainya. Tapi yang kumaksud animasi disini adalah perubahan gambar demi gambar, atau yang biasa disebut "frame by frame". Untuk penggambarannya, yang pasti jangan terlalu terpaku apalagi meniru saya dalam menggambar karakter di dalam game ini . Mungkin menggambar dengan membuat sketsa di kertas dapat menghasilkan gambar yang lebih baik . Perhatikan kedua kelas berikut:


...
#define ADDFRAME    0.3

...
class kapal
{
 ...
    int power, jenisPEL;
    float kecX, kecY, animasi;

 public:
 ...
};

class musuh
{
 ...
    float kecY, Y, animasi;
    bool aktif, dmg, hancur, forUfo;

    public:
 ...
};

...
void kapal::tampil()
{
    animasi+= ADDFRAME;
    if( animasi > = MAX_ANIMASI) animasi=0;

    terapinGbr(kotak.x-10, kotak.y-10, gbrKapal, screen, & cKapal[(int)(animasi)]);
}

...

void musuh::deArmor(int _dmg)
{
    //decrease armor, dmg = damage
    armor -= _dmg;
    dmg = true;
}

void musuh::tampil()
{
    animasi += ADDFRAME;
    if( !hancur){
        if( animasi > = MAX_ANIMASI) animasi = 0;
        terapinGbr(kotak.x-10,kotak.y-10, gambar, screen, & cKapal[(int)animasi]);
        if( dmg){
            terapinGbr(kotak.x-10,kotak.y-10,gbrMusuh_dmg,screen, & cKapal[tipe]);
            dmg = false;
        }
    }
    else{
        if( animasi > = MAX_ANIMASI) aktif = false;
        else terapinGbr(kotak.x-10,kotak.y-10, gbrMeledak01, screen, & cKapal[(int)animasi]);
    }
}
...

Kedua kelas tersebut memiliki variabel dengan nama animasi, tentu kita tahu fungsinya. Untuk tipe datanya sendiri kita gunakan float, bukan bilangan bulat (int). Karena penambahan frame-nya menggunakan bilangan riil (ADDFRAME = 0.3) agar mempermudah perhitungan. Ini karena kita hanya mempunyai 3 gambar/frame animasi, jika kita menambahkannya sebanyak 1 atau setiap framenya berganti-ganti gambar maka program kita akan terlihat seperti terburu-buru. Kita bisa saja menggubahnya menjadi int, lalu menampilkan dengan membaginya terlebih dahulu seperti berikut:


    animasi++; //jika bertipe 'int animasi'
    if( animasi > = (5*MAX_ANIMASI)) animasi=0;

    terapinGbr(kotak.x-10, kotak.y-10, gbrKapal, screen, & cKapal[(animasi/5)]);

Hasilnya akan sama, hanya saja pergerakan animasi dengan cara diatas (dengan int) akan terlihat lebih lambat. Ini karena pergantian gambar setiap 5 frame game (dalam game terdapat 22 frame per detiknya), berbeda dengan sebelumnya yang berkisar pada 3-4 frame (ADDRAME = 0.3). Jika kita perhatikan yang ditampilkan di layar adalah surface yang sesungguhnya memiliki 3 gambar. Lalu bagaimana agar ketiga gambar tersebut ditampilkan satu-persatu sesuai nilai frame animasi yang ada. Yaitu dengan memasukkan parameter kelima dalam fungsi terapinGbr(). Yang jika kita telusuri lagi fungsi terapinGbr() maka parameter kelima akan masuk ke fungsi SDL, yaitu SDL_BlitSurface().

Tentu tidak semudah itu kita mengisi parameter kelima ini, yang perlukan adalah SDL_Rect berpointer/beralamat. Untuk apa SDL_Rect? Dan bagaimana cara kerjanya? SDL_Rect ini berfungsi untuk mengambil bagian dari gambar dan cara kerjanya sederhana yaitu membuat sebuah luas dengan koordinat berdasarkan nilai-nilai member SDL_Rect. Member x dan y untuk memulai pengambilan koordinat pada gambar, dan member w (lebar) dan h (tinggi) untuk menggambil luas dari koordinat yang telah ditetapkan (x,y). Pengambilan gambar ini biasa disebut dengan 'clip', dan pada program kita ini terdapat pada fungsi 'void setClip()':


...

SDL_Rect cKapal[3]; //clip untuk animasi kapal
SDL_Rect cPeluru[2]; //clip untuk peluru

const int PEL_NORMAL = 0;
const int PEL_KECIL = 1;

void setClip()
{
    cPeluru[PEL_NORMAL].x = 0;
    cPeluru[PEL_NORMAL].y = 0;
    cPeluru[PEL_NORMAL].w = 20;
    cPeluru[PEL_NORMAL].h = 20;

    cPeluru[PEL_KECIL].x = 20;
    cPeluru[PEL_KECIL].y = 0;
    cPeluru[PEL_KECIL].w = 10;
    cPeluru[PEL_KECIL].h = 10;

    for( int c=0;c < MAX_ANIMASI;c++){
        cKapal[c].x = c*60;
        cKapal[c].y = 0;
        cKapal[c].w = 60;
        cKapal[c].h = 60;
    }
}
...

Fungsi dari kode diatas akan tampak seperti gambar berikut:

Gambar 2. Potong tiga.

Bagaimana dengan penggambaran (void tampil()) si musuh? Khusus untuk mereka kita menambahkan variabel boolean hancur dan dmg. Jika musuh tertembak maka jumlah armornya akan berkurang sesuai jumlah damage (lihat fungsi 'void musuh::deArmor(int _dmg)). Jika musuh masih memiliki armor (atau masih hidup) setelah tertembak maka akan tampil sekilas efek kerusakan berupa cahaya merah (lihat pengecekan variabel (var) boolean dmg). Begitu juga dengan var hancur, berfungsi untuk menghasilkan efek ledakan jika armor musuh sudah habis. Kita juga dapat membuat var hancur untuk kapal jagoan, karena pada game ini belum ada. Hanya akan muncul status Game Over jika telah terjadi tabrakan dengan musuh atau peluru musuh. Hmm ngomong-ngomong soal peluru, selanjutnya kita akan bahas tentang peluru ini .

- krofz

Thursday, 21 October 2010

Kapal Luar Angkasa v0.2 (1)

Gambar 1. Kapal Luar Angkasa v0.2

Ya, versi kedua ini telah keluar . Yang pastinya (harus) banyak perubahan dari versi sebelumnya (Kapal Luar Angkasa v0.1). Apa saja perubahannya? Silahkan download terlebih dahulu program dan source codenya:

Link : http://www.mediafire.com/?gd6sd89wr1m9gsg
Size : 705 KB
IDE : Code::Blocks v8
Attention : add #include < ctime > , if srand not recognized.

Main Menu, Class dan Constructor

Gambar 2. Click Play Game.
Jika pada versi sebelumnya, saat kita menjalankan program (game) langsung dihadapkan dengan pemusnahan kapal-kapal musuh (yang nggak ada habisnya). Sekarang ada tombol-tombol untuk memilih bagian-bagian mana saja yang akan kita kunjungi (dan mampir sebentar untuk meminum segelas teh/kopi), yang biasa disebut "Main Menu". Saat ini hanya ada dua tombol, yaitu tombol untuk memulai permainan, dan untuk keluar dari permainan. Tombol-tombol ini tentu bisa kita tambah dengan mudah dengan adanya kelas tombol (class tombol):


class tombol
{
    SDL_Rect kotak;

    public:
    tombol(int,int);
    void diklik(int,int,int);
    void tbl_tampil(std::string); //tbl = tombol
};
SDL_Rect kotak, berfungsi untuk menempatkan koordinat objek tombol pada layar (screen). Selain itu merupakan bagian terpenting karena untuk memeriksa apakah tombol kiri mouse tertekan diatas objek tombol ini atau tidak. SDL_Rect memang banyak gunanya hehehe... (lihat Segitiga dari SDL_Rect, oups Segitiga dari Kotak). Untuk tombol(int,int) merupakan konstruktor (Constructor) dengan 2 parameter bertipe int. Sedangkan kata kunci public adalah pemberian hak atau akses untuk variabel, fungsi atau member lainnya pada kelas, yang berarti nilainya dapat digunakan oleh objek lain diluar kelas ini. Jika kita tidak menetapkan haknya (misal public) maka secara otomatis hak yang dimiliki adalah private dan hanya dapat digunakan oleh member pada kelas yang sama. Sedangkan konstruktor dipanggil secara otomatis, jika pada contoh diatas memiliki 2 parameter.

Maka saat kita membuat objek dengan kelas tombol kita hanya perlu memasukkan nilai untuk parameternya, jika tidak maka akan terjadi error saat proses build. Kecuali jika kelas tombol memiliki konstruktor tanpa parameter. Konstruktor berguna untuk menginisialisasi nilai-nilai pada member (variabel) pada kelas. Satu kelas dapat memiliki beberapa konstruktor dengan parameter yang berbeda-beda, seperti kode berikut:

#include <iostream>

using namespace std;

class A{
    int x;
    char y;
    public:
    A();
    A(int);
    A(char);
    void show();
};

//Konstruktor pertama
A::A(){
    x = 15;
    y = 'A';
}

//Konstruktor kedua
A::A(int _X){
    x = _X;
    y = 'B';
}

//Konstruktor ketiga
A::A(char _y){
    x = 10;
    y = _y;
}

void A::show(){
    cout<<x<<" dan "<<y<<endl;
}

int main(){
    A a, b(16), c('K');
    a.show();
    b.show();
    c.show();
    return 0;
}

//maaf untuk penamaan variabelnya...
Dapat dilihat pada fungsi main, untuk objek a tidak diberi parameter apapun maka konstruktor yang akan dipanggil adalah konstruktor pertama. Untuk objek b dan c sama-sama memanggil konstruktor dengan parameter, hanya saja konstruktor yang akan dipilih akan disesuaikan dengan data yang dimasukkan.


GameStatus

Jika pada awal program dibuka kita dihadapkan dengan Main Menu, maka pada source code saat memasuki main loop kita disuguhi oleh Game Status. Bagian ini akan mempermudah kita dalam memproses, menampilkan bahkan mencari masalah (Bug) pada program kita. Misal ketika kita berada pada "case GS_PLAYGAME:" maka yang diproses dan ditampilkan adalah kapal jagoan, kapal musuh, peluru dan objek-objek yang diperlukan saja. Jika sewaktu-waktu program crash pada bagian ini (saat bermain), maka pencarian dapat dimulai dari sini (GS_PLAYGAME). Seperti layer pada program Photoshop, yang memudahkan kita mengedit foto-foto.

Sementara itu saja dulu, kita akan ungkap semuanya nanti hehehe...

- krofz

Next Part : Kapal Luar Angkasa v0.2 (2)
Update: 14 Desember 2012, 18 April 2013 (add some instruction)
 

back to top

back to top