1. 程式人生 > >Processing摸索前行(8)

Processing摸索前行(8)

前面,我們摸索了Pressing執行緒已經物件封裝,還做了雷達以及示波器,這一篇博文,我們利用processing來做一個小的遊戲。這個遊戲我們在很多手游上玩過,一個滑動的盤子,接住彈珠,彈珠每次彈跳可以擊碎一個方塊。
明白了需求,我們就來一步一步來實現吧。
一、會自動反彈的彈珠
首先我們要實現的是一個能夠反彈的彈珠。程式碼如下:

PVector ballPosition, ballSpeed;
color ballColor;
void setup() {
 // noLoop();
 size(320,280);
  ballPosition = new PVector(this.width/2,this.height/2);
  ballSpeed = new PVector(4, 4); 
  ballColor=color(random(255),random(255),random(255));
}

void draw() {
  background(0);
  ellipse(ballPosition.x, ballPosition.y, 30, 30);
  fill(ballColor);
  ballPosition.add(ballSpeed);
  if(ballPosition.x<=15 || ballPosition.x>=(this.width-15))
  {
    ballSpeed.x*=-1;
      ballColor=color(random(255),random(255),random(255));
 
}
  if(ballPosition.y<=15 || ballPosition.y>=(this.height-15))
  {
    ballSpeed.y*=-1 ;
      ballColor=color(random(255),random(255),random(255));
 
}
}

我們在這裡使用了向量來儲存“”對值“,這裡不用point來記錄,那是因為point不能用來做運算。執行效果:
在這裡插入圖片描述
下面我們在螢幕上方放置一些方塊,然後能夠檢測到碰撞,我們來看看程式碼:

PVector ballPosition, ballSpeed;
ArrayList<Block>  blocksArr;
color ballColor;
boolean   xbound=false;
boolean   ybound=false;
void setup() {
 size(320,280);
 
  ballPosition = new PVector(width/2,height/2);//random(this.width/2),random(this.height/2)
  ballSpeed = new PVector(4, 4); 
  ballColor=color(random(255),random(255),random(255));
  blocksArr=new ArrayList<Block>();
  initBlocks(5);
}

void draw() {
  background(0);

  for(Block block:blocksArr)
   if(block.displayStatus>0)
   {
    block.drawBlock();
    block.checkCollision(ballPosition);
    if(block.xb)
    {
      frameRate(10);
    xbound=block.xb;
    }
    if(block.yb)
    {
    ybound=block.yb;
    }


}
bounceBall();


}

void bounceBall()
{
  noStroke();
  fill(ballColor);
 
 
  ellipse(ballPosition.x, ballPosition.y, 10, 10);
  
  ballPosition.add(ballSpeed);
  
   //檢測碰撞  
 if(!ybound &&!xbound)//當兩個block碰撞檢測量都為false則進入正常邊界檢測
 {
   //正常X邊界檢測
    if(ballPosition.x<=15 || ballPosition.x>=(this.width-5))
      xbound=true;
    else
      xbound=false;
   if(ballPosition.y<=15 || ballPosition.y>=(this.height-5))
      ybound=true;
   else
      ybound=false;
 }
    
  if(xbound)
  {
      ballSpeed.x*=-1;
      ballColor=color(random(255),random(255),random(255)); 
      xbound=!xbound;
   }
  if(ybound)
  {
      ballSpeed.y*=-1 ;
      ballColor=color(random(255),random(255),random(255));
      ybound=!ybound;
  }
  stroke(10,200,30);
}

void initBlocks(int layerCount)
{
  int bWidth=40;
  int bHeight=20;
  Block blk;
  for(int j=0;j<layerCount;j++)
  for(int i=0;i<this.width/40;i++)
  {
    blk=new Block(i*bWidth,j*bHeight);
    blocksArr.add(blk);
  }
  
}

class Block{



float xcoor;
  float ycoor;
  int bWidth=40;
  int bHeight=20;
  int displayStatus=5;
  boolean xb=false;
  boolean yb=false;
  Block(float x,float y)
  {
    xcoor=x;
    ycoor=y;  
  }
  

  void  drawBlock()
  {
    fill(180,100,100,displayStatus*50);
    rect(xcoor,ycoor,bWidth,bHeight);
    noFill();
  }

  void checkCollision(PVector ball)
  {
    float nearestValueX;
     float nearestValueY;


if(xcoor<ball.x && ball.x<xcoor+40 && ycoor<ball.y && ball.y<ycoor+20)

{
  nearestValueX=abs(ball.x-xcoor)>abs(ball.x-xcoor+40)?abs(ball.x-xcoor):abs(ball.x-xcoor+40);
  nearestValueY=abs(ycoor-ball.y)> abs(ball.y-ycoor+20)?abs(ycoor-ball.y):abs(ball.y-ycoor+20);
  
    if(nearestValueX<nearestValueY)
   { 
      xb=true;
 
     
   }
   else
    {
     yb=true;
 
    }

  displayStatus=0;


  
}
    
  }
  
}

以上程式碼利用了前面我們學習的類的封裝將block封裝為類了,檢測方塊與小球的碰撞也封裝在其中了,這樣做的目的就是減少一次對block的檢測遍歷,節約運算資源。這裡的檢測只是粗略的檢測,喜歡鑽研的小夥伴們可以將小球的半徑也考慮在內效果會更好。
上述程式碼執行效果:
在這裡插入圖片描述

如果還有興趣的話,按照同樣的原理,可以增加一個接球的滑板,同樣也自帶一個檢測碰撞函式,利用對xbound和ybound的操作來實現控制,貼在這裡程式碼太長了。執行效果如下:
在這裡插入圖片描述
在這裡插入圖片描述
目前,這個小遊戲玩起來基本沒有什麼問題,但是在processing執行的時候如果有其他的視窗優先於processing視窗處於啟用狀態,那麼,遊戲中的按鍵就不會響應。暫時還米有找到強制使processing窗體處於優先啟用狀態的語句。
加入了接球板的原始碼:

完全版原始碼