2023年11月2日 星期四

達yo - week08

 今天要做的是 碰撞偵測

1.1

一開始在畫面上畫出一顆靜止的圓點

再來增加兩行程式碼

  x += vx;
  y += vy;
使圓點移動

執行畫面

改變x(最初圓點的位置),y(最初圓點的高度),vx,(拋下去的寬度)vy(拋的高度)的數值

vx


讓圓點有往上拋的效果



設一個高度讓圓點碰到就不能一直往下但會發生球往右邊移動
無法停止

碰到地板後 會因能量耗損 彈不高、速度變慢的效果

程式碼
//碰撞偵測:Mario vs. Pikachu
//牛頓力學(1)靜者恆靜、動者恆動(2)f = m*a 位置、速度、加速度
void setup(){
  size(400,400);
}
float x=50,y=250,vx=2,vy=-20;
void draw(){
  ellipse(x,y,10,10);
  x += vx;
  y += vy;
  
  vy += 0.98;//重力加速度
  if(y>350){//利用if判斷,看有無碰到地板 y=350位置
    y = 350;
    vy = -vy*0.5;//碰撞後能量耗損、速度變慢
    vx = vx*0.8;
  }
  ellipse(x,y,10,10);
}


1.2 做馬力歐的背景模樣出來

圓點(馬力歐)
用左右鍵控制馬力歐往哪邊移動
(*按鍵放開無法停止*)

執行畫面

2.1
做出按鍵放開就會停止移動、按往上鍵使球往上彈跳

void keyReleased(){
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}



往上彈跳程式碼
//碰撞偵測:Mario vs. Pikachu
//牛頓力學(1)靜者恆靜、動者恆動(2)f = m*a 位置、速度、加速度
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);
}
boolean flying = false;
void keyPressed(){
  if(keyCode == RIGHT) vx = 2;
  if(keyCode == LEFT) vx = -2;
  if(keyCode == UP){
    vy=-20;
    flying = true;//開始飛行
  }
}
void keyReleased(){
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}


執行畫面

解決連續按往上鍵會一直飛上去的問題
  if(keyCode == UP && flying == false){//如果沒有在飛 才能飛
    vy=-20;
    flying = true;//開始飛行
  }


2.2

增加一個Box
  fill(229,119,42);rect(200,150,20,20);


讓馬力歐碰到Box會往下





在Box正下方往上跳碰到的呈現效果
程式碼
//碰撞偵測:Mario vs. Pikachu
//牛頓力學(1)靜者恆靜、動者恆動(2)f = m*a 位置、速度、加速度
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);
  fill(229,119,42);rect(200,150,20,20);
  if(hitBox(200,150,20,20)){
    vy=0;
    marioY = 150+20;
  }
}
boolean hitBox(int x,int y, int w,int h){
  if(x<marioX && marioX < x+w && y < marioY && marioY < y+h) return true;
  else return false;
}
boolean flying = false;
void keyPressed(){
  if(keyCode == RIGHT) vx = 2;
  if(keyCode == LEFT) vx = -2;
  if(keyCode == UP && flying == false){//如果沒有在飛 才能飛
    vy=-20;
    flying = true;//開始飛行
  }
}
void keyReleased(){
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}

3.1
使馬力歐跳到Box上面不會掉下來




執行畫面

解決跳上Box無法再掉下來的問題

程式碼
  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;
  }
}
boolean leaveBox(int x,int y,int w,int h){
  if(x-7>marioX || marioX > x+w+7) return true;
  else return false;
}
boolean flying = false, stand_box=false;


效果示意

最後將Box用一個函式來取代,要增加多個方塊比較簡潔



總程式碼
//碰撞偵測:Mario vs. Pikachu
//牛頓力學(1)靜者恆靜、動者恆動(2)f = m*a 位置、速度、加速度
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(100,150,20,20);
  drawAndTestBox(200,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;
}


沒有留言:

張貼留言