Rabu, 09 Juli 2014

Tugas Membuat Game Processing Softskill


Assalamualaikum Wr.Wb
      perkenalkan kami adalah developer game indie yang sedang belajar, kami akan mengerjakan sebuah tugas softskill membuat game, software yang kami pakai adalah processing.

Nama kelompok :
 Ardian Aruhil Kahfi (51411051)
 Junaidi Akbar (53411886)
 Raffael Eko Prayogo (55411743)

RANCANGAN PROGRAM

1.1.            Rancangan Aplikasi

Dalam aplikasi ini Storyboard menerangkan tentang perjalanan user dalam menggunakan aplikasi adalah sebagai berikut :





Pada Storyboard di atas, ketika user membuka aplikasi Castle Deffense ini, makan tampilan yang akan muncul pertama kali adalah splash screen. Kemudian setelah itu user akan masuk ke halaman menu utama. Pada menu utama terdapat petunjuk untuk memainkan game Castle Deffence dan terdapat satu button untuk memulai permainan. Setelah kita klik button mainkan maka user akan masuk ke halaman game permainan Castle Deffense.

Rancangan Splash Screen


3.3.            Rancangan Menu Utama


     Pada rancangan menu utama Castle Deffense, terdiri dari gambar yang berupa ilustrasi dari suasana permainan. Kemudian di sebelas kanan atas terdapat petunjuk permainan Castle Deffense dan di kanan bawah terdapat button mainkan untuk masuk ke halaman permainan.  

3.3.            Rancangan Halaman Permainan


Pada rancangan halaman permainan, terdiri dari tampilan game Castle Deffense itu sendiri.Pada bagian atas layar akan menampilkan uang, nyawa dan score yang pemain miliki. Dan pada bagian kanan bawah layar terdapat satu button yaitu button start untuk memulai permainan.

3.3.            Implementasi Permainan

·         Cara Bermain Castle Deffence
Buka game Castle Deffence, kemudian yang pertama kali ketika kita membuka game tersebut akan muncul splash screen Castle Deffence. Setelah itu pemain akan memasuki menu utama dari game Castle Deffence yang terdiri dari ilustrasi gambar, petunjuk permainan dan button mainkan untuk masuk ke halaman permainan.
Setelah memasukin halaman permainan, atur strategi untuk meletakkan Pasukan Mario mu di tempat yang strategis untuk membunuh para monster. Untuk awal permainan, pemain diberikan dua buah Pasukan Mario. Jika sudah mengatur posisi dua buah Pasukan Mario, klik button start yang berada di kanan bawah layar untuk memulai permainan.
Pada level awal permainan, monster yang harus dimusnakan adalah 4 ekor.
Nilai uang yang akan pemain dapatkan jika berhasil membunuh satu monster adalah 60. Jika pemain berhasil mengumpulkan uang sebanyak 250 maka pemain bisa menambah satu buah Pasukan Mario, sehingga jumlah Pasukan Mario yang dimilki pemain menjadi 3 dan begitu seterusnya.
Pemain akan game over jika jumlah monster yang lolos dari tembakan peletok gun berjumlah 10 ekor.

·         Layout Program

Tampilan Splash Screen

Tampilan Menu Utama

Tampilan Halaman Permainan

Tampilan Game Over


Coding untuk membuat game "Castle Deffense" :

Tower_defence :

/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/6459*@* */
/* !do not delete the line above, required for linking your tweak if you upload again */
  
  ArrayList towers;
  ArrayList squares;
  int fr = 0;
  int dualtimer = 0;
  PImage path, desa, titlepage, instructions;
  int MONEY = 700;
  int LIVES = 10;
  int SCORE = 0; 
  
  
  
  int cols = 16;
  int rows = 12;
  int gridAccess [][] = new int[cols][rows];
  
  int jmlbuaya = 4;
  int buayaHealth = 100;
  
  int maptestX, maptestY;
  int placeX, placeY;
  
  Button[] b = new Button[192];
  
  boolean play = false;
  boolean end = false;
  boolean intro = false;
  int timer = 0;
  boolean title = true;
  
  PFont file;
  
  void setup () {
    size(640,480);
    cursor(CROSS);
    rectMode(CENTER);
    imageMode(CENTER);
    smooth();
    frameRate(30);
  
    file = loadFont("File-24.vlw");
    textFont(file);
    textAlign(CENTER);
  
    path = loadImage("basicPath1.png");
    desa = loadImage("desa.png");
    titlepage = loadImage("titlepage.png");
    instructions = loadImage("instructions.png");
  
    for(int h = 0; h< 192; h++) {
      b[h] = new Button();
    }
    
    int u = 0;                                            //Sets up grid ID number
      for (int v = 0; v < rows; v++) {
        for (int w = 0; w < cols; w++) {
          gridAccess[w][v] = u;
          u++;
        } 
      }
  
  
    towers = new ArrayList();
    squares = new ArrayList();
  
  } 
  
  
  void draw () {
    
    maptestX = int(map(mouseX,0,640,0,16));
    maptestY = int(map(mouseY,0,480,0,12));
    
    if(title) {
      dualtimer++;
      if(dualtimer <= 120) {
        image(titlepage,width/2,height/2);
      }
      else {
       title = false;
       intro = true;
       dualtimer = 0;
      }
    }
    
    if(intro) {
      image(instructions,width/2,height/2+1);
      fill(100);
      rect(540,460,120,40); // start
      //rect(500,290,120,40); // start
      //rect(500,340,120,40);
      //rect(500,390,120,40);
      fill(255);
      text("Mainkan", 540, 470);
      //text("Mainkan", 500, 300);
      //text("Petunjuk", 500, 350);
      //text("About", 500, 400);
    }
      
    if(!title && !intro) {
      dualtimer++;
      pushMatrix();
      translate(width/2,height/2);
      image(desa,20,0);
      popMatrix();
      image(path,319,239);
    
      int button_number = 0;
      for(int i = 0; i < 12; i++) {
        for(int j = 0; j < 16; j++) {
          b[button_number].button_display((20+(j*40)),(20+(i*40)));
          button_number++;     
        }
      }
    
      fill(100);
      rect(540,460,120,40); // start
      fill(255);
      if(!play || !end) {
        text("START", 540, 470);
      }
      if (play) {
        fill(#278AA8,150);
        rect(540,460,120,40);
      }
      fill(0);
      String score = "SCORE: " + " " + nf(SCORE,8);
      text(score,500,30);
      String money = "UANG: " + " " + nf(MONEY,4) + " rupiah";  
      text(money, 140, 30);
      String lives = "LIVES: " + " " + nf(LIVES,2);
      text(lives, 325, 30);
    }
    
    if(play) {
      fr++;
      if(fr == 25) {
        squares.add(new Square(buayaHealth));
        if(squares.size() < jmlbuaya) {
          fr = 0;
        }
        if(squares.size() == jmlbuaya) {
          fr = 30;
        }
      }
  
      for(int j=0; j<squares.size(); j++) {
        if(squares.size()>0)
          ((Square)squares.get(j)).squareDisplay();
      }
  
      if(squares.size() == 0) {
        timer++;
        if(timer == 120) {
          fr = 0;
          buayaHealth += 35;
          jmlbuaya += 1;
          timer = 0;
        }
      }
    }
  
    if(LIVES == 0) {
      play = false;
      end = true;
    }
  
  
    for(int i=0; i<towers.size(); i++) {
  
      ((Tower)towers.get(i)).tower_display(); 
      ((Tower)towers.get(i)).shoot(); 
    }
  
    if(end) {
      for(int z = 0; z<towers.size(); z++) {
        towers.remove(z);
      }
      lose();
    }
  }
  
  
  void mousePressed() {
    
    if(intro) {
      if((mouseX >= 480 && mouseX <= 600) && (mouseY >= 425 && mouseY <= 465)) {
        intro = false;
        dualtimer = 0;
      }
    }
  
    if(!play && !intro) {
      if((mouseX >= 480 && mouseX <= 600) && (mouseY >= 425 && mouseY <= 465)) {
        if(dualtimer > 1)
          play = true;
      } 
    }
  
    if(!end && !intro && !title) {
      if((mouseX <= 480) || (mouseX> 600) || ((mouseX >= 480 && mouseX <= 600) && mouseY >= 465) || ((mouseX >= 480 && mouseX <= 600) && mouseY <= 425)) {
        if(MONEY >= 250) {
          placeX = current_buttonX(maptestX,maptestY);
          placeY = current_buttonY(maptestX,maptestY);
          towers.add(new Tower(placeX, placeY));
          MONEY -= 250;
        }    
      }
    }
  }
  
  
  int current_buttonX (int x, int y) {
   int xpos = 0;
   int buttonChoice = gridAccess[x][y];
   xpos = b[buttonChoice].rectX;
   return xpos;  
  }
  
  int current_buttonY (int x, int y) {
   int ypos = 0;
   int buttonChoice = gridAccess[x][y];
   ypos = b[buttonChoice].rectY;
   return ypos;  
  }
  
  void lose() {
    fill(255);
    text("GAME OVER", width/2, height/2);
    text("SCORE: " + SCORE, width/2, height/2 + 40);
    keyPressed();
  }
  
  void keyPressed(){
    if (key == ' ') {
    reset();
    }
  }
  
  void reset(){
    intro = true;
    play = false;
    end = false;
    timer = 0;
    fr = 0;
    dualtimer = 0;
    MONEY = 700;
    LIVES = 10;
    SCORE = 0; 
    jmlbuaya = 4;
    buayaHealth = 100;
  }

Amo :

class Amo {
  PVector loc = new PVector();
  Tower t;
  int time = 0;
  PVector center;
  PVector turret;
  float dirX, dirY;
  PImage bullet;

  Amo (float x, float y) {
    loc.x = x;
    loc.y = y;
    turret = new PVector(loc.x, loc.y);
    bullet = loadImage("bullet.png");
  }

  void run(float a, float b) {
    dirX = a;
    dirY = b;
    center = new PVector(dirX, dirY);
    image(bullet,loc.x,loc.y);
    PVector velocity = PVector.sub(center,turret);
    loc.add(new PVector(velocity.x/2, velocity.y/2));
  }
}

Grid :


  class Button {
  
    int rectX = 0;
    int rectY = 0;
    int testX, testY;
    int rectSize = 40; 
    color rectColor,  baseColor;
    color rectHighlight;
    color rectRed;
    color currentColor;
    boolean rectOver = false;
    boolean rectOn = false;
  
    Button() {
      rectHighlight = color(175,100);
      rectRed = color(#278AA8,25);
      baseColor = color(102);
      currentColor = rectRed;
    }
  
    void button_display (int x, int y) {
      rectX = x;
      rectY = y;
      rectColor = color(currentColor);
  
      update(mouseX,mouseY);
      testX = posX(mouseX,mouseY);
      testY = posY(mouseX,mouseY);
  
      if (rectOn) {
        fill (rectRed);
      }
      else if (rectOver) {
        fill(rectHighlight);
      } 
      else {
        fill (rectColor);
      }
      
      stroke(255,10);
      rect(rectX, rectY, rectSize, rectSize);
    }
  
    void update (int x, int y) {
      
      if (overRect(rectX, rectY, rectSize, rectSize)) {
        rectOver = true;
      } 
      else {
        rectOver = false;
      }
      
      if (mousePressed && rectOver) {
        rectOn = true;
      }
      else {
        rectOn = false;
      }
    }
    
   int posX (int x, int y) {
      int a = 0;
      if (mousePressed && rectOn) {
        a = rectX;
      } 
      return a;
    }
    
    int posY (int x, int y) {
      int a = 0;
      if (mousePressed && rectOn) {
        a = rectY;
      } 
      return a;
    }

    boolean overRect (int x, int y, int width, int height) 
    {
      if (mouseX >= x-20 && mouseX <= x+20 && mouseY >= y-20 && mouseY <= y+20) {
        return true;
      } 
      else {
        return false;
      }
    }  
  }

Squere :

class Square {

  float xpos = -5;
  float ypos = 100;
  int speed = 2;
  int health;
  PImage see;

  Square (int HEALTH) {
    health = HEALTH;
    see = loadImage("see_enemy.png");
  }

  void hurt() {
    health -= 3;
  }

  void squareDisplay() {

    if (xpos < 100) {
      xpos += speed;
    }

    else if (ypos < 300 && xpos < 260) {
      ypos += speed;
    }

    else if (xpos < 260) {
      xpos += speed;
    }

    else if (ypos > 100 && ypos < 350 && xpos < 300) {
      ypos -= speed;
    }

    else if (xpos < 380) {
      xpos += speed;
    }

    else if (ypos < 380 && xpos < 450) {
      ypos += speed;
    }

    else if (xpos < 460 && ypos > 370) {
      xpos += speed;
    }

    else if (xpos > 450 && xpos < 470 && ypos <= 380 && ypos > 220) {
      ypos -= speed;
    }

    else
      xpos += speed;

    pushMatrix();
    translate(xpos,ypos);
    image(see,0,0,60,75);
    popMatrix();

    if(xpos > width + 25) {
      LIVES -= 1;
      squares.remove(this);
    }

    if (health < 0) {
      squares.remove(this);
      SCORE += (100 + int(SCORE*.07));
      MONEY += 60;
    }
  }
}

Tower :


class Tower {

  ArrayList amos;
  PVector location = new PVector();
  float r = 40;
  float aX = r;
  float aY = r;
  int radius = 100;
  int Tfr = 0;
  int inReach = 160;
  PImage towerbase, towereye;


  float angle;

  Tower (float x, float y) {
    location.x = x;
    location.y = y;
    amos = new ArrayList(); 
    towerbase = loadImage("towerbase.png");
    towereye = loadImage("towereye.png");
  }

  void tower_display() {
    for (int i=0; i < squares.size(); i++) {
      if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos,location.x,location.y) < inReach) {        
        angle = atan2((((Square)squares.get(0)).ypos)-location.y, (((Square)squares.get(0)).xpos)-location.x);
        aX = (r * cos(angle)) + location.x;
        aY = (r * sin(angle)) + location.y;
      }
    }

    image(towerbase,location.x,location.y);
    pushMatrix();
    translate(location.x,location.y+1);
    rotate(angle+PI-PI/13);  
    image(towereye,0,0);
    popMatrix();


  }

  void shoot() {

    if(squares.size()>0) {
      if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos,location.x,location.y) < inReach) {
        Tfr++;
        if(Tfr == 5){
          amos.add(new Amo(location.x,location.y));  
          Tfr = 0;
        }
      }

      for(int k=0; k<amos.size(); k++) {

        image(towerbase,location.x,location.y);
        ((Amo)amos.get(k)).run(aX, aY);
        pushMatrix();
        translate(location.x,location.y+1);
        rotate(angle+PI-PI/13);  
        image(towereye,0,0);
        popMatrix();


        if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos, ((Amo)amos.get(k)).loc.x, ((Amo)amos.get(k)).loc.y) < 25) {
          amos.remove(k);
          ((Square)squares.get(0)).hurt();
        }
        else if(((Amo)amos.get(k)).loc.x > width || ((Amo)amos.get(k)).loc.x < 0 || ((Amo)amos.get(k)).loc.y > height || ((Amo)amos.get(k)).loc.y < 0) {
          amos.remove(k);
        }
      }
    }
  }
  
  
  
}


Selanjunya untuk melihat game Castle Deffense ini dapat diakses pada link berikut ini :