撞球遊戲製作
運用入射角=反射角的概念
將這個概念代入到程式裡面去
設定畫布大小後,在x=50,y=100的位置畫一個向著右下角移動的線
float vx=1,vy=1.3;//vx=1往右,vy=1.3往下
float x=50,y=100;//本來的位置
void setup(){//設定
size(200,300);//視窗大小
}
void draw(){//畫圖
ellipse(x,y,3,3);//畫一個3x3(線粗細)的x,y座標
x += vx;//不斷更新的x座標
y += vy;//不斷更新的y座標
}
上面那個程式讓我們學會如何畫一個向右下角奔跑的線,那麼接下來我們要學習如何讓線在碰到邊框之後會進行反彈
以y座標為例子,我們將視窗寬度設定為200,所以如果超出200的話就要進行反彈,才不會讓線超出視窗並一直跑
float vx=1,vy=1.3;//vx=1往右,vy=1.3往下
float x=50,y=100;//本來的位置
void setup(){//設定
size(300,200);//視窗大小
}
void draw(){//畫圖
ellipse(x,y,3,3);//畫一個3x3(線粗細)的x,y座標
x += vx;
y += vy;
//要如何做出反彈效果?
if(y>200){//當y座標大於我們所設定的視窗寬度200時
vy = -vy;//y就會反彈
}
}
float vx=1,vy=1.3;//vx=1往右,vy=1.3往下
float x=50,y=100;//本來的位置
void setup(){//設定
size(100,200);//視窗大小
}
void draw(){//畫圖
ellipse(x,y,3,3);//畫一個3x3(線粗細)的x,y座標
x += vx;
y += vy;
//要如何做出反彈效果?
if(x>100){//如果x座標>視窗長度100
vx = -vx;//x就會反彈
}
}
用內積將這兩個程式碼進行合體,稍微改寫一下,(我們看回圖1,綠色線的長度要拿去做內積,也就是速度x法向量),試著將v加上v2來看看會如何移動,會發現v會非常快速的向右邊移動,這並不是我們想要的結果
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
PVector n;//法向量
void setup(){//設定
size(400,300);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,100);//設定座標
n = new PVector(-1,0);//設定法向量
}
void draw(){//畫圖
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
//要如何做出反彈效果?
if(p.x >= 100){
//vx = -vx;
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,green);//乘法,v2是綠色的長度(功)
v.add(v2);//原來的v加上v2//v就會向右移動超快,所以是錯誤的
}
}
以PVector來改寫上上個y方向的程式會得到一樣的結果
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
PVector n;//法向量
void setup(){//設定
size(300,200);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,100);//設定座標
n = new PVector(0,-1);//設定法向量,向上
}
void draw(){//畫圖
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
//要如何做出反彈效果?
if(p.y >= 200){//一旦碰撞發生
//vx = -vx;
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色長度(功)//原來的方向加上2倍的負方向
v.add(v2);//v加上v2
}
}
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
void setup(){//設定
size(500,500);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,60);//設定座標
}
void draw(){//畫圖
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
line(0,500,mouseX,mouseY);
ellipse(300,300,150,150);//畫圓
//要如何做出反彈效果?
if(dist(p.x,p.y,300,300)<75){//一旦碰撞發生
//vx = -vx;
PVector n = new PVector(-1,-1).normalize();//單位法向量
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向
v.add(v2);//v加上v2
}
}
延續上周繼續學習撞球遊戲的製作方式
但上次學習的那個程式反射角並不是很完美,那麼要如何做出完美的入射角反射角呢?
PVector v;//float vx=1往右,vy=1.3;往下(速度)PVector p;//flaot x=50,y=100;(座標)void setup(){//設定 size(500,500);//視窗大小 v = new PVector(1,1.3);//設定速度 p = new PVector(50,60);//設定座標}void draw(){//畫圖 ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標 p.add(v);//p的座標要加上v的速度//x += vx; y += vy; line(0,500,mouseX,mouseY); ellipse(300,300,150,150);//畫圓 //要如何做出反彈效果? if(dist(p.x,p.y,300,300)<75){//一旦碰撞發生 //vx = -vx; PVector c = new PVector(300,300);//圓心 PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量 //完美的入射角等於反射角 float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積) PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向 v.add(v2);//v加上v2 }}
試著用滑鼠操控大球,讓小球再觸碰到大球的時候進行反彈PVector v;//float vx=1往右,vy=1.3;往下(速度)PVector p;//flaot x=50,y=100;(座標)void setup(){//設定 size(500,500);//視窗大小 v = new PVector(1,1.3);//設定速度 p = new PVector(50,60);//設定座標}void draw(){//畫圖 background(#FFFFF2);//將背景清空才不會有殘影 ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標 p.add(v);//p的座標要加上v的速度//x += vx; y += vy; line(0,500,mouseX,mouseY); ellipse(mouseX,mouseY,150,150);//畫圓 //要如何做出反彈效果? if(dist(p.x,p.y,mouseX,mouseY)<75){//一旦碰撞發生,距離也要改成mouseX,mouseY(球才會在表面進行反彈) //vx = -vx; PVector c = new PVector(mouseX,mouseY);//圓心(可以用滑鼠操控圓,但是會有殘影,要先將背景清空) PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量 //完美的入射角等於反射角 float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積) PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向 v.add(v2);//v加上v2 }}
當小球觸碰到大球時會顯示法向量的線條PVector v;//float vx=1往右,vy=1.3;往下(速度)PVector p;//flaot x=50,y=100;(座標)void setup(){//設定 size(500,500);//視窗大小 v = new PVector(1,1.3);//設定速度 p = new PVector(50,60);//設定座標 frameRate(10);//每秒刷新多少幀數,一秒鐘刷新10幀}void draw(){//畫圖 background(#FFFFF2);//將背景清空才不會有殘影 ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標 p.add(v);//p的座標要加上v的速度//x += vx; y += vy; //line(0,500,mouseX,mouseY);(可省略,不用畫輔助線) ellipse(mouseX,mouseY,150,150);//畫圓 //要如何做出反彈效果? if(dist(p.x,p.y,mouseX,mouseY)<75){//一旦碰撞發生,距離(dist)也要改成mouseX,mouseY(球才會在表面進行反彈) //vx = -vx; PVector c = new PVector(mouseX,mouseY);//圓心(可以用滑鼠操控圓,但是會有殘影,要先將背景清空) PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量 //完美的入射角等於反射角 float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積) PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向 v.add(v2);//v加上v2 line(c.x,c.y,p.x,p.y);//(當小球碰到大球會閃過法向量) }}
延續上周繼續學習撞球遊戲的製作方式
但上次學習的那個程式反射角並不是很完美,那麼要如何做出完美的入射角反射角呢?
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
void setup(){//設定
size(500,500);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,60);//設定座標
}
void draw(){//畫圖
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
line(0,500,mouseX,mouseY);
ellipse(300,300,150,150);//畫圓
//要如何做出反彈效果?
if(dist(p.x,p.y,300,300)<75){//一旦碰撞發生
//vx = -vx;
PVector c = new PVector(300,300);//圓心
PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量
//完美的入射角等於反射角
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向
v.add(v2);//v加上v2
}
}
試著用滑鼠操控大球,讓小球再觸碰到大球的時候進行反彈
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
void setup(){//設定
size(500,500);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,60);//設定座標
}
void draw(){//畫圖
background(#FFFFF2);//將背景清空才不會有殘影
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
line(0,500,mouseX,mouseY);
ellipse(mouseX,mouseY,150,150);//畫圓
//要如何做出反彈效果?
if(dist(p.x,p.y,mouseX,mouseY)<75){//一旦碰撞發生,距離也要改成mouseX,mouseY(球才會在表面進行反彈)
//vx = -vx;
PVector c = new PVector(mouseX,mouseY);//圓心(可以用滑鼠操控圓,但是會有殘影,要先將背景清空)
PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量
//完美的入射角等於反射角
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向
v.add(v2);//v加上v2
}
}
當小球觸碰到大球時會顯示法向量的線條
PVector v;//float vx=1往右,vy=1.3;往下(速度)
PVector p;//flaot x=50,y=100;(座標)
void setup(){//設定
size(500,500);//視窗大小
v = new PVector(1,1.3);//設定速度
p = new PVector(50,60);//設定座標
frameRate(10);//每秒刷新多少幀數,一秒鐘刷新10幀
}
void draw(){//畫圖
background(#FFFFF2);//將背景清空才不會有殘影
ellipse(p.x,p.y,3,3);//畫一個3x3(線粗細)的x,y座標
p.add(v);//p的座標要加上v的速度//x += vx; y += vy;
//line(0,500,mouseX,mouseY);(可省略,不用畫輔助線)
ellipse(mouseX,mouseY,150,150);//畫圓
//要如何做出反彈效果?
if(dist(p.x,p.y,mouseX,mouseY)<75){//一旦碰撞發生,距離(dist)也要改成mouseX,mouseY(球才會在表面進行反彈)
//vx = -vx;
PVector c = new PVector(mouseX,mouseY);//圓心(可以用滑鼠操控圓,但是會有殘影,要先將背景清空)
PVector n = PVector.sub(p,c).normalize();//單位法向量,要初始化做減法,把p跟圓心做相減再取法向量
//完美的入射角等於反射角
float green = PVector.dot(v,n);//綠色線的長度(做功)=PVector做內積(把速度跟法向量做內積)
PVector v2 = PVector.mult(n,-green*2);//乘法,v2是綠色的長度(功)//原來的方向加上2倍的負方向
v.add(v2);//v加上v2
line(c.x,c.y,p.x,p.y);//(當小球碰到大球會閃過法向量)
}
}





.png)





沒有留言:
張貼留言