0
0

ドラクエ式縦列パーティ

Last updated at Posted at 2023-12-20

tuibi.png
いいかんじの距離で後ろについてくる縦列パーティ↑のロジック
ストリートファイターのコマンド入力もこんな感じのロジックだと聞いた。

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
	}
}

パーティ追尾仕様

Track.png
勇者の足跡をストックしておき、ピッタリの間隔になるようにベクトル補完。
しっかり処理すると追尾のカクツキが消えます。


簡易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
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0