Langsung ke konten utama

Turorial PewDiePie Game on Steroids [PART 1] - Processing



Pada kesempatan kali ini penulis akan membagikan tutorial cara membuat game yang ada pada Google Chrome jika tidak ada koneksi internet. Tapi perbedaannya karakter T Rex diganti dengan PewDiePie dan rintangan Kaktus diganti dengan T - Series, burung Pterodactyl dengan Monetisasi / Demonetisasi YouTube. Langsung saja ke tutorial :

  1. Pertama, install aplikasi processing >> https://processing.org/download/
  2. Estrak dan jalankan aplikasinya
  3. Pertama kita buat kelas yang menampilkan tampilan awal dari game. Simpan dengan nama file Game


int nextConnectionNo = 1000;

Population pop;
int frameSpeed = 60;
boolean showBestEachGen = false;
int upToGen = 0;
Player genPlayerTemp;
boolean showNothing = false;
//images
PImage dinoRun1;
PImage dinoRun2;
PImage dinoJump;
PImage dinoDuck;
PImage dinoDuck1;
PImage smallCactus;
PImage manySmallCactus;
PImage bigCactus;
PImage bird;
PImage bird1;
ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
ArrayList<Bird> birds = new ArrayList<Bird>();
ArrayList<Ground> grounds = new ArrayList<Ground>();
int obstacleTimer = 0;
int minimumTimeBetweenObstacles = 60;
int randomAddition = 0;
int groundCounter = 0;
float speed = 10;
int groundHeight = 250;
int playerXpos = 150;
ArrayList<Integer> obstacleHistory = new ArrayList<Integer>();
ArrayList<Integer> randomAdditionHistory = new ArrayList<Integer>();
//--------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
frameRate(60);
fullScreen();
dinoRun1 = loadImage("dinorun0000.png");
dinoRun2 = loadImage("dinorun0001.png");
dinoJump = loadImage("dinoJump0000.png");
dinoDuck = loadImage("dinoduck0000.png");
dinoDuck1 = loadImage("dinoduck0001.png");
smallCactus = loadImage("cactusSmall0000.png");
bigCactus = loadImage("cactusBig0000.png");
manySmallCactus = loadImage("cactusSmallMany0000.png");
bird = loadImage("berd.png");
bird1 = loadImage("berd2.png");
pop = new Population(500); //<<number of dinosaurs in each generation
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
void draw() {
drawToScreen();
if (showBestEachGen) {//show the best of each gen
if (!genPlayerTemp.dead) {//if current gen player is not dead then update it
genPlayerTemp.updateLocalObstacles();
genPlayerTemp.look();
genPlayerTemp.think();
genPlayerTemp.update();
genPlayerTemp.show();
} else {//if dead move on to the next generation
upToGen ++;
if (upToGen >= pop.genPlayers.size()) {//if at the end then return to the start and stop doing it
upToGen= 0;
showBestEachGen = false;
} else {//if not at the end then get the next generation
genPlayerTemp = pop.genPlayers.get(upToGen).cloneForReplay();
}
}
} else {//if just evolving normally
if (!pop.done()) {//if any players are alive then update them
updateObstacles();
pop.updateAlive();
} else {//all dead
//genetic algorithm 
pop.naturalSelection();
resetObstacles();
}
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//draws the display screen
void drawToScreen() {
if (!showNothing) {
background(250); 
stroke(0);
strokeWeight(2);
line(0, height - groundHeight - 30, width, height - groundHeight - 30);
drawBrain();
writeInfo();
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void drawBrain() { //show the brain of whatever genome is currently showing
int startX = 600;
int startY = 10;
int w = 600;
int h = 400;
if (showBestEachGen) {
genPlayerTemp.brain.drawGenome(startX, startY, w, h);
} else {
for (int i = 0; i< pop.pop.size(); i++) {
if (!pop.pop.get(i).dead) {
pop.pop.get(i).brain.drawGenome(startX, startY, w, h);
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//writes info about the current player
void writeInfo() {
fill(200);
textAlign(LEFT);
textSize(40);
if (showBestEachGen) { //if showing the best for each gen then write the applicable info
text("Score: " + genPlayerTemp.score, 30, height - 30);
//text(, width/2-180, height-30);
textAlign(RIGHT);
text("Gen: " + (genPlayerTemp.gen +1), width -40, height-30);
textSize(20);
int x = 580;
text("Distace to next obstacle", x, 18+44.44444);
text("Height of obstacle", x, 18+2*44.44444);
text("Width of obstacle", x, 18+3*44.44444);
text("Bird height", x, 18+4*44.44444);
text("Speed", x, 18+5*44.44444);
text("Players Y position", x, 18+6*44.44444);
text("Gap between obstacles", x, 18+7*44.44444);
text("Bias", x, 18+8*44.44444);
textAlign(LEFT);
text("Small Jump", 1220, 118);
text("Big Jump", 1220, 218);
text("Duck", 1220, 318);
} else { //evolving normally 
text("Score: " + floor(pop.populationLife/3.0), 30, height - 30);
//text(, width/2-180, height-30);
textAlign(RIGHT);
text("Gen: " + (pop.gen +1), width -40, height-30);
textSize(20);
int x = 580;
text("Distace to next obstacle", x, 18+44.44444);
text("Height of obstacle", x, 18+2*44.44444);
text("Width of obstacle", x, 18+3*44.44444);
text("Bird height", x, 18+4*44.44444);
text("Speed", x, 18+5*44.44444);
text("Players Y position", x, 18+6*44.44444);
text("Gap between obstacles", x, 18+7*44.44444);
text("Bias", x, 18+8*44.44444);
textAlign(LEFT);
text("Small Jump", 1220, 118);
text("Big Jump", 1220, 218);
text("Duck", 1220, 318);
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
void keyPressed() {
switch(key) {
case '+'://speed up frame rate
frameSpeed += 10;
frameRate(frameSpeed);
println(frameSpeed);
break;
case '-'://slow down frame rate
if (frameSpeed > 10) {
frameSpeed -= 10;
frameRate(frameSpeed);
println(frameSpeed);
}
break;
case 'g'://show generations
showBestEachGen = !showBestEachGen;
upToGen = 0;
genPlayerTemp = pop.genPlayers.get(upToGen).cloneForReplay();
break;
case 'n'://show absolutely nothing in order to speed up computation
showNothing = !showNothing;
break;
case CODED://any of the arrow keys
switch(keyCode) {
case RIGHT://right is used to move through the generations
if (showBestEachGen) {//if showing the best player each generation then move on to the next generation
upToGen++;
if (upToGen >= pop.genPlayers.size()) {//if reached the current generation then exit out of the showing generations mode
showBestEachGen = false;
} else {
genPlayerTemp = pop.genPlayers.get(upToGen).cloneForReplay();
}
break;
}
break;
}
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//called every frame
void updateObstacles() {
obstacleTimer ++;
speed += 0.002;
if (obstacleTimer > minimumTimeBetweenObstacles + randomAddition) { //if the obstacle timer is high enough then add a new obstacle
addObstacle();
}
groundCounter ++;
if (groundCounter> 10) { //every 10 frames add a ground bit
groundCounter =0;
grounds.add(new Ground());
}
moveObstacles();//move everything
if (!showNothing) {//show everything
showObstacles();
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//moves obstacles to the left based on the speed of the game 
void moveObstacles() {
println(speed);
for (int i = 0; i< obstacles.size(); i++) {
obstacles.get(i).move(speed);
if (obstacles.get(i).posX < -playerXpos) { 
obstacles.remove(i);
i--;
}
}
for (int i = 0; i< birds.size(); i++) {
birds.get(i).move(speed);
if (birds.get(i).posX < -playerXpos) {
birds.remove(i);
i--;
}
}
for (int i = 0; i < grounds.size(); i++) {
grounds.get(i).move(speed);
if (grounds.get(i).posX < -playerXpos) {
grounds.remove(i);
i--;
}
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//every so often add an obstacle 
void addObstacle() {
int lifespan = pop.populationLife;
int tempInt;
if (lifespan > 1000 && random(1) < 0.15) { // 15% of the time add a bird
tempInt = floor(random(3));
Bird temp = new Bird(tempInt);//floor(random(3)));
birds.add(temp);
} else {//otherwise add a cactus
tempInt = floor(random(3));
Obstacle temp = new Obstacle(tempInt);//floor(random(3)));
obstacles.add(temp);
tempInt+=3;
}
obstacleHistory.add(tempInt);
randomAddition = floor(random(50));
randomAdditionHistory.add(randomAddition);
obstacleTimer = 0;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//what do you think this does?
void showObstacles() {
for (int i = 0; i< grounds.size(); i++) {
grounds.get(i).show();
}
for (int i = 0; i< obstacles.size(); i++) {
obstacles.get(i).show();
}
for (int i = 0; i< birds.size(); i++) {
birds.get(i).show();
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------
//resets all the obstacles after every dino has died
void resetObstacles() {
randomAdditionHistory = new ArrayList<Integer>();
obstacleHistory = new ArrayList<Integer>();
obstacles = new ArrayList<Obstacle>();
birds = new ArrayList<Bird>();
obstacleTimer = 0;
randomAddition = 0;
groundCounter = 0;
speed = 10;

4. Selanjutnya adalah class Monetisasi dengan nama Bird.

class Bird {
  float w = 60;
  float h = 50;
  float posX;
  float posY;
  int flapCount = 0;
  int typeOfBird;
//------------------------------------------------------------------------------------------------------------------------------------------------------
 //constructor
  Bird(int type) {
    posX = width;
    typeOfBird = type;
    switch(type) {
    case 0://flying low
      posY = 10 + h/2;
      break;
    case 1://flying middle
      posY = 100;
      break;
    case 2://flying high
      posY = 180;
      break;
    }
  }
//------------------------------------------------------------------------------------------------------------------------------------------------------
  //show the birf
  void show() {
    flapCount++;
 
    if (flapCount < 0) {//flap the berd
      image(bird,posX-bird.width/2,height - groundHeight - (posY + bird.height-20));
    } else {
      image(bird1,posX-bird1.width/2,height - groundHeight - (posY + bird1.height-20));
    }
    if(flapCount > 15){
     flapCount = -15;
   
    }
  }
//------------------------------------------------------------------------------------------------------------------------------------------------------
  //move the bard
  void move(float speed) {
    posX -= speed;
  }
//------------------------------------------------------------------------------------------------------------------------------------------------------
  //returns whether or not the bird collides with the player
  boolean collided(float playerX, float playerY, float playerWidth, float playerHeight) {
    float playerLeft = playerX - playerWidth/2;
    float playerRight = playerX + playerWidth/2;
    float thisLeft = posX - w/2 ;
    float thisRight = posX + w/2;
    if ((playerLeft<= thisRight && playerRight >= thisLeft ) || (thisLeft <= playerRight && thisRight >= playerLeft)) {
      float playerUp = playerY + playerHeight/2;
      float playerDown = playerY - playerHeight/2;
      float thisUp = posY + h/2;
      float thisDown = posY - h/2;
      if (playerDown <= thisUp && playerUp >= thisDown) {
        return true;
      }
    }
    return false;
  }
}
 
   5. Selanjunya kita menambahkan rintangan kedalam game dengan nama file Obstacle
class Obstacle {

  float posX;

  int w ;

  int h ;

  int type;
  //------------------------------------------------------------------------------------------------------------------------------------------------------
  //constructor
  Obstacle(int t) {
    posX = width;
    type = t;
    switch(type) {
    case 0://small cactus
      w = 40;
      h = 80;
      break;
    case 1://big cactus
      w = 60;
      h = 120;
      break;
    case 2://small cacti
      w = 120;
      h = 80;
      break;
    }
  }
  //------------------------------------------------------------------------------------------------------------------------------------------------------
  //show the cactus
  void show() {
    fill(0);
    rectMode(CENTER);
    switch(type) {
    case 0:
      image(smallCactus, posX - smallCactus.width/2, height - groundHeight - smallCactus.height);
      break;
    case 1:
      image(bigCactus, posX - bigCactus.width/2, height - groundHeight - bigCactus.height);
      break;
    case 2:
      image(manySmallCactus, posX - manySmallCactus.width/2, height - groundHeight - manySmallCactus.height);
      break;
    }
  }
  //------------------------------------------------------------------------------------------------------------------------------------------------------
  // move the obstacle
  void move(float speed) {
    posX -= speed;
  }
  //------------------------------------------------------------------------------------------------------------------------------------------------------
  //returns whether or not the player collides with this obstacle
  boolean collided(float playerX, float playerY, float playerWidth, float playerHeight) {
    float playerLeft = playerX - playerWidth/2;
    float playerRight = playerX + playerWidth/2;
    float thisLeft = posX - w/2 ;
    float thisRight = posX + w/2;
    if ((playerLeft<= thisRight && playerRight >= thisLeft ) || (thisLeft <= playerRight && thisRight >= playerLeft)) {
      float playerDown = playerY - playerHeight/2;
      float thisUp = h;
      if (playerDown <= thisUp) {
        return true;
      }
    }
    return false;
  }
}
  6. Tahap selanjutnya adalah pembuatan Jaringan Syaraf Tiruan yang tersedia DISINI
GAMEPLAY
Player Generasi Awal


Player Generasi Mahir

Source code dapat pembaca download DISINI
Terimakasih telah membaca, semoga bermanfaat :)



Komentar

  1. Game nya otomatis playing atau user yg playnya?

    BalasHapus
  2. Gamenya mantep . . . Cocok buat anak saya lebih sesuai umur di banding game m***** l***** . .

    BalasHapus
  3. keren postingannya kak, sangat bermanfaat!

    BalasHapus
  4. Keren cocok buat bocil milenial kekinian ni..

    BalasHapus
    Balasan
    1. Segera di download gan dicoba sendiri hehe

      Hapus
  5. Bagus juga ,tapi saya main dota

    BalasHapus
    Balasan
    1. Coba sekali2 main game ini kak. Karena game dota tidak baik untuk kesehatan

      Hapus
  6. Mantap dek gamesnya.. kembang kan terus dan sukses ya 😇

    BalasHapus
  7. semoga banyak di gemarin dan semakin berkembang

    BalasHapus
  8. Semoga lebih baik lagi. Terus kembangkan👍

    BalasHapus
  9. Keren euy, mantap ni, bagus juga gamenya, best laah👏👏

    BalasHapus

  10. Bagus gamenya gan,cocok buat anak gua dirumah untuk menghibur waktu luang anak saya. Tpi itu klo bisa objeknya ganti agak lucuan begitu gan, jgn korsi haha
    Thanks 👍🏻

    BalasHapus
    Balasan
    1. Hehe iya next time inshaAllah akan dikembangkan lagi. Terimakasih masukkan nya kak :)

      Hapus
  11. Balasan
    1. Hehe setelah kami kembangkan lagi ya kak. Terimakasih :)

      Hapus
  12. Ini buatnya pake aplikasi apa ya kak

    BalasHapus
  13. Balasan
    1. Pake proccessing kak, ntar copy codingnya baru run kan aplikasinya :)

      Hapus
  14. Bagus, tpi kasihan si playernya scor udah jauh"
    Tapi mati ulang dari awal.
    Maunya kasih nyawa biar dia gk nyerah

    BalasHapus

Posting Komentar

Postingan populer dari blog ini

Apa Itu IMK(Interaksi Manusia dan Komputer) ?

Interaksi manusia dan komputer adalah disiplin ilmu yang mempelajari hubungan antara manusia dan komputer yang meliputi perancangan, evaluasi, dan implementasi antarmuka pengguna komputer agar mudah digunakan oleh manusia. Sedangkan interaksi manusia dan komputer sendiri adalah serangkaian proses, dialog dan kegiatan yang dilakukan oleh manusia untuk berinteraksi dengan komputer secara interaktif untuk melaksanakan dan menyelesaikan tugas yang diinginkan. IMK atau interaksi manusia dan komputer adalah suatu ilmu yang sangat berkaitan dengan disain implementasi dan evaluasi dari sistem komputasi iyang interaktif untuk digunakan oleh manusia dan studi tentang ruang lingkupnya,ada interaksi antara satu atau lebih manusia dan satu atau lebih komputasi mesin. Agar komputer dapat diterima secara luas dan digunakan secara efektif, maka perlu dirancang secara baik. Hal ini tidak berarti bahwa semua sistem harus dirancang agar dapat mengakomodasi semua orang, namun kom...

CSS Introduction

What is CSS? CSS stands for C ascading S tyle S heets CSS describes how HTML elements are to be displayed on screen, paper, or in other media CSS saves a lot of work . It can control the layout of multiple web pages all at once External stylesheets are stored in CSS file. Why Use CSS? CSS is used to define styles for your web pages, including the design, layout and variations in display for different devices and screen sizes. CSS Solved a Big Problem HTML was NEVER intended to contain tags for formatting a web page! HTML was created to describe the content of a web page, like: <h1>This is a heading</h1> <p>This is a paragraph.</p> When tags like <font>, and color attributes were added to the HTML 3.2 specification, it started a nightmare for web developers. Development of large websites, where fonts and color information were added to every single page, became a long and expensive process. To solve this problem, the Worl...