# 第 11 章 【互動系統與模擬】物件導向與向量 - Class 粒子系統
[老師講義](https://course.creativecoding.in/note/chap/11)
物件封裝 自有的狀態 速度 等 行為抽象化
Leap motion
物件導向 遊戲
案例分享
https://www.dstrict.com/ART
https://natureofcode.com/book/chapter-6-autonomous-agents/
> 或許下一個讀書會內容可以看這個 模擬物理系統講的滿好的書
```js
// 建立一個球的原型
class Ball{
constructor(args){ //初始化物件的時候會被執行的方法
this.p = args.p
}
move(){ // 每個由 Ball 實例化出來的物件都會有的方法
this.p.x++
}
doSomething(){
...
}
...
}
```
```jsx=
//直接把 draw() 跟 update() 寫在 class Ball{...} 裡面的話,就可以直接使用 ball.draw() 與 ball.update() 方法了
class Ball{
constructor(args){
this.r = args.r
this.color = args.color
this.p = args.p
...
}
draw(){
push() //加入 push&pop確保畫布不會亂跑
fill(this.color)
ellipse(this.p.x, this.p.y, this.r)
pop()
}
update(){
this.p.x += this.v.x
this.p.y += this.v.y
}
...
}
for(let i=0; i<balls.length;i++){
let ball = balls[i]
// 繪製 draw() 的部分
ball.draw()
// 更新位置 update() 的部分
ball.update()
}
```
new Ball
class
constructor(args)
把args 包成物件
method間不需要逗號
記得善用 push() pop()
用 mode 方式改變群組內的變化
this.mode == 'happy'
再加上眼睛
移比較快等
ellipse 是以直徑來設定 記得
```js
for(let o =0; o<8 ; o++){
rotate(PI/4)
beginShape()
for(let i=0; i< 30;i++){
vertex(this.r/2 + i/2, sin(i /10)*10)
}
endShape()
}
```
互動
```js
function mousePressed(){
for(let ball of balls){
ball.escape();
ball.setHappy();
}
}
```
讓每隻都不一樣
random ID = rid
this.rid = random(10000)
讓一些起始角度/速動都跟rid有關
檢查
class內的method
```js
isBallInRanged(){
let d = dist()
d<dist? 1: 0
}
draw()裡面
if(isBallInRanged){
ball.color ==
}
```
把setHappy, setCrazy整合起來變成 setMode(mode)
11-4
換成 Vector
(x,y)
P5.Vector
https://p5js.org/reference/#/p5.Vector
v1.add(v2)
v1.mult(0.99)
createVector(mouseX,mouseY)
向量好處 較複雜的操作
```js
let mouseV = createVector(mouseX,mouseY)
let delta = mouseV.sub(this.p).limit(2)
this.p.add(delta)
小心會動到原本的值 記得先.copy()
```
值日生: Frank
【互動系統與模擬】物件導向與向量 - Class 粒子系統
多物件互動與鍵盤事件
互動遊戲常用:
讓第二種物件跟病毒做互動吧
crazy, mousePressed, InRange 之前的函式先 command 掉不要觸發
創造第二種物件:子彈
發射子彈攻擊這些病毒
碰到病毒的時候 病毒會死掉
新增 Class Ball
怕整個 code 太長可以開第二個 tab
習慣整理 Code 是程式設計師的美德(K)
新增 Class Bullet
基本屬性:位置 速度 加速度
動作:update, draw
假設從左上角射子彈好了,所以初始的位置是 (0,0)
記得利用 Vector
createVector(1,1) 往右下移動
新增一個陣列 Array,裝所有的子彈
```
var bullets = []
```
滑鼠點下去的時候,就
```
let bullet = new Bullet() // 新增一個子彈
bullets.push(bullet) // 加入陣列
```
!! B 記得大寫代表他是類別
把子彈畫出來
```
for(let bullet of bullets)
```
做一個類似堡壘的東西在中央
從中央開始射 這樣改起來很容易
位置:
```
x = width/2
y = height/2
mode = CENTER
```
子彈碰到這個病毒的時候,希望他們兩個就消滅掉
mouse in range 修改成 Ball In Range
概念:每一個 ball 取出來之後呢,我們要檢查每一顆子彈
```
for(let bullet of bullets) {
...
}
```
碰撞?
```
hitResult = ball.isBallInRange()
// return True || False
```
子彈的速度:
bullet 產生的時候用 createVector
然後取中心點跟滑鼠之間之間的差距量
```
createVector(mouseX-width/2,mouseY-height/2)
```
限制長(速)度,後面接 ...
```
.limit(5) || limit(10)
```
與其用 limit() 我們可以直接用 setMag()
固定速度
```
setMag(10)
```
移除物件
```
hitResult ? ball.dead = true : ball.dead = fasle
```
```
draw(){
if(this.dead) {
return
}
}
```
把剛剛的 rect 改成可操作的船?
KeyPressed vs KeyisPressed
KeyPressed 只觸發一次
KeyisPressed 持續觸發
```
print(key) // 看按鍵的程式代號
```
作業:
船做成 Class
加入爆炸?