2023年11月2日 星期四

碰撞

 STEP 01

1.今天要做碰撞偵測,開啟processing

2.做一個符合牛頓力學,動者恆者,靜者恆靜的一個圓

STEP 02

1.做F=ma,位置,速度,加速度

2.修改圓的初始位置,及xy速度,對y軸增加加速度(0.98)

STEP 03

1.利用if判定,假設Y=350的地方是地板,如果到了地板就停止下落往旁邊走

2.根據作用力與反作用力,下落至地板,球應該往上反彈一點,並且碰撞因摩擦力能量消耗,速度會變慢

STEP 04

1.開新視窗,要做彈跳馬利歐

2.利用按壓左右方向鍵的方式,實現讓馬力歐移動,有個問題,按了會走,但不會停

3.用background跟fill做出類似的場景

STEP 05

1.利用keyReleased()放開鍵,讓左右移動能停下來

2.加上上鍵功能,發現馬力歐會飛走

STEP 06

1.布林宣告飛行,預設false,然後在if按下上鍵加上將飛行布林變數變成true

2.然後加上if飛行中,要受到重力影響,加上重力加速度0.98(9.8)

3.用剛才的方式使其掉落不會超過地板

4.發生多段跳,按很多下上鍵還是會飛很高

5.在按下上鍵的if判斷添加條件,飛行布林變數為false時,按下上鍵才會執行跳的動作,避免多段跳飛天

STEP 07

1.建立一個方塊,要讓馬利歐撞它

2.布林宣告撞箱子,利用箱子座標和馬利歐的座標改變布林變數

3.撞到就速度歸0,掉回地板

4.無法站到磚塊上

STEP  08

1.改善方塊碰撞體積,玩家操縱的馬利歐能佔到磚塊上了

2.問題:站到磚塊上後,會浮空掉不下來

STEP 09

1.做兩個布林變數,站在箱子跟離開箱子

2.藉由這兩個變數跟飛行布林變數配合,得到重力加速度等使馬利歐正常離開方塊下落



STEP 10

1.將方塊相關的程式改用一個函式去做

方塊相關程式:

fill(229,119,42); rect(200,150,20,20);

  if(hitbox(200,150,20,20)){

    if(vy>0){

      marioY = 150-10;//往上

      flying = false;

      stand_box = true;

    }else{

      vy = 0;

      marioY=150+20+10;//往下

     }

  }

  if(stand_box==true && flying==false && leavebox(200,150,20,20)){

      stand_box = false;

      flying = true;

      vy = 0;

    }

}


2.用函式多做幾個方塊,看起來比較好看


最後程式碼樣子

//牛頓力學碰撞偵測

void setup(){

  size(400,400);

}

float marioX=50, marioY=250,vx=0,vy=0;

void draw(){

  background(108,137,255);

  marioX += vx;

  if(flying){//如果飛行中

    marioY += vy;//上下位置改變

    vy += 0.98;//重力加速度往下

    if(marioY>=250){//碰到地板

      marioY = 250;//站在地板上

      flying = false;//不再飛行

    }

  }

  fill(255,0,0); ellipse(marioX,marioY,15,20);

  fill(229,119,42); rect(0,260,400,150);

  drawAndTestBox(200,150,20,20);

  drawAndTestBox(250,150,20,20);

  drawAndTestBox(300,150,20,20);

}

void drawAndTestBox(int x,int y,int w,int h){

  fill(229,119,42); rect(x,y,w,h);

  if(hitbox(x,y,w,h)){

    if(vy>0){

      marioY = y-10;//往上

      flying = false;

      stand_box = true;

    }else{

      vy = 0;

      marioY=y+h+10;//往下

     }

  }

  if(stand_box==true && flying==false && leavebox(x,y,w,h)){

      stand_box = false;

      flying = true;

      vy = 0;

    }

}

boolean leavebox(int x,int y,int w,int h){

  if(x-7>marioX || marioX>x+w+7) return true;

  else return false;

}

boolean hitbox(int x,int y,int w,int h){

  if(x-7<marioX && marioX<x+w+7 && y-10<marioY && marioY<y+h+10) return true;

  else return false;

}

boolean flying = false,stand_box = false;//一開始不飛

void keyPressed(){

  if(keyCode==RIGHT) vx=2;

  if(keyCode==LEFT) vx=-2;

  if(keyCode==UP && flying==false){//禁止多段跳

    vy= -20;

    flying = true;//飛行 啟動

    stand_box = false;

  }

}

void keyReleased(){

  if(keyCode==LEFT || keyCode==RIGHT) vx=0;  

}

沒有留言:

張貼留言