いいかんじの距離で後ろについてくる縦列パーティ↑のロジック
ストリートファイターのコマンド入力もこんな感じのロジックだと聞いた。
var party = new Party(
new Member(0),new Member(1),new Member(2),
new Member(3),new Member(5),new Member(6),
new Member(7),new Member(8),new Member(9),
new Member(10)
)
var camera = new Camera(...party.items)
party.camera = camera.delta
class Party{
constructor(...a){
this.items = a
this.track = [new Vector(0,0)]
this.position = new Vector(0,0)
this.camera = null
this.gap = 60
}
update(vector){//コントローラーのスティック入力など渡し
var compass = vector.rotate(this.camera.yaw)//進行方向
var delta = compass.mul(4)
this.position = this.position.add(delta)
this.position.push(delta.magnitude)//長さキャッシュ
this.track.unshift(this.position)
//メモ添付
var track = this.track
for(var i=0;i<this.items.length;i++){
var member = this.items[i]
var position = track[0]
var vector = position.sub(track[1])
member.position = position.sub(this.position)
member.vector = vector
member.direction(vector.rotate(-this.camera.yaw))
var distance = 0
var j = track.findIndex(p=>(distance+=p[2])>this.gap)
if(j==-1||j==track.length-1) break
var front = track[j-1]
var back = track[j]
var delta = distance - this.gap
var vector = front.sub(back).mul(delta/front[2])
var position = back.add(vector)
position.push(vector.magnitude)
track = track.slice(j)
track.unshift(position)
}
return this.shoot()
}
shoot(){//パン・チルト
this.items.forEach(v=>{
v.rotate(-this.camera.pitch,-this.camera.yaw)
v.direction(v.vector.rotate(-this.camera.yaw))
})
return this
}
}
パーティ追尾仕様
勇者の足跡をストックしておき、ピッタリの間隔になるようにベクトル補完。
しっかり処理すると追尾のカクツキが消えます。
簡易Vector2
javascriptでもスカラー風に四則演算書けたらいいのにね
class Vector extends Array{//Vector2
get x() {return this[0]}
get y() {return this[1]}
get magnitude() {return Math.hypot(this[0],this[1])}
get radian() {return this.length?Math.atan2(this[1],this[0]):0}
get degree() {return this.radian*Vector.R2D}
get square() {return this[0]*this[0]+this[1]*this[1]}//sqrMagnitude
set degree(d){
var r = d/Vector.R2D
var m = this.length?this.magnitude:1
this[0] = Math.cos(r)*m
this[1] = Math.sin(r)*m
}
add(a){return new Vector(this[0]+a[0], this[1]+a[1] )}
sub(a){return new Vector(this[0]-a[0], this[1]-a[1] )}
mul(n){return new Vector(this[0]*n, this[1]*n )}
div(n){return new Vector(this[0]/n, this[1]/n )}
rotate(d){//rotateZ
var v = this.slice()
v.degree += d
return v
}
}
Vector.R2D = 180/Math.PI