=========================================================================
EIGHTH
今天的重點是碰撞偵測,以馬力歐(Mario)為例
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; }
註:有殘影的球x,y各別+1跑(往右下角跑)
2.用位置、速度、加速度來形成一個拋物線
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; } 註:利用重力將球往下拉
3.拋物線下來之後會落在y=350的地板上
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;; } ellipse(x, y, 10, 10); } 註:掉到y=350會往右繼續運動
4.在原來的基礎上加上彈跳
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; vy = -vy * 0.5;//能量耗損、速度變慢 } ellipse(x, y, 10, 10); }
註:因為x也有耗損,所以可以加上vx = vx*0.7的耗損
5.做出一個馬力歐場景跟人物,並且利用鍵盤讓他能夠左右移動
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; } 註:此時還未能夠停止
6.讓馬力歐能夠停下、往上
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; } 註:加上keyReleased讓馬力歐能夠停下,這時候的跳還並未加上重力所以會直接往上跑
7.讓馬力歐能夠跳起來並且落在正確的地板上
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; }註:在flying狀態會有重力往下,以此來模擬跳
8.做出一個hitBox的函式,來做碰撞箱
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; } 註:用判斷上下左右邊界來取決於是否要停止flying
9.將碰撞箱做得更好,並且能先站方塊在上面
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; }
註:vy>0就會停止flying往下掉。如果vy=0就可以站在方塊上,但此時站上了會掉不下來
10.最後讓馬力歐能夠順利掉落到地板,並且能撞到方塊
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 = 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; }
註:利用跟hitbox寫出邏輯相反的leaveBox,在這之中要判斷flying與否跟stand_box與否
11.發明了一個drawAndTextBox,可以利用for迴圈來做出多個方塊
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); drawAndTextBox(100,150,20,20); drawAndTextBox(200,150,20,20); drawAndTextBox(300,150,20,20); } void drawAndTextBox(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;//現在有2個變數,都要處理 } } void keyReleased(){ if(keyCode==LEFT || keyCode==RIGHT) vx = 0; }註:為了能夠複製多個方塊所以做出一個函式能夠呼叫,只要呼交函式並定義參數就可以設置了
沒有留言:
張貼留言