Rabu, 23 Juli 2014

Tugas Softskill Membuat Game dengan Processing

Coding untuk Keyboard
class Keyboard { // digunakan untuk melacak input keyboard
  Boolean holdingUp,holdingRight,holdingLeft,holdingSpace;
  
  Keyboard() {
    holdingUp=holdingRight=holdingLeft=holdingSpace=false;
  }
  
  /* Cara Processing, dan banyak bahasa pemrograman / lingkungan, 
   * berkaitan dengan kunci yang memperlakukan mereka seperti kejadian (sesuatu bisa terjadi saat  turun, atau ketika naik.
   * Karena kita ingin memperlakukan mereka seperti tombol - memeriksa "itu ditekan sekarang?" - 
   * Kita perlu menggunakan peristiwa-peristiwa ditekan dan dilepas untuk memperbarui beberapa 
   * nilai-nilai palsu benar bahwa kita dapat memeriksa di tempat lain./

  void pressKey(int key,int keyCode) {
    if(key == 'r') { // tidak akan pernah ditekan, sehingga tidak dibutuhkan Boolean untuk melacak
      if(gameWon()) { // jika kondisi permainan menang
        resetGame(); // kemudian R key mereset permainan
      }
    }
   
    if (keyCode == UP) {
      holdingUp = true;
    }
    if (keyCode == LEFT) {
      holdingLeft = true;
    }
    if (keyCode == RIGHT) {
      holdingRight = true;
    }
    if (key == ' ') {
      holdingSpace = true;
    }
  }
  void releaseKey(int key,int keyCode) {
    if (keyCode == UP) {
      holdingUp = false;
    }
    if (keyCode == LEFT) {
      holdingLeft = false;
    }
    if (keyCode == RIGHT) {
      holdingRight = false;
    }
    if (keyCode == ' ') {
      holdingSpace = false;
    }
  }
}


Coding untuk Player
 class Player {
  PVector position,velocity; // Pvector berisi dua sumbu, x and y

  Boolean isOnGround; // Digunakan untuk melacak apakah pemain ada ditanah. Berfungsi untuk kontrol dan animasi 
  Boolean facingRight; // Digunakan untuk menentukan arah terakhir pemain pindah. Digunakan untuk memutar pemain. 
  int animDelay; // Penghitung waktu mundur antara update animasi 
  int animFrame; // Melacak frame animasi untuk pemain saat ditampilkan 
  int coinsCollected; // counter untuk menjaga penghitungan pada berapa banyak koin pemain telah dikumpulkan
  static final float JUMP_POWER = 11.0; // seberapa keras sentakan pemain pada lompatan
  static final float RUN_SPEED = 5.0; //  kekuatan pergerakan pemain di tanah
  static final float AIR_RUN_SPEED = 2.0; // seperti kecepatan berlari, tetapi digunakan untuk kontrol sementara di udara
  static final float SLOWDOWN_PERC = 0.6; // gesekan dari tanah. Dikalikan dengan kecepatan x setiap frame
  static final float AIR_SLOWDOWN_PERC = 0.85; // daya tahan di udara, jika kontrol udara memungkinkan kecepatan yang luar biasa
  static final int RUN_ANIMATION_DELAY = 3; // berapa banyak siklus permainan berjalan antara update animasi?
  static final float TRIVIAL_SPEED = 1.0; // jika dibawah kecepatan ini, pemain dianggap berdiri diam
  
  Player() { // konstruktor, dipanggil secara otomatis ketika pemain dibuat
    isOnGround = false;
    facingRight = true;
    position = new PVector();
    velocity = new PVector();
    reset();
  }
  
  void reset() {
    coinsCollected = 0;
    animDelay = 0;
    animFrame = 0;
    velocity.x = 0;
    velocity.y = 0;
  }
  
  void inputCheck() {
    // Keyboard bendera ditetapkan oleh keyPressed / keyReleased di main .pde    
    float speedHere = (isOnGround ? RUN_SPEED : AIR_RUN_SPEED);
    float frictionHere = (isOnGround ? SLOWDOWN_PERC : AIR_SLOWDOWN_PERC);
    
    if(theKeyboard.holdingLeft) {
      velocity.x -= speedHere;
    } else if(theKeyboard.holdingRight) {
      velocity.x += speedHere;
    } 
    velocity.x *= frictionHere; // penyebab pemain untuk terus kehilangan kecepatan
    
    if(isOnGround) { // pemain hanya dapat melompat jika masih diatas tanah
      if(theKeyboard.holdingSpace || theKeyboard.holdingUp) { // keduanya arah keatas atau bar spasi menyebabkan pemain melompat
        sndJump.trigger(); // memainkan suara
        velocity.y = -JUMP_POWER; // mengatur kecepatan vertikal
        isOnGround = false; //   menandai pemain telah meninggalkan lapangan, tidak dapat melompat lagi saat ini
    }
  }
  
  void checkForWallBumping() {
    int guyWidth = guy_stand.width; // pikirkan ukuran pemain berdiri sebagai ukuran fisik pemain
    int guyHeight = guy_stand.height;
    int wallProbeDistance = int(guyWidth*0.3);
    int ceilingProbeDistance = int(guyHeight*0.95);
    
    /* Because of how we draw the player, "position" is the center of the feet/bottom
     * To detect and handle wall/ceiling collisions, we create 5 additional positions:
     * leftSideHigh - left of center, at shoulder/head level
     * leftSideLow - left of center, at shin level
     * rightSideHigh - right of center, at shoulder/head level
     * rightSideLow - right of center, at shin level
     * topSide - horizontal center, at tip of head
     * These 6 points - 5 plus the original at the bottom/center - are all that we need
     * to check in order to make sure the player can't move through blocks in the world.
     * This works because the block sizes (World.GRID_UNIT_SIZE) aren't small enough to
     * fit between the cracks of those collision points checked.
     */
    
    // digunakan sebagai penyelidik untuk mendeteksi pelarian ke dinding, langit-langit
    PVector leftSideHigh,rightSideHigh,leftSideLow,rightSideLow,topSide;
    leftSideHigh = new PVector();
    rightSideHigh = new PVector();
    leftSideLow = new PVector();
    rightSideLow = new PVector();
    topSide = new PVector();

    // menyelidiki update dinding
    leftSideHigh.x = leftSideLow.x = position.x - wallProbeDistance; // tepi kiri pemain
    rightSideHigh.x = rightSideLow.x = position.x + wallProbeDistance; // tepi kanan pemain
    leftSideLow.y = rightSideLow.y = position.y-0.2*guyHeight; // tinggi lompatan
    leftSideHigh.y = rightSideHigh.y = position.y-0.8*guyHeight; // tinggi bahu

    topSide.x = position.x; // tengah-tengah pemain
    topSide.y = position.y-ceilingProbeDistance; // atas orangnya

    //jika ada tepi pemain ada di dalam killblock merah, ulang putaran
    if( theWorld.worldSquareAt(topSide)==World.TILE_KILLBLOCK ||
         theWorld.worldSquareAt(leftSideHigh)==World.TILE_KILLBLOCK ||
         theWorld.worldSquareAt(leftSideLow)==World.TILE_KILLBLOCK ||
         theWorld.worldSquareAt(rightSideHigh)==World.TILE_KILLBLOCK ||
         theWorld.worldSquareAt(rightSideLow)==World.TILE_KILLBLOCK ||
         theWorld.worldSquareAt(position)==World.TILE_KILLBLOCK) {
      resetGame();
      return; // kemungkinan tabrakan akan menjadi tidak relevan, keluar fungsi sekarang    } 
    
    // kondisi berikut hanya memeriksa tabrakan dengan setiap benjolan
    // tergantung pada dimana penyelidikan telah bertabrakan, kita mendorong pemain kembali ke arah yang berlawanan

    
    if( theWorld.worldSquareAt(topSide)==World.TILE_SOLID) {
      if(theWorld.worldSquareAt(position)==World.TILE_SOLID) {
        position.sub(velocity);
        velocity.x=0.0;
        velocity.y=0.0;
      } else {
        position.y = theWorld.bottomOfSquare(topSide)+ceilingProbeDistance;
        if(velocity.y < 0) {
          velocity.y = 0.0;
        }
      }
    }
    
    if( theWorld.worldSquareAt(leftSideLow)==World.TILE_SOLID) {
      position.x = theWorld.rightOfSquare(leftSideLow)+wallProbeDistance;
      if(velocity.x < 0) {
        velocity.x = 0.0;
      }
    }
   
    if( theWorld.worldSquareAt(leftSideHigh)==World.TILE_SOLID) {
      position.x = theWorld.rightOfSquare(leftSideHigh)+wallProbeDistance;
      if(velocity.x < 0) {
        velocity.x = 0.0;
      }
    }
   
    if( theWorld.worldSquareAt(rightSideLow)==World.TILE_SOLID) {
      position.x = theWorld.leftOfSquare(rightSideLow)-wallProbeDistance;
      if(velocity.x > 0) {
        velocity.x = 0.0;
      }
    }
   
    if( theWorld.worldSquareAt(rightSideHigh)==World.TILE_SOLID) {
      position.x = theWorld.leftOfSquare(rightSideHigh)-wallProbeDistance;
      if(velocity.x > 0) {
        velocity.x = 0.0;
      }
    }
  }

  void checkForCoinGetting() {
    PVector centerOfPlayer;
    // kami menggunakan ini untuk memeriksa koin tumpang tindih di tengah pemain
    // (ingat bahwa "posisi" adalah melacak tengah bawah kaki)
    centerOfPlayer = new PVector(position.x,position.y-guy_stand.height/2);

    if(theWorld.worldSquareAt(centerOfPlayer)==World.TILE_COIN) {
      theWorld.setSquareAtToThis(centerOfPlayer, World.TILE_EMPTY);
      sndCoin.trigger();
      coinsCollected++;
    }
  }

  void checkForFalling() {
    / / Jika kita berdiri pada ubin kosong atau koin, kita tidak berdiri pada apa pun. Jatuh!    if(theWorld.worldSquareAt(position)==World.TILE_EMPTY ||
       theWorld.worldSquareAt(position)==World.TILE_COIN) {
       isOnGround=false;
    }
    if(isOnGround==false) { // tidak di tanah ?
      if(theWorld.worldSquareAt(position)==World.TILE_SOLID) { // ada di kotak padat?
        isOnGround = true;
        position.y = theWorld.topOfSquare(position);
        velocity.y = 0.0;
      } else { // jatuh
        velocity.y += GRAVITY_POWER;
      }
    }
  }

  void move() {
    position.add(velocity);
    
    checkForWallBumping();
    
    checkForCoinGetting();
    
    checkForFalling();
  }
  
  void draw() {
    int guyWidth = guy_stand.width;
    int guyHeight = guy_stand.height;
    
    if(velocity.x<-TRIVIAL_SPEED) {
      facingRight = false;
    } else if(velocity.x>TRIVIAL_SPEED) {
      facingRight = true;
    }
    
    pushMatrix(); // lets us compound/accumulate translate/scale/rotate calls, then undo them all at once
    translate(position.x,position.y);
    if(facingRight==false) {
      scale(-1,1); // membalik horizontal dengan skala horisontal dengan -100%
    }
    translate(-guyWidth/2,-guyHeight); // menggambar gambar berpusat pada kaki karakter
    if(isOnGround==false) { // jatuh atau melompat
      image(guy_run1, 0,0); // pose ini berjalan cukup baik terlihat saat di udara

    } else if(abs(velocity.x)<TRIVIAL_SPEED) { // not moving fast, i.e. standing
      image(guy_stand, 0,0);
    } else { // berjalan. Bernyawa.
      if(animDelay--<0) {
        animDelay=RUN_ANIMATION_DELAY;
        if(animFrame==0) {
          animFrame=1;
        } else {
          animFrame=0;
        }
      }
      
      if(animFrame==0) {
        image(guy_run1, 0,0);
      } else {
        image(guy_run2, 0,0);
      }
    }
    
    popMatrix(); // Membatalkan semua penerjemahan / skala / memutar panggilan sejak pushMatrix sebelumnya dalam fungsi ini
  }
}