2023年11月2日 星期四

WW-Week08_mario_game

第一節課

碰撞偵測,我們要做幾個遊戲來示範 > 馬力歐、皮卡丘打排球

第一個小程式week08_1_newton_x_y_vx_vy

先做馬力歐跳跳跳,根據牛頓力學: (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;
}

第二個小程式week08_2_newton_x_y_vx_vy_gravity

(2) f=m*a 位置、速度、加速度,劃出拋物線

void setup(){
  size(400,400);
}
float x=50, y=250, vx=2, vy=-20;//-20相反倍數
void draw(){
    ellipse(x,y,10,10);
    x += vx;
    y += vy;
    vy+=0.98;///重力加速度
}

第三個小程式week08_3_newton_floor_if_collision

step 1.用if來判斷有沒有碰到地板
void setup(){
  size(400,400);
}
float x=50, y=250, vx=2, vy=-20;
void draw(){
    x += vx;
    y += vy;
    vy+=0.98;///重力加速度
    if(y>350){//利用if判斷,看有沒有到地板 y=350位置
      y=350;//若碰到地板就都設350
    }
    ellipse(x,y,10,10);
}
step 2.碰到地板,方向正負顛倒,往上彈,*0.5能量耗損速度變慢
void setup(){
  size(400,400);
}
float x=50, y=250, vx=2, vy=-20;
void draSw(){
    x += vx;
    y += vy;
    vy+=0.98;///重力加速度
    if(y>350){//利用if判斷,看有沒有到地板 y=350位置
      y=350;
      vy = -vy*0.5;//*0.5耗損能量,越彈越小
    }
    ellipse(x,y,10,10);
}

第四個小程式week08_4_mario_keyPreesed_keyCode_UP_RIGHT_LEFT

新開檔案,要來寫馬力歐遊戲了

void setup(){   size(400,400); } float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0 void draw(){   background(108,137,255);   marioX += vx;   fill(255,0,0); ellipse( marioX, marioY, 15, 20);///馬力歐本人   fill(229,119,42); rect(0,260,400,150);//地板 } void keyPressed(){   if(keyCode==RIGHT) vx = 2;//按右鍵往右加速度跑   if(keyCode==LEFT) vx =-2;//按左鍵往左加速度跑 }
第二節課

第五個小程式week08_5_mario_keyReleased_keyCode_UP_RIGHT_LEFT

***上一個程式馬利歐動了就沒辦法停止

加入keyPresse(),並加按上鍵Y向上跑

void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  marioY += vy;
  fill(255,0,0); ellipse( marioX, marioY, 15, 20);///馬力歐本人
  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;
}

第六個小程式week08_6_mario_flying_vy_098

***但出現兩個問題,1.沒有重力加速度,2.向上時不會停

step 1.所以現在要加重力加速度(vy += 0.98),只有跳起來(flying=true)的時候才要開啟重力,不然馬力歐會掉到地獄去
void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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;
}
step 2.解決會飛出框外的問題,在飛的時候不能再飛一次,沒有在飛的時候按UP才會有作用
void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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 && flying==false) {
    vy =-20;
    flying = true;///開始飛行
  }
}
void keyReleased(){//放開時停止移動
  if(keyCode==LEFT || keyCode==RIGHT) vx=0;
}
***連續按UP***

第七個小程式week08_7_mario_hit_box_if

加入方塊,和碰撞

void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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;///bug:碰到的時候會在當下的位置停住
    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;///碰到方塊的下邊界
  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;
}
第三節課

第八個小程式week08_8_mario_vy_direction_stand_fall

***剛剛寫的只有hit到下邊界而已,想要可以hit上面

可以站到方塊上,並微調碰撞的點(原本在馬力歐肚臍,改到馬力歐頭頂和腳底)

void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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)){
    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;//馬力歐的厚度
  ///碰到方塊的下邊界
  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;
}

第九個小程式week08_9_mario_stand_box_and_fall

***現在的問題是到方塊上面後flying停止了,所以馬力歐卡在半空中(方塊上邊的位置)

離開方塊就要進入flying掉回地面才對,添加一個leaveBox()函數表示當馬力歐離開方塊回傳True,stand_box來判斷,如果站在


void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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)){
    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){///離開box
  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;
  ///碰到方塊的下邊界
  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;
}

第十個小程式week08_A_mario_add_box

想多加幾個方塊,所以寫一個drawAndTestBox()函式,將寫方塊的的部分加入此函式

void setup(){
  size(400,400);
}
float marioX=50, marioY=250, vx=0, vy=0;///vx,vy剛開始速度=0
void draw(){
  background(108,137,255);
  marioX += vx;
  if(flying){//如果在飛行
    marioY += vy;///Y方向位置會改變
    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);///多加一個方塊
}
boolean leaveBox(int x,int y,int w,int h){///離開box
  if (x-7>marioX || marioX>x+w+7 )return true;
  else return false;
}
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 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;
  ///碰到方塊的下邊界
  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;
}


沒有留言:

張貼留言