2023年11月2日 星期四

再...再課8單 - 互動技術概論 - Week08

今天想做碰撞偵測的程式。

先讓視窗有東西移動,就像牛頓力學的第一定律一樣。


程式碼:

//碰撞偵測
//牛頓力學 (1)靜者恆靜、動者恆動
void setup()
{
  size(400, 400);
}
float x=200, y=200, vx=1, vy=1;
void draw()
{
  ellipse(x, y, 10, 10);
  x += vx;
  y += vy;
}
----------------------------------------------------------------------------
加上有拋物線的移動軌跡。
像是牛頓第二定律的加速度一樣向上拋。
程式碼:
//碰撞偵測
//牛頓力學 (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;
}
--------------------------------------------------------------------------
讓球落下的位置不低於350,限制高度。

程式碼:
//碰撞偵測
//牛頓力學 (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)
  {
    y=350;
  }
  ellipse(x, y , 10, 10);
}
--------------------------------------------------------------------------
加上當物品產生碰撞時,力會變小 (摩擦力)。

程式碼:
//碰撞偵測
//牛頓力學 (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)
  {
    y=350;
    vy = -vy * 0.5;
  }
  ellipse(x, y , 10, 10);
}
--------------------------------------------------------------------------
讓x軸也增加摩擦力。

程式碼:
//碰撞偵測
//牛頓力學 (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)
  {
    y=350;
    vy = -vy * 0.5;
    vx = vx* 0.8;
  }
  ellipse(x, y , 10, 10);
}
--------------------------------------------------------------------------
先做出一個類似馬力歐的人物和背景。加上鍵盤的左右鍵會左右移動 (但此時是會超出視窗範圍的)。

程式碼:
//碰撞偵測
//牛頓力學 (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;
  fill(255, 0, 0); ellipse(marioX, marioY,  15, 25);
  fill(229, 119, 42); rect(0, 260, 400, 150);
}
void keyPressed()
{
  if(keyCode == RIGHT) vx = 2;
  if(keyCode == LEFT) vx = -2;
}
--------------------------------------------------------------------------
加上跳躍(但此時跳躍會跳出視窗外)。

程式碼:
//碰撞偵測
//牛頓力學 (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;
  marioY += vy;
  fill(255, 0, 0); ellipse(marioX, marioY,  15, 25);
  fill(229, 119, 42); rect(0, 260, 400, 150);
}
void keyPressed()
{
  if(keyCode == RIGHT) vx = 2;
  if(keyCode == LEFT) vx = -2;
  if(keyCode == UP) vy = -20;
}
void keyReleased()
{
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}
--------------------------------------------------------------------------
讓角色向上跳躍後會回到地面上。

程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  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;
}
--------------------------------------------------------------------------
但是一直按上鍵的話,角色會飛走。
所以再flying加上限制。

程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  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 && flying==false)
  {
    vy = -20;
    flying = true; //開始飛行
  }
}
void keyReleased()
{
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}
--------------------------------------------------------------------------
讓角色撞到磚塊之後不會穿過去。

程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  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;
}
--------------------------------------------------------------------------
用vy決定stand。
程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  fill(229, 119, 42); rect(0, 260, 400, 150);
  fill(229, 119, 42); rect(200, 150, 20, 20);
  if(hitBox(200,150,20,20))
  {
    if(vy>0)
    {
      marioY = 150-10;
      flying = false;
    }
    else
    {
      vy=0;
      marioY = 150+20+10;
    }  
  }
}
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; //一開始不會飛
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;
}
--------------------------------------------------------------------------
讓角色站在磚塊時會站在上面。

程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  fill(229, 119, 42); rect(0, 260, 400, 150);
  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 = false;
    stand_box = 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; //開始飛行
  }
}
void keyReleased()
{
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}

--------------------------------------------------------------------------
加上掉落的效果。

程式碼:
//碰撞偵測
//牛頓力學 (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, 25);
  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 = false;
    stand_box = 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; //開始飛行
  }
}
void keyReleased()
{
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}

沒有留言:

張貼留言